Repartitioning a flash chip / Resizing Bootloader

I own a Xiaomi Mi router 4a (100M, International). I want to put on it a custom build of the U-Boot bootloader. So far I figured out how to build U-Boot and added it to the Openwrt build process.

The original bootloader seems to be some a modified version of U-Boot 1.1.3 (Indicated by the string I get on the serial console while booting). The version I compiled is v2024.10 (this is the version currently supported by most devices with U-Boot support in the Openwrt project).

The problem arises when I compare binary sizes. The original bootloader fits inside a 128KiB partition, while my version seems to take up ~300KiB. I tried to minimize the binary size with no luck (I tried disabling drivers and software I don't need in the U-Boot menuconfig).

UPDATE: I disabled absolutely everythig I found and U-Boot still takes up ~200KiB. This indicates, that I must change partition sizes in order to get the new bootloader onto my device.

The next idea I had was to resize the boot partition, since I have enough free space on the rootfs_data.

My questions are:

  • Is there a simple configuration for U-Boot that builds a minimal image? (EDIT: pointless question, new versions are just larger)
  • What are the steps required to resize the boot partition? (This means that I would need to move partitions following the boot partition)
  • What partitions get remade when installing a new version of OpenWrt?

P.S.: I am using a SPI NOR Flash chip

Some information on the partitions availible:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00020000 00010000 "bootloader"
mtd1: 00010000 00010000 "config"
mtd2: 00010000 00010000 "factory"
mtd3: 00010000 00010000 "crash"
mtd4: 00010000 00010000 "cfg_bak"
mtd5: 00200000 00010000 "overlay"
mtd6: 00da0000 00010000 "firmware"
mtd7: 00231eb4 00010000 "kernel"
mtd8: 00b6e14c 00010000 "rootfs"
mtd9: 004d0000 00010000 "rootfs_data"

device-tree describing partitions:

&spi0 {
	status = "okay";

	flash0: flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;

		partitions: partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "bootloader";
				reg = <0x0 0x20000>;
				read-only;
			};

			partition@20000 {
				label = "config";
				reg = <0x20000 0x10000>;
				read-only;
			};

			partition@30000 {
				label = "factory";
				reg = <0x30000 0x10000>;
				read-only;

				nvmem-layout {
					compatible = "fixed-layout";
					#address-cells = <1>;
					#size-cells = <1>;

					eeprom_factory_0: eeprom@0 {
						reg = <0x0 0x400>;
					};

					eeprom_factory_8000: eeprom@8000 {
						reg = <0x8000 0x200>;
					};

					macaddr_factory_4: macaddr@4 {
						compatible = "mac-base";
						reg = <0x4 0x6>;
						#nvmem-cell-cells = <1>;
					};

					macaddr_factory_28: macaddr@28 {
						reg = <0x28 0x6>;
					};
				};
			};

			partition@40000 {
				label = "crash";
				reg = <0x40000 0x10000>;
				read-only;
			};

			partition@50000 {
				label = "cfg_bak";
				reg = <0x50000 0x10000>;
				read-only;
			};

			partition@60000 {
				label = "overlay";
				reg = <0x60000 0x100000>;
				read-only;
			};

			partition@160000 {
				label = "firmware";
				reg = <0x160000 0xea0000>;
				compatible = "denx,uimage";
			};
		};
	};
};

You are pretty much on your own, just keep them aligned to 64kB eraseblock boundary.

If You could go below 192 KiB then not much would be required to change, or even nothing, if the U-Boot environment would be compiled in. Then writing simply to first 2 partitions would suffice. One caveat is You'll need to change (or delete) where uboot-tools package look for U-Boot environment.
Btw. there seem to be a lot of space wasted by crash, cfg_bak and overlay partitions, You could repurpose them if they are not used.

1 Like