Modify final initramfs image?

While adding support for the AVM FRITZ!Box 3390 I would like to find a way to modify an initramfs image on the device:

The FRITZ!Box has two SoC, a Lantiq and an ath79 SoC. The ath79 does not have any flash memory available and is booted by writing an initramfs image via raw ethernet frames. In oder to support configuration of the ath79 target, I would like to be able to rebuild an initramfs image on the lantiq device.

  • How should I configure the image generation so that it is possible to easily modify the image?
  • Can I instruct the system (kernel) to load the initramfs from a specific memory location? Note: there is no U-Boot present, hence some changes/configuration of lzma-loader might lead to a solution?

Thanks

I discovered similar with the 7490, and ultimately parked it. If you happen to find a solution to this I’d be interested to see how it works. Judging from the boot up of oem firmware, there appeared to be 2 or even 3 files that are sent over to the WiFi cpu - but I never found a way to get it to do anything other than turn on.

I'm basically done with the FRITZ!Box 3390 (I still have issues with the WiFi EEPROMs), see the relevant thread here: Port to AVM FRITZ!Box 3390

According to this article, you can append a gzipped cpio archive containing new or changed files to an existing initramfs image; it is not necessary to rebuild the whole image.

1 Like

Thanks, unfortunately, this seems to only work if the initramfs is built as an external file and not baked into the kernel, as it is done with OpenWrt.

arch/mips/ath79/prom.c from the kernel source suggests you can use initrd_start and initrd_size. Maybe they can be set with a built-in command line?

This isn´t true. All file are only appended and not compiled in!
On most targets you will have the kernel, initramfs and dtb compressed as one file...

For example on tp-link devices, you will have:

  • 512 byte tp-link header
  • compressed payload
    • uncompressed kernel
    • initramfs
    • dtb

I think the bigger problem is that you will have the device tree right after the initramfs.

How is your image build command for your image?

Edit: I´ve checked you github repo and see the image build steps now...

Even if its "baked into" the kernel file ... it's just a (z)cat file which can be devided into its parts. But without the buildscript you have to search for the file headers for splitting "by hand".

For me its not 100% clear what the threadstarter wants to achive. Are you building an image with openwrt sources? Do you have a build which you want to modify? If you build from sources there should be a initramfs config file which you can edit and target to the location where initramfs has to be loaded (there are several ways if you google). If you want to edit a given kernel imagefile then you have to extract the kernel file, split it, extract the parts (kernel and initramfs), make the changes and do the things backwards. But I would not recommend that if you want to change things inside kernel itself. Because you cannot just edit the kernel image (its a binary) like the initramfs. But for starters I've googled fast: https://blog.packagecloud.io/eng/2016/03/08/how-to-extract-and-disassmble-a-linux-kernel-image-vmlinuz/

@juppin: No, unfortunately, it's not that simple - initramfs is definitely not just appended: as @mpa has already pointed out, initrd_start and initrd_size are compiled in. Thus, if I want to modify the image, I'd have to modify initrd_start and initrd_size in the resulting binary.

@mpa: Unfortunately, I cannot just pass initrd_start and initrd_end via the firmware, because there is no U-Boot or other bootloader I have access to. The ath79 is booted via a proprietary network boot loader. I was unable to figure out the checksumming algorithm of this loader, so I cannot use U-Boot instead. However, it might be possible to modify lzma-loader to pass in the required addresses, but I haven't had the time to look into this.

@pwned: sorry if my initial post was unclear: I'm working on a FRITZ!Box 3390, which has two SoC on one board (Lantiq for DSL + 5GHz WiFi, Atheros for 2.4GHz WiFi). Both can run OpenWrt, but only one SoC (the Lantiq) has access to the flash chip, the other SoC is booted via the network. It runs entirely from RAM, so there is no easy way to configure the image. My idea was to configure the initramfs image on the Lantiq, which would require rebuilding the initramfs on the target, not on the host.

Anyway, thanks for all your replies. In the meantime, I'm using a different approach which works well enough for me:

Upon boot of the ath79, it waits for the Lantiq to upload a .tar.gz along with a script. The .tar.gz is unpacked to / and the script is executed before the boot process continues. This way, the WiFi firmware files as well as the configuration files can be used on the ath79. The two SoC communicate via raw Ethernet frames, so no IP configuration is necessary.