OpenWrt 19.07 on devices with small kernel partition

Why can't I throw away unnecessary hardware from kernel to shrink the size? I could not find something specific about kernel_menuconfig, whatever I did, lzma image still the same size.

The image has gotten, but not tested yet:
ap147_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14328k(rootfs),1672k(kernel),64k(art)ro,16000k@0x50000(firmware)

I subtracted 200Kb from rootfs and added that to kernel partition. Still don't know correctly is... I think it can cause problems with rootfs_data partition at least... but maybe u-boot will not find kernel.

1 Like

Seeing that there is a u-boot-env partition, would it be an option to change the entry-point after the bootloader? If you can make it boot from 0x50000 instead of 0xe8000, you wouldn't have to care as much about not running into the art partition and you could just use a dynamic firmware partition split.

What I have scratched from u-boot-env partition:

# fw_printenv 
bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ath-nor0:256k(u-boot),64k(u-boot-env),14528k(rootfs),1408k(uImage),64k(mib0),64k(ART)
bootdelay=2
baudrate=115200
ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee
dir=
lu=tftp 0x80060000 ${dir}u-boot.bin&&erase 0x9f000000 +$filesize&&cp.b $fileaddr 0x9f000000 $filesize
lf=tftp 0x80060000 ${dir}ap143${bc}-jffs2&&erase 0x9f050000 +0xE30000&&cp.b $fileaddr 0x9f050000 $filesize
lk=tftp 0x80060000 ${dir}vmlinux${bc}.lzma.uImage&&erase 0x9fE80000 +$filesize&&cp.b $fileaddr 0x9fE80000 $filesize
bc=AP147-16M
filesize=28780
fileaddr=80060000
lok=tftp 0x80060000 openwrt-ar71xx-generic-${bc}-kernel.bin && erase 0x9f680000 +${filesize} && cp.b $fileaddr 0x9f680000 0x160000
lqsdk=run lof && run lok
bootcmd=bootm 0x9fE80000
lof=tftp 0x80060000 openwrt-ar71xx-generic-${bc}-squashfs-sysupgrade.bin && erase 0x9f050000 +${filesize} && cp.b $fileaddr 0x9f050000 $filesize
stdin=serial
stdout=serial
stderr=serial
ethact=eth0
ipaddr=192.168.2.2
serverip=192.168.2.1

It confuses me even more, because the kernel partition size is 1408k

My guess is that the bootargs from u-boot are patched out in the OpenWrt kernel. To be sure, you can check /proc/cmdline in OpenWrt to see what bootargs were actually used.

I don't really understand how ar71xx/legacy.mk works, but maybe changing the partition layout to the following will be sufficient to generate an image with kernel:rootfs instead of rootfs:kernel:
ap147_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro

If you can then permanently modify u-boot to boot from the start of the firmware partition, you don't have to worry about the kernel size any more.

setenv bootcmd bootm 0x50000
saveenv

One question before I'll continue: why is the image weight 17970432 bytes instead 16262165 which I had before? Is it normal?

It needs to specify. What binwalk shows me on old image which works now:

And new, generated by "16000k(firmware)"

I think it does not fit

So, I turned back to my previous idea and got a positive result!
It took times to calculate "magic number" to boot kernel. I opened old sysupgrade image in hex editor, then found the address where kernel starts, then did the same for new image and then subtracted it from old address, then the result subtracted from old magic number.
Thus:

00E30000 (old kernel address) - 00DFE000 (new kernel address) = 32000
9fE80000 (old magic number) - 32000 = 9FE4E000

It seems that the build system uses rootfs or firmware partition size and always appends a uImage with the kernel. In that case, my suggestion by itself wont be enough and you have to find a way to place the uImage before the rootfs.

That 'magic' number is the address where the flash is mapped to. Address 0x9f000000 refers to the first byte of the flash. 0x9fe80000 is just the address of the kernel image then (0xe80000 = 256kiB+64kiB+14528kiB).

If you change the partition sizes, note that it might be best to stick to multiples of 64k.

Ok, but why and what does it threaten in the future?

I don't know if you've tried running with a modified firmware layout yet, but e.g. the mtd splitter that dynamically creates the rootfs-data overlay rounds partition sizes to an erase block. If the end of your rootfs partition doesn't align with an EB, then your kernel may or may not get corrupted.

Wow! I have never calculated hex before: (1024*256=262144=0x40000) + (1024*64=65536=0x10000) + (1024*14528=14876672=0xE30000) = 15204352 or 0xE80000
Just leave it here to come back if I'll forget again :slight_smile:

1 Like

Yes, I ran, it works.

Even I am facing the same issue with 19.07 branch for ap147-10, being a newbie to Openwrt platform, can you please tell the final fix to generate squashfs.bin image.

There is no final fix, I've just done it for myself.
Ok, I'll tell you the algorithm what I did:

  1. get git repository
  2. Edit file target/linux/ar71xx/image/legacy.mk and replace ap147_mtdlayout with
    ap147_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14328k(rootfs),1672k(kernel),64k(art)ro,16000k@0x50000(firmware)
  3. make menuconfig and choose the platform.
  4. make
  5. you need to connect to your device via UART and use any terminal emulator (for example putty)
  6. upload image with uboot menu and tftp (you can upload it via web or sysupgrade, but the device will not boot), I recommend to learn to use tftp if something went wrong and you'll want to get back an old image:
    tftpboot 0x80060000 openwrt-19.07.3-ar71xx-generic-ap147-010-squashfs-sysupgrade.bin && erase 0x9f050000 +${filesize} && cp.b $fileaddr 0x9f050000 $filesize
  7. change magic number to new address:
    setenv bootcmd bootm 0x9FE4E000
    saveenv

I could help you to build the image, but you anyway need to get in to uboot menu and change magic number. ( item 7).

Hi thanks, I tried this workaround, but still could not get the openwrt-19.07-ar71xx-generic-ap147-010-squashfs-sysupgrade.bin image, Is there any more files to modified

How did calculate the magic number, is there any way to update this magic number, before the build in the uboot package.

Hmmm... As I understand, you need to update u-boot-env partition as well, but it is in read-only more, I did not think about it.
The second way is to shrink the kernel size by cut out unneeded options. This what I tried to do at first, but fail.

I think the way is to update existing firmware with unlocked u-boot-env partition, then change magic number from userspace with fw_setenv and then upgrade it to new firmware with modified kernel space.

It is been a while, I noticed that the problem was fixed in regular tree of OpenWrt, I've just easily compiled the image for AP147_10 with version 19.07.6. But, today I've discovered that the ImageBuilder version is still have this bug:

Image Name:   MIPS OpenWrt Linux-4.14.221
Created:      Wed Mar 10 18:14:26 2021
Image Type:   MIPS Linux Kernel Image (lzma compressed)
Data Size:    1589436 Bytes = 1552.18 KiB = 1.52 MiB
Load Address: 80060000
Entry Point:  80060000

The directory build_dir/target-mips_24kc_musl//linux-ar71xx_generic/ of openwrt-imagebuilder-19.07.7-ar71xx-generic.Linux-x86_64 does not have any custom image for this profile... I guess it must have?

so... could maintainers fix that?