Cant seem to change the firmware image size

Hi all. I've been using the build environment at tag v21.02.0-rc4 to create SD-card firmware images for the FriendlyElec Nanopi R2S, and they work fine.

I'm planning to hook up an SPI NOR flash chip (the board has space for it) and play with that. I'd like to use the R/_W pin of the chip to have a true Read-Only device and I have some other plans.

Before that all can happen, I need to be able to control the size of the firmware image. However, whatever I set for CONFIG_TARGET_KERNEL_PARTSIZE and CONFIG_TARGET_ROOTFS_PARTSIZE, I seem to always get an ext4 image that's 92 MB and a squashfs image that's 67 MB.

I must be missing something obvious and would appreciate some pointers. Thanks...

squashfs image is as big as the files inside, and on first boot it will generate the read-write partition. Also afaik it is compressed with gzip so all empty space does not matter.
If you want to see the real size you need to ungzip the image and flash it to the device, then let it boot the first time to create the read-write partition.

For ext4 partition, it's again compressed with gzip so you need to ungzip to see the real size.

In the same make menuconfig page where you can set kernel and rootfs partsize there is an option to turn off gzip compression of the images.

OpenWrt needs to do some operations that require read-write storage on first boot like generating ssh keys, or running first-boot scripts that generate default configuration. So if you make images to load in a read-only system you should already include all your default configs and the ssh keys for the device. see Building the firmware for Raspberry Pi 4 with Wi-Fi enabled before first boot - #5 by bobafetthotmail

Since you want to make a true read-only system, you may also want to look at this thread too to remount the whole overlay in RAM Disable /etc config save

1 Like

Thank you for responding!

When I mentioned the file sizes I saw, I did mean after gunzip. Strangely when I tell it to not gzip the images this also does not seem to have any effect. The root fs tar I had it save seems to have about 9MB of files in it, so I just have no idea where this huge file size comes from. The gunzip for the images did complain about junk at the end that it was ignoring, if that helps...

Thank you for your pointers to make a true readonly system.

this is normal, OpenWrt appends stuff to the end of the gzipped file, this is read/used by the sysupgrade procedure but for gzip is garbage

in the rootfs you only have the userspace, the full image has a kernel and maybe a bootloader and/or boot firmware, but still it's not going to be much more than 5Mb so 9+5MB, so I don't know why it shows so big full images in your build.

If you flash the images on a USB drive or SD card maybe you can see where the space is used.

Thanks for the clarification...

How would I see?

the Linux system you use for development can see the contents of the partitions, at least for the ext4 type of image.

So after you flash the image you can see and mount the partitions of the SD card to a folder and run df -h or du -h in them or any other linux command to find who is using space.

For the squashfs image you probably need to boot openwrt and send these commands from inside the OpenWrt system.

for example from a x86 device

root@OpenMPTCProuter:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                49.5M     49.5M         0 100% /rom
devtmpfs                999.3M         0    999.3M   0% /rom/dev
tmpfs                   999.6M      4.2M    995.3M   0% /tmp
/dev/loop0              460.6M    112.0M    348.5M  24% /overlay
overlayfs:/overlay      460.6M    112.0M    348.5M  24% /
/dev/sda1                63.0M      5.1M     56.6M   8% /boot
/dev/sda1                63.0M      5.1M     56.6M   8% /boot
tmpfs                   512.0K         0    512.0K   0% /dev

I have the SD on the host Mac whereas I build on an Ubuntu in a VM. So instead of figuring out how to get my raw SD card to my VM, I used binwalk instead:

binwalk openwrt-rockchip-armv8-friendlyarm_nanopi-r2s-squashfs-sysupgrade.img 

132304        0x204D0         device tree image (dtb)
8388608       0x800000        device tree image (dtb)
8393148       0x8011BC        CRC32 polynomial table, little endian
9126140       0x8B40FC        device tree image (dtb)
33554432      0x2000000       Linux EXT filesystem, blocks count: 4096, image size: 4194304, rev 2.0, ext2 filesystem data, UUID=84173db5-fa99-e35a-95c6-28613cc73cc7, volume name "kernel"
40063984      0x26353F0       MPEG transport stream data
41443328      0x2786000       ELF, 64-bit LSB shared object, version 1 (SYSV)
41609216      0x27AE800       CRC32 polynomial table, little endian
41925395      0x27FBB13       Neighborly text, "neighbor get requestrequest"
41925445      0x27FBB45       Neighborly text, "neighbor get request get request"
41925500      0x27FBB7C       Neighborly text, "neighbor get request"
41925769      0x27FBC89       Neighborly text, "neighbor get requestrequest"
41925819      0x27FBCBB       Neighborly text, "neighbor get requestest"
41925865      0x27FBCE9       Neighborly text, "neighbor get request"
41925907      0x27FBD13       Neighborly text, "neighbor dump requestbor dump request"
41925965      0x27FBD4D       Neighborly text, "neighbor dump request dump request"
41926020      0x27FBD84       Neighborly text, "neighbor dump request attribute in neighbor dump request"
41926097      0x27FBDD1       Neighborly text, "neighbor dump requestequest"
41926139      0x27FBDFB       Neighborly text, "neighbor table dump requestbor table dump request"
41926197      0x27FBE35       Neighborly text, "neighbor table dump request neighbor table dump request"
41926261      0x27FBE75       Neighborly text, "neighbor table dump requestork address not specified"
41926440      0x27FBF28       Neighborly text, "Neighbor entry is now dead"
42856736      0x28DF120       Unix path: /dev/vc/0
42941992      0x28F3E28       Ubiquiti partition header, header size: 56 bytes, name: "PARTNAME=%s", base address: 0x74790A00, data size: 23295090 bytes
42947072      0x28F5200       xz compressed data
43057672      0x2910208       Unix path: /lib/firmware/updates/5.4.137
43135789      0x292332D       PARity archive data - Index file
43209137      0x29351B1       Copyright string: "Copyright(c) Pierre Ossman"
43238056      0x293C2A8       Unix path: /sys/firmware/devicetree/base
43239953      0x293CA11       Unix path: /sys/firmware/fdt': CRC check failed
43255809      0x2940801       Neighborly text, "neighbor table overflow!app_solicit"
43281696      0x2946D20       Neighborly text, "NeighborSolicits"
43281720      0x2946D38       Neighborly text, "NeighborAdvertisementsErrors"
43284858      0x294797A       Neighborly text, "neighbor %.2x%.2x.%pM lost hash_elasticity option has been deprecated and is always %u"
46088192      0x2BF4000       device tree image (dtb)
67108864      0x4000000       Squashfs filesystem, little endian, version 4.0, compression:xz, size: 2569966 bytes, 831 inodes, blocksize: 262144 bytes, created: 2021-07-31 17:21:01

As you can see it's chatty and detects more than there is, but I do see what My problem is: my kernel and squashfs are put at 32M and 64M respectively, so I would always come out a few MB past 64M.

I guess I need to understand what determines where in the image these partitions end up and/or what size they are.

(This is a FriendlyElec Nanopi R2S, based on a Rockchip 3328.)

can't you just do USB passthrough of the USB-SDcard adapter to the VM? Virtualbox, Fusion and Parallels can do that in a few clicks.

Anyways, the image config files for your device in the build system is here

Yes it is called sysupgrade but devices with sdcard/USB/whatever images use the same image for first install and for sysupgrade.

The list of commands it is giving
boot-common | boot-script nanopi-r2s | pine64-img | gzip | append-metadata
are mostly handled in the makefile that actually assembles this image, the interesting part is the pine64-img as that is the step where everything is combined, which is here

Yes I know Pine64 is not your device, but it seems your device was added to this target after the Pine64 (see the first link above, there is also Pine64 in the list) and therefore it is just reusing the same code to generate the SDcard images since the devices are using the same SoC/hardware.

From the comments and the website page linked, it seems it is adding padding and placing things like that because it is required by first stage bootloader and because it expects to have space for ARM Trustzone firmware blobs, or some other technical reasons like that.

Thank you !!

Everything is much clearer now. At least I now understand where the 32M and 64M offsets come from. Reading it in a bit more depth, I don't think the 32M separation is a requirement of the first stage boot the way the first 2M and 4M offsets seem to be hard requirements. Building now, let's see what happens.

Thanks for the step by step tutorial!

This quest continues in a new thread I called:

Created NanoPi R2S (Rockchip rk3328) 16MB image. Next: boot from SPI flash

because that title is more likely to be found by the people that need it. It contains the complete patch file and config to create a 16MB image.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.