3 @@ -54,28 +54,44 @@ namespace NSLU2Image {
4 int &address, int &length) {
5 address = image.tellg();
6 length = buffer_length;
7 - if (address+length > NSLU2Protocol::FlashSize)
8 - length = NSLU2Protocol::FlashSize-address;
9 + if (address+length > EndAddress)
10 + length = EndAddress-address;
12 SafeRead(&image, buffer, length, "image (read)");
15 + virtual void GetBoundaries(int &start, int &end)
17 + start = BaseAddress;
21 /* Rewind to the start of the image (or the Kernel if not
22 * doing a complete reprogram).
24 virtual void Rewind(void) {
25 - SafeSeek(&image, reprogram ? 0 : NSLU2Protocol::BaseAddress,
26 + SafeSeek(&image, reprogram ? 0 : BaseAddress,
34 /* Validate that this really is an image file. */
35 void Validate(const char *i) {
38 SafeSeek(&image, -8, i, std::ios::end);
39 SafeRead(&image, signature, 8, i);
40 - if (memcmp(signature, "eRcOmM", 6) != 0)
42 + if (memcmp(signature, "eRcOmM", 6) == 0) {
43 + BaseAddress = NSLU2Protocol::BaseAddress;
44 + EndAddress = NSLU2Protocol::FlashSize;
45 + } else if (memcmp(signature + 1, "sErCoMm", 7) == 0) {
47 + EndAddress = NSLU2Protocol::FlashSize - 0x40000;
49 throw NSLU2Image::FileError(DataError, i, 0);
52 @@ -93,6 +109,12 @@ namespace NSLU2Image {
53 virtual ~SynthesiseImage() {
56 + void GetBoundaries(int &start, int &end)
58 + start = NSLU2Protocol::BaseAddress;
59 + end = NSLU2Protocol::FlashSize;
62 /* Get the next block of bytes, returns an address and length, false if
67 @@ -35,6 +35,8 @@ namespace NSLU2Image {
71 + virtual void GetBoundaries(int &start, int &end) = 0;
73 /* Get the next block of bytes, returns an address and length.
75 virtual void GetBytes(char *buffer, size_t buffer_length,
76 --- a/nslu2_upgrade.cc
77 +++ b/nslu2_upgrade.cc
78 @@ -95,7 +95,7 @@ namespace NSLU2Upgrade {
80 class RealDoUpgrade : public DoUpgrade {
82 - RealDoUpgrade(Wire *w, Progress *p, bool r) :
83 + RealDoUpgrade(Wire *w, Progress *p, bool r, int start, int end) :
84 wire(w), progress(p), sequenceError(-1), reprogram(r),
85 lastType(NSLU2Protocol::InvalidType) {
87 @@ -105,6 +105,8 @@ namespace NSLU2Upgrade {
88 NSLU2Protocol::UpgradeStartPacket packet(seq);
89 wire->Send(packet.PacketBuffer(), packet.PacketLength());
91 + BaseAddress = start;
95 virtual ~RealDoUpgrade() {
96 @@ -205,8 +207,8 @@ namespace NSLU2Upgrade {
100 - DoUpgrade *DoUpgrade::MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram) {
101 - return new RealDoUpgrade(wire, progress, reprogram);
102 + DoUpgrade *DoUpgrade::MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram, int start, int end) {
103 + return new RealDoUpgrade(wire, progress, reprogram, start, end);
107 @@ -421,13 +423,18 @@ void NSLU2Upgrade::RealDoUpgrade::Upgrad
108 /* Simple upgrade programs only the addresses beyound BaseAddress,
109 * reprogram overwrites the whole flash.
111 - if (!reprogram && address < NSLU2Protocol::BaseAddress) {
112 + if (!reprogram && address < BaseAddress) {
114 - if (length <= NSLU2Protocol::BaseAddress)
115 + if (length <= BaseAddress)
116 return; /* nothing to do. */
117 - address = NSLU2Protocol::BaseAddress;
118 + address = BaseAddress;
121 + if (!reprogram && address + length > EndAddress) {
122 + if (address >= EndAddress)
123 + return; /* nothing to do. */
124 + length -= EndAddress - address;
128 /* Skip blocks of 255 valued bytes - the erase clears the flash to this
129 @@ -495,11 +502,11 @@ void NSLU2Upgrade::RealDoUpgrade::Verify
132 /* Verify never verifies anything below BaseAddress. */
133 - if (address < NSLU2Protocol::BaseAddress) {
134 + if (address < BaseAddress) {
136 - if (length <= NSLU2Protocol::BaseAddress)
137 + if (length <= BaseAddress)
138 return; /* nothing to do. */
139 - address = NSLU2Protocol::BaseAddress;
140 + address = BaseAddress;
144 --- a/nslu2_upgrade.h
145 +++ b/nslu2_upgrade.h
146 @@ -206,6 +206,8 @@ namespace NSLU2Upgrade {
152 virtual ~DoUpgrade() {
155 @@ -228,7 +230,7 @@ namespace NSLU2Upgrade {
156 virtual void Reboot(void) = 0;
157 /* Reboot the NSLU2. */
159 - static DoUpgrade *MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram);
160 + static DoUpgrade *MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram, int start, int end);
161 /* Instantiate a real DoUpgrade, returns NULL if the object
162 * cannot be instantiated.
168 class ProgressBar : public UpSlug2::CharacterProgressBar<80> {
170 - ProgressBar(bool reprogram, const unsigned char *t) :
171 - UpSlug2::CharacterProgressBar<80>(reprogram, 64),
172 + ProgressBar(bool reprogram, const unsigned char *t, int start, int end) :
173 + UpSlug2::CharacterProgressBar<80>(reprogram, 64, start, end),
174 target(t), displayed(false), ticker(0) {
177 @@ -95,7 +95,7 @@ private:
178 else if (seen == -1) {
181 - sent -= NSLU2Protocol::BaseAddress;
182 + sent -= NSLU2Protocol::FlashSize - (EndAddress - BaseAddress);
186 @@ -423,7 +423,7 @@ int main(int argc, char **argv) {
190 - do switch (getopt_long(argc, argv, "he:d:t:f:vUni:Ck:r:R:j:p:P:T:F:E:", options, 0)) {
191 + do switch (getopt_long(argc, argv, "he:d:t:f:vUni:Ck:r:R:j:op:P:T:F:E:", options, 0)) {
192 case -1: if (optind < argc) {
193 std::fprintf(stderr, "%s: unrecognised option\n", argv[optind]);
195 @@ -523,16 +523,22 @@ done:
197 if (mac && got_kernel) {
198 Pointer<NSLU2Upgrade::Wire> wire(NSLU2Upgrade::Wire::MakeWire(device, fromMac, mac, euid));
199 - ProgressBar progress(reprogram, mac);
200 + int BaseAddress = NSLU2Protocol::BaseAddress;
201 + int EndAddress = NSLU2Protocol::FlashSize;
203 if (full_image) { /* complete image. */
204 /* The full image case allows a complete reprogram. */
205 + NSLU2Image::Image *image_p;
206 Pointer<NSLU2Image::Image> image(
207 NSLU2Image::Image::MakeImage(
208 reprogram, full_image));
210 + image_p->GetBoundaries(BaseAddress, EndAddress);
211 + ProgressBar progress(reprogram, mac, BaseAddress, EndAddress);
212 Pointer<NSLU2Upgrade::DoUpgrade> upgrade(
213 NSLU2Upgrade::DoUpgrade::MakeDoUpgrade(
214 - wire.p, &progress, reprogram));
215 + wire.p, &progress, reprogram,
216 + BaseAddress, EndAddress));
217 progress.FirstDisplay();
218 Upgrade(upgrade.p, image.p, no_upgrade, no_verify);
219 progress.EndDisplay();
220 @@ -551,9 +557,11 @@ done:
222 product_id, protocol_id,
223 firmware_version, extra_version));
224 + ProgressBar progress(reprogram, mac, BaseAddress, EndAddress);
225 Pointer<NSLU2Upgrade::DoUpgrade> upgrade(
226 NSLU2Upgrade::DoUpgrade::MakeDoUpgrade(
227 - wire.p, &progress, false));
228 + wire.p, &progress, false,
229 + BaseAddress, EndAddress));
230 progress.FirstDisplay();
231 Upgrade(upgrade.p, image.p, no_upgrade, no_verify);
232 progress.EndDisplay();
233 --- a/upslug2_progress.h
234 +++ b/upslug2_progress.h
235 @@ -161,15 +161,19 @@ namespace UpSlug2 {
236 Timedout, /* *: timeout on a sent packet for this address. */
243 /* reprogram says whether this is a full reprogram (the entire
244 * flash will be erased) or not (the leading, RedBoot, SysConf
245 * partitions are not erased).
246 * resolution should be about 6 for a command line (character)
247 * progress bar and 8 for a GUI (pixel) progress bar.
249 - ProgressBar(bool r) :
250 + ProgressBar(bool r, int start, int end) :
251 reprogram(r), timeout(false), retransmit(false), status(Init) {
252 + BaseAddress = start;
256 /* lowWaterMark..(highWaterMark-1) bytes are in state 'st',
257 @@ -179,8 +183,8 @@ namespace UpSlug2 {
258 /* These initial settings cover the majority of cases
261 - lowWaterMark = reprogram ? 0 : NSLU2Protocol::BaseAddress;
262 - highWaterMark = status >= st ? NSLU2Protocol::FlashSize-1 : 0;
263 + lowWaterMark = reprogram ? 0 : BaseAddress;
264 + highWaterMark = status >= st ? EndAddress-1 : 0;
267 /* Everything has an initial value... */
268 @@ -286,9 +290,9 @@ namespace UpSlug2 {
270 template <int characters> class CharacterProgressBar : public ProgressBar {
272 - CharacterProgressBar(bool reprogram, int n, const char ind[NumberOfStates] = 0) :
273 + CharacterProgressBar(bool reprogram, int n, int start, int end, const char ind[NumberOfStates] = 0) :
274 numberOfCharacters(n > characters || n < 1 ? characters : n),
275 - ProgressBar(reprogram) {
276 + ProgressBar(reprogram, start, end) {
278 std::memcpy(indicators, ind, NumberOfStates);