280 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
--- a/nslu2_image.cc
 | 
						|
+++ b/nslu2_image.cc
 | 
						|
@@ -54,28 +54,44 @@ namespace NSLU2Image {
 | 
						|
 				int &address, int &length) {
 | 
						|
 			address = image.tellg();
 | 
						|
 			length = buffer_length;
 | 
						|
-			if (address+length > NSLU2Protocol::FlashSize)
 | 
						|
-				length = NSLU2Protocol::FlashSize-address;
 | 
						|
+			if (address+length > EndAddress)
 | 
						|
+				length = EndAddress-address;
 | 
						|
 			if (length > 0)
 | 
						|
 				SafeRead(&image, buffer, length, "image (read)");
 | 
						|
 		}
 | 
						|
 
 | 
						|
+		virtual void GetBoundaries(int &start, int &end)
 | 
						|
+		{
 | 
						|
+			start = BaseAddress;
 | 
						|
+			end = EndAddress;
 | 
						|
+		}
 | 
						|
+
 | 
						|
 		/* Rewind to the start of the image (or the Kernel if not
 | 
						|
 		 * doing a complete reprogram).
 | 
						|
 		 */
 | 
						|
 		virtual void Rewind(void) {
 | 
						|
-			SafeSeek(&image, reprogram ? 0 : NSLU2Protocol::BaseAddress,
 | 
						|
+			SafeSeek(&image, reprogram ? 0 : BaseAddress,
 | 
						|
 					"image (seek)");
 | 
						|
 		}
 | 
						|
 
 | 
						|
 	private:
 | 
						|
+		int BaseAddress;
 | 
						|
+		int EndAddress;
 | 
						|
+
 | 
						|
 		/* Validate that this really is an image file. */
 | 
						|
 		void Validate(const char *i) {
 | 
						|
 			char signature[8];
 | 
						|
 
 | 
						|
 			SafeSeek(&image, -8, i, std::ios::end);
 | 
						|
 			SafeRead(&image, signature, 8, i);
 | 
						|
-			if (memcmp(signature, "eRcOmM", 6) != 0)
 | 
						|
+
 | 
						|
+			if (memcmp(signature, "eRcOmM", 6) == 0) {
 | 
						|
+				BaseAddress = NSLU2Protocol::BaseAddress;
 | 
						|
+				EndAddress = NSLU2Protocol::FlashSize;
 | 
						|
+			} else if (memcmp(signature + 1, "sErCoMm", 7) == 0) {
 | 
						|
+				BaseAddress = 0;
 | 
						|
+				EndAddress = NSLU2Protocol::FlashSize - 0x40000;
 | 
						|
+			} else
 | 
						|
 				throw NSLU2Image::FileError(DataError, i, 0);
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -93,6 +109,12 @@ namespace NSLU2Image {
 | 
						|
 		virtual ~SynthesiseImage() {
 | 
						|
 		}
 | 
						|
 
 | 
						|
+		void GetBoundaries(int &start, int &end)
 | 
						|
+		{
 | 
						|
+			start = NSLU2Protocol::BaseAddress;
 | 
						|
+			end = NSLU2Protocol::FlashSize;
 | 
						|
+		}
 | 
						|
+
 | 
						|
 		/* Get the next block of bytes, returns an address and length, false if
 | 
						|
 		 * there is a problem.
 | 
						|
 		 */
 | 
						|
--- a/nslu2_image.h
 | 
						|
+++ b/nslu2_image.h
 | 
						|
@@ -35,6 +35,8 @@ namespace NSLU2Image {
 | 
						|
 		virtual ~Image() {
 | 
						|
 		}
 | 
						|
 
 | 
						|
+		virtual void GetBoundaries(int &start, int &end) = 0;
 | 
						|
+
 | 
						|
 		/* Get the next block of bytes, returns an address and length.
 | 
						|
 		 */
 | 
						|
 		virtual void GetBytes(char *buffer, size_t buffer_length,
 | 
						|
--- a/nslu2_upgrade.cc
 | 
						|
+++ b/nslu2_upgrade.cc
 | 
						|
@@ -95,7 +95,7 @@ namespace NSLU2Upgrade {
 | 
						|
 
 | 
						|
 	class RealDoUpgrade : public DoUpgrade {
 | 
						|
 	public:
 | 
						|
-		RealDoUpgrade(Wire *w, Progress *p, bool r) :
 | 
						|
+		RealDoUpgrade(Wire *w, Progress *p, bool r, int start, int end) :
 | 
						|
 			wire(w), progress(p), sequenceError(-1), reprogram(r),
 | 
						|
 			lastType(NSLU2Protocol::InvalidType) {
 | 
						|
 			if (reprogram) {
 | 
						|
@@ -105,6 +105,8 @@ namespace NSLU2Upgrade {
 | 
						|
 				NSLU2Protocol::UpgradeStartPacket packet(seq);
 | 
						|
 				wire->Send(packet.PacketBuffer(), packet.PacketLength());
 | 
						|
 			}
 | 
						|
+			BaseAddress = start;
 | 
						|
+			EndAddress = end;
 | 
						|
 		}
 | 
						|
 
 | 
						|
 		virtual ~RealDoUpgrade() {
 | 
						|
@@ -205,8 +207,8 @@ namespace NSLU2Upgrade {
 | 
						|
 
 | 
						|
 	};
 | 
						|
 
 | 
						|
-	DoUpgrade *DoUpgrade::MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram) {
 | 
						|
-		return new RealDoUpgrade(wire, progress, reprogram);
 | 
						|
+	DoUpgrade *DoUpgrade::MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram, int start, int end) {
 | 
						|
+		return new RealDoUpgrade(wire, progress, reprogram, start, end);
 | 
						|
 	}
 | 
						|
 };
 | 
						|
 
 | 
						|
@@ -421,13 +423,18 @@ void NSLU2Upgrade::RealDoUpgrade::Upgrad
 | 
						|
 	/* Simple upgrade programs only the addresses beyound BaseAddress,
 | 
						|
 	 * reprogram overwrites the whole flash.
 | 
						|
 	 */
 | 
						|
-	if (!reprogram && address < NSLU2Protocol::BaseAddress) {
 | 
						|
+	if (!reprogram && address < BaseAddress) {
 | 
						|
 		length += address;
 | 
						|
-		if (length <= NSLU2Protocol::BaseAddress)
 | 
						|
+		if (length <= BaseAddress)
 | 
						|
 			return; /* nothing to do. */
 | 
						|
-		address = NSLU2Protocol::BaseAddress;
 | 
						|
+		address = BaseAddress;
 | 
						|
 		length -= address;
 | 
						|
 	}
 | 
						|
+	if (!reprogram && address + length > EndAddress) {
 | 
						|
+		if (address >= EndAddress)
 | 
						|
+			return; /* nothing to do. */
 | 
						|
+		length -= EndAddress - address;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 #if 1
 | 
						|
 	/* Skip blocks of 255 valued bytes - the erase clears the flash to this
 | 
						|
@@ -495,11 +502,11 @@ void NSLU2Upgrade::RealDoUpgrade::Verify
 | 
						|
 		Finish();
 | 
						|
 
 | 
						|
 	/* Verify never verifies anything below BaseAddress. */
 | 
						|
-	if (address < NSLU2Protocol::BaseAddress) {
 | 
						|
+	if (address < BaseAddress) {
 | 
						|
 		length += address;
 | 
						|
-		if (length <= NSLU2Protocol::BaseAddress)
 | 
						|
+		if (length <= BaseAddress)
 | 
						|
 			return; /* nothing to do. */
 | 
						|
-		address = NSLU2Protocol::BaseAddress;
 | 
						|
+		address = BaseAddress;
 | 
						|
 		length -= address;
 | 
						|
 	}
 | 
						|
 
 | 
						|
--- a/nslu2_upgrade.h
 | 
						|
+++ b/nslu2_upgrade.h
 | 
						|
@@ -206,6 +206,8 @@ namespace NSLU2Upgrade {
 | 
						|
 
 | 
						|
 	class DoUpgrade {
 | 
						|
 	public:
 | 
						|
+		int BaseAddress;
 | 
						|
+		int EndAddress;
 | 
						|
 		virtual ~DoUpgrade() {
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -228,7 +230,7 @@ namespace NSLU2Upgrade {
 | 
						|
 		virtual void Reboot(void) = 0;
 | 
						|
 			/* Reboot the NSLU2. */
 | 
						|
 
 | 
						|
-		static DoUpgrade *MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram);
 | 
						|
+		static DoUpgrade *MakeDoUpgrade(Wire *wire, Progress *progress, bool reprogram, int start, int end);
 | 
						|
 			/* Instantiate a real DoUpgrade, returns NULL if the object
 | 
						|
 			 * cannot be instantiated.
 | 
						|
 			 *
 | 
						|
--- a/upslug2.cc
 | 
						|
+++ b/upslug2.cc
 | 
						|
@@ -21,8 +21,8 @@
 | 
						|
 
 | 
						|
 class ProgressBar : public UpSlug2::CharacterProgressBar<80> {
 | 
						|
 public:
 | 
						|
-	ProgressBar(bool reprogram, const unsigned char *t) :
 | 
						|
-		UpSlug2::CharacterProgressBar<80>(reprogram, 64),
 | 
						|
+	ProgressBar(bool reprogram, const unsigned char *t, int start, int end) :
 | 
						|
+		UpSlug2::CharacterProgressBar<80>(reprogram, 64, start, end),
 | 
						|
 		target(t), displayed(false), ticker(0) {
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -95,7 +95,7 @@ private:
 | 
						|
 			else if (seen == -1) {
 | 
						|
 				seen = 0;
 | 
						|
 				if (!reprogram)
 | 
						|
-					sent -= NSLU2Protocol::BaseAddress;
 | 
						|
+					sent -= NSLU2Protocol::FlashSize - (EndAddress - BaseAddress);
 | 
						|
 			} else
 | 
						|
 				sent -= seen;
 | 
						|
 
 | 
						|
@@ -423,7 +423,7 @@ int main(int argc, char **argv) {
 | 
						|
 { 0,                                                            0,                 0,  0  }
 | 
						|
 	};
 | 
						|
 
 | 
						|
-	do switch (getopt_long(argc, argv, "he:d:t:f:vUni:Ck:r:R:j:p:P:T:F:E:", options, 0)) {
 | 
						|
+	do switch (getopt_long(argc, argv, "he:d:t:f:vUni:Ck:r:R:j:op:P:T:F:E:", options, 0)) {
 | 
						|
 	case  -1: if (optind < argc) {
 | 
						|
 			  std::fprintf(stderr, "%s: unrecognised option\n", argv[optind]);
 | 
						|
 			  std::exit(1);
 | 
						|
@@ -523,16 +523,22 @@ done:
 | 
						|
 
 | 
						|
 		if (mac && got_kernel) {
 | 
						|
 			Pointer<NSLU2Upgrade::Wire> wire(NSLU2Upgrade::Wire::MakeWire(device, fromMac, mac, euid));
 | 
						|
-			ProgressBar progress(reprogram, mac);
 | 
						|
+			int BaseAddress = NSLU2Protocol::BaseAddress;
 | 
						|
+			int EndAddress = NSLU2Protocol::FlashSize;
 | 
						|
 
 | 
						|
 			if (full_image) { /* complete image. */
 | 
						|
 				/* The full image case allows a complete reprogram. */
 | 
						|
+				NSLU2Image::Image *image_p;
 | 
						|
 				Pointer<NSLU2Image::Image> image(
 | 
						|
 						NSLU2Image::Image::MakeImage(
 | 
						|
 							reprogram, full_image));
 | 
						|
+				image_p = image.p;
 | 
						|
+				image_p->GetBoundaries(BaseAddress, EndAddress);
 | 
						|
+				ProgressBar progress(reprogram, mac, BaseAddress, EndAddress);
 | 
						|
 				Pointer<NSLU2Upgrade::DoUpgrade> upgrade(
 | 
						|
 					NSLU2Upgrade::DoUpgrade::MakeDoUpgrade(
 | 
						|
-						wire.p, &progress, reprogram));
 | 
						|
+						wire.p, &progress, reprogram,
 | 
						|
+						BaseAddress, EndAddress));
 | 
						|
 				progress.FirstDisplay();
 | 
						|
 				Upgrade(upgrade.p, image.p, no_upgrade, no_verify);
 | 
						|
 				progress.EndDisplay();
 | 
						|
@@ -551,9 +557,11 @@ done:
 | 
						|
 							fis_payload,
 | 
						|
 							product_id, protocol_id,
 | 
						|
 							firmware_version, extra_version));
 | 
						|
+				ProgressBar progress(reprogram, mac, BaseAddress, EndAddress);
 | 
						|
 				Pointer<NSLU2Upgrade::DoUpgrade> upgrade(
 | 
						|
 					NSLU2Upgrade::DoUpgrade::MakeDoUpgrade(
 | 
						|
-						wire.p, &progress, false));
 | 
						|
+						wire.p, &progress, false,
 | 
						|
+						BaseAddress, EndAddress));
 | 
						|
 				progress.FirstDisplay();
 | 
						|
 				Upgrade(upgrade.p, image.p, no_upgrade, no_verify);
 | 
						|
 				progress.EndDisplay();
 | 
						|
--- a/upslug2_progress.h
 | 
						|
+++ b/upslug2_progress.h
 | 
						|
@@ -161,15 +161,19 @@ namespace UpSlug2 {
 | 
						|
 			Timedout,   /* *: timeout on a sent packet for this address. */
 | 
						|
 			NumberOfStates
 | 
						|
 		} Status;
 | 
						|
-		
 | 
						|
+		int BaseAddress;
 | 
						|
+		int EndAddress;
 | 
						|
+
 | 
						|
 		/* reprogram says whether this is a full reprogram (the entire
 | 
						|
 		 * flash will be erased) or not (the leading, RedBoot, SysConf
 | 
						|
 		 * partitions are not erased).
 | 
						|
 		 * resolution should be about 6 for a command line (character)
 | 
						|
 		 * progress bar and 8 for a GUI (pixel) progress bar.
 | 
						|
 		 */
 | 
						|
-		ProgressBar(bool r) :
 | 
						|
+		ProgressBar(bool r, int start, int end) :
 | 
						|
 			reprogram(r), timeout(false), retransmit(false), status(Init) {
 | 
						|
+			BaseAddress = start;
 | 
						|
+			EndAddress = end;
 | 
						|
 		}
 | 
						|
 
 | 
						|
 		/* lowWaterMark..(highWaterMark-1) bytes are in state 'st',
 | 
						|
@@ -179,8 +183,8 @@ namespace UpSlug2 {
 | 
						|
 			/* These initial settings cover the majority of cases
 | 
						|
 			 * correctly.
 | 
						|
 			 */
 | 
						|
-			lowWaterMark = reprogram ? 0 : NSLU2Protocol::BaseAddress;
 | 
						|
-			highWaterMark = status >= st ? NSLU2Protocol::FlashSize-1 : 0;
 | 
						|
+			lowWaterMark = reprogram ? 0 : BaseAddress;
 | 
						|
+			highWaterMark = status >= st ? EndAddress-1 : 0;
 | 
						|
 			switch (st) {
 | 
						|
 			case Init:
 | 
						|
 				/* Everything has an initial value... */
 | 
						|
@@ -286,9 +290,9 @@ namespace UpSlug2 {
 | 
						|
 	 */
 | 
						|
 	template <int characters> class CharacterProgressBar : public ProgressBar {
 | 
						|
 	public:
 | 
						|
-		CharacterProgressBar(bool reprogram, int n, const char ind[NumberOfStates] = 0) :
 | 
						|
+		CharacterProgressBar(bool reprogram, int n, int start, int end, const char ind[NumberOfStates] = 0) :
 | 
						|
 			numberOfCharacters(n > characters || n < 1 ? characters : n),
 | 
						|
-			ProgressBar(reprogram) {
 | 
						|
+			ProgressBar(reprogram, start, end) {
 | 
						|
 			if (ind)
 | 
						|
 				std::memcpy(indicators, ind, NumberOfStates);
 | 
						|
 			else
 |