I am struggling to get a Broadcom ARM9 platform to boot from a kernel that does not have a built-in initrd image.
I have successfully compiled the vendor kernel and U-Boot for the platform. Note that both kernel and U-Boot are forks from upstream, so I am unable to test with mainline releases.
I can successfully boot a kernel with a built-in initramfs CONFIG_INITRAMFS_SOURCE=rootfs.cpio
generated by Buildroot:
u-boot> bootm
## Booting kernel from FIT Image at 70000000 ...
Using '24' configuration
Trying 'kernel' kernel subimage
Description: Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x700000bc
Data Size: 6895136 Bytes = 6.6 MiB
Architecture: ARM
OS: Linux
Load Address: 0x60008000
Entry Point: 0x60008000
Hash algo: sha1
Hash value: ddb314e7d5409237fe4c00644d70c55f9f18c67c
Verifying Hash Integrity ... sha1+ OK
## Flattened Device Tree from FIT Image at 70000000
Using '24' configuration
Trying 'fdt24' FDT blob subimage
Description: MS225-24 DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x706937c4
Data Size: 9148 Bytes = 8.9 KiB
Architecture: ARM
Hash algo: sha1
Hash value: ff70437562340a11455a1b3552e745539d903c33
Verifying Hash Integrity ... sha1+ OK
Loading FDT from 0x706937c4 to 0x00000000
Booting using the fdt blob at 0x(null)
Loading Kernel Image ... OK
OK
boot_prep_linux commandline: console=ttyS0,115200n8 earlyprintk ubi.mtd=ubi
Loading Device Tree to 9fee1000, end 9fee63bb ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 3.18.131 (root@40e39c311f61) (gcc version 11.3.0 (Buildroot 2023.02.1) ) #1 Thu May 18 20:23:29 UTC 2023
[ 0.000000] CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Meraki Brumby
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] CPU: All CPU(s) started in SVC mode.
This is the same method the vendor firmware uses to boot.
Contents of the image tree source file:
/dts-v1/;
/ {
description = "Meraki Brumby FIT Image";
#address-cells = <1>;
images {
kernel {
description = "Kernel";
data = /incbin/("zImage");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x60008000>;
entry = <0x60008000>;
hash {
algo = "sha1";
};
};
fdt24 {
description = "MS225-24 DTB";
data = /incbin/("meraki-brumby24p.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
load = <0x0>;
hash {
algo = "sha1";
};
};
fdt48 {
description = "MS225-48 DTB";
data = /incbin/("meraki-brumby48.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
load = <0x0>;
hash {
algo = "sha1";
};
};
};
configurations {
default = "24";
24 {
description = "Meraki brumby 24";
kernel = "kernel";
fdt = "fdt24";
hash {
algo = "sha1";
};
};
48 {
description = "Meraki brumby 48";
kernel = "kernel";
fdt = "fdt48";
hash {
algo = "sha1";
};
};
};
};
However if I take the same kernel, and build it without CONFIG_INITRAMFS_SOURCE
but instead provide (the same) rootfs.cpio
in the FIT image, it does not boot:
u-boot> bootm
## Booting kernel from FIT Image at 70000000 ...
Using '24' configuration
Trying 'kernel' kernel subimage
Description: Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x700000bc
Data Size: 1879088 Bytes = 1.8 MiB
Architecture: ARM
OS: Linux
Load Address: 0x60008000
Entry Point: 0x60008000
Hash algo: sha1
Hash value: 8ba797a97ddd6b5925172644307af1e12dd1bc6c
Verifying Hash Integrity ... sha1+ OK
## Loading init Ramdisk from FIT Image at 70000000 ...
Using '24' configuration
Trying 'ramdisk' ramdisk subimage
Description: ramdisk
Type: RAMDisk Image
Compression: uncompressed
Data Start: 0x701cadcc
Data Size: 4946988 Bytes = 4.7 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00000000
Entry Point: 0x00000000
Hash algo: sha1
Hash value: 69d44c28fccf9babbe018511ef3e4fe9c043c427
Verifying Hash Integrity ... sha1+ OK
## Flattened Device Tree from FIT Image at 70000000
Using '24' configuration
Trying 'fdt24' FDT blob subimage
Description: MS225-24 DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x70682ae0
Data Size: 9148 Bytes = 8.9 KiB
Architecture: ARM
Hash algo: sha1
Hash value: ff70437562340a11455a1b3552e745539d903c33
Verifying Hash Integrity ... sha1+ OK
Booting using the fdt blob at 0x70682ae0
Loading Kernel Image ... OK
OK
boot_prep_linux commandline: console=ttyS0,115200n8 earlyprintk ubi.mtd=ubi
Loading Ramdisk to 9fa2f000, end 9fee6c2c ... OK
Loading Device Tree to 9fa29000, end 9fa2e3bb ... OK
Starting kernel ...
Contents of the image tree source file:
/dts-v1/;
/ {
description = "Meraki Brumby FIT Image";
#address-cells = <1>;
images {
kernel {
description = "Kernel";
data = /incbin/("zImage");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x60008000>;
entry = <0x60008000>;
hash {
algo = "sha1";
};
};
ramdisk {
description = "ramdisk";
data = /incbin/("rootfs.cpio.lzma");
type = "ramdisk";
arch = "arm";
os = "linux";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash {
algo = "sha1";
};
};
fdt24 {
description = "MS225-24 DTB";
data = /incbin/("meraki-brumby24p.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash {
algo = "sha1";
};
};
fdt48 {
description = "MS225-48 DTB";
data = /incbin/("meraki-brumby48.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash {
algo = "sha1";
};
};
};
configurations {
default = "24";
24 {
description = "Meraki brumby 24";
kernel = "kernel";
ramdisk = "ramdisk";
fdt = "fdt24";
hash {
algo = "sha1";
};
};
48 {
description = "Meraki brumby 48";
kernel = "kernel";
ramdisk = "ramdisk";
fdt = "fdt48";
hash {
algo = "sha1";
};
};
};
};
According to this mailing list post the load
address of the ramdisk
does not matter for a FIT image, although it is required by U-Boot. Failing to provide the load
address of the ramdisk
results in the following error:
Can't get ramdisk subimage load address!
Ramdisk image is corrupt or invalid
The kernel is compiled with CONFIG_RD_LZMA=y
, and providing CONFIG_INITRAMFS_SOURCE=rootfs.cpio.lzma
works, so it is not an issue of the kernel being unable to decompress the ramdisk specified in the FIT image.
The kernel with built-in initrd is around ~70KB larger than the FIT image (6895136 bytes versus 6826076), which I haven't investigated but assume may be due to overhead of including a built-in initrd. Both the kernel and initrd are LZMA compressed. I have tried other compression methods (gzip
) without success.
I am also fairly confident this is not an issue of memory mapping or overwriting, as I have mistakenly created a FIT image containing a zImage with built-in initrd, ramdisk
from the FIT image, and device tree (totaling ~14MB). If there was an issue with the load
or entry
being incorrect, I would expect the FIT-with-ramdisk scenario to fail too, and it does not:
u-boot> bootm
## Booting kernel from FIT Image at 70000000 ...
Using '24' configuration
Trying 'kernel' kernel subimage
Description: Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x700000bc
Data Size: 8495752 Bytes = 8.1 MiB
Architecture: ARM
OS: Linux
Load Address: 0x60008000
Entry Point: 0x60008000
Hash algo: sha1
Hash value: ec94a62986d70635ccd7b023d600b83c22e3aff0
Verifying Hash Integrity ... sha1+ OK
## Loading init Ramdisk from FIT Image at 70000000 ...
Using '24' configuration
Trying 'ramdisk' ramdisk subimage
Description: ramdisk
Type: RAMDisk Image
Compression: uncompressed
Data Start: 0x7081a424
Data Size: 5345280 Bytes = 5.1 MiB
Architecture: ARM
OS: Linux
Load Address: 0x61008000
Entry Point: 0x61008000
Hash algo: sha1
Hash value: 1dc96437bf2424fc372851148cbf0296c5b61354
Verifying Hash Integrity ... sha1+ OK
## Flattened Device Tree from FIT Image at 70000000
Using '24' configuration
Trying 'fdt24' FDT blob subimage
Description: MS225-24 DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x70d3350c
Data Size: 9010 Bytes = 8.8 KiB
Architecture: ARM
Hash algo: sha1
Hash value: 58a2bd3c7bfe085020e704b6655861e0e4a274d1
Verifying Hash Integrity ... sha1+ OK
Loading FDT from 0x70d3350c to 0x00000000
Booting using the fdt blob at 0x(null)
Loading Kernel Image ... OK
OK
boot_prep_linux commandline: console=ttyS0,115200n8 earlyprintk ubi.mtd=ubi mtdparts=m25p80:0xc0000(u-boot)ro,0x10000(env),0x30000(shmoo)ro,0xA00000(fit),0x500000(overlay)
Loading Ramdisk to 9f9cd000, end 9fee6000 ... OK
Loading Device Tree to 9f9c7000, end 9f9cc331 ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 3.18.131 (root@0b1f5507523e) (gcc version 8.4.0 (Buildroot 2021.02.7) ) #1 Mon May 1 20:05:46 UTC 2023
[ 0.000000] CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Meraki Brumby
The bare kernel, without a built-in initrd, and without a ramdisk
in the FIT image, also fails to boot:
u-boot> bootm
## Booting kernel from FIT Image at 70000000 ...
Using '24' configuration
Trying 'kernel' kernel subimage
Description: Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x700000bc
Data Size: 1879952 Bytes = 1.8 MiB
Architecture: ARM
OS: Linux
Load Address: 0x60008000
Entry Point: 0x60008000
Hash algo: sha1
Hash value: 2fb4e06ea0400d54fa14cc8427ab60036c06b9c5
Verifying Hash Integrity ... sha1+ OK
## Flattened Device Tree from FIT Image at 70000000
Using '24' configuration
Trying 'fdt24' FDT blob subimage
Description: MS225-24 DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x701cb134
Data Size: 9148 Bytes = 8.9 KiB
Architecture: ARM
Hash algo: sha1
Hash value: ff70437562340a11455a1b3552e745539d903c33
Verifying Hash Integrity ... sha1+ OK
Loading FDT from 0x701cb134 to 0x00000000
Booting using the fdt blob at 0x(null)
Loading Kernel Image ... OK
OK
boot_prep_linux commandline: console=ttyS0,115200n8 earlyprintk ubi.mtd=ubi
Loading Device Tree to 9fee1000, end 9fee63bb ... OK
Starting kernel ...
Kernel .config (without CONFIG_INITRAMFS_SOURCE
but otherwise identical to the "it boots!" scenario).
Why won't this kernel boot without a built-in initrd?! (╯ರ ~ ರ)╯︵ ┻━┻