initramfs cpio 아카이브를 다시 패키지하는 방법은 무엇입니까?

initramfs cpio 아카이브를 다시 패키지하는 방법은 무엇입니까?

initramfs cpio 아카이브의 압축을 풀고 다음을 사용하여 다시 패키지했습니다 sudo find -depth | sudo cpio -o -H newc > ~/repacked_initramfs.cpio.https://salsa.debian.org/kernel-team/initramfs-tools/-/blob/master/mkinitramfs?ref_type=heads#L492

repacked_initramfs.cpio는 원본과 정확히 같은 크기입니다.

~ $ ls -lA initramfs.cpio repacked_initramfs.cpio
-rw-r--r-- 1 fadedbee fadedbee 227892224 Apr  3 15:27 initramfs.cpio
-rw-r--r-- 1 fadedbee fadedbee 227892224 Apr  8 15:32 repacked_initramfs.cpio

gzip 압축 후의 크기는 약간 다릅니다.

root@smarcimx8mq4g:~# ls -lA initramfs.cpio repacked_initramfs.cpio
-rw-r--r-- 1 root root 227892224 Apr  3 14:27 initramfs.cpio
-rw-r--r-- 1 user user 227892224 Apr  8 14:32 repacked_initramfs.cpio

root@smarcimx8mq4g:~# gzip initramfs.cpio

root@smarcimx8mq4g:~# gzip repacked_initramfs.cpio 

root@smarcimx8mq4g:~# ls -lA initramfs.cpio.gz repacked_initramfs.cpio.gz 
-rw-r--r-- 1 root root 68217581 Apr  3 14:27 initramfs.cpio.gz
-rw-r--r-- 1 user user 68212934 Apr  8 14:32 repacked_initramfs.cpio.gz

.img 파일의 크기도 마찬가지입니다.

root@smarcimx8mq4g:~# mkimage -A arm64 -O linux -T ramdisk -n "Initial Ram Disk" -d initramfs.cpio.gz initramfs.img
Image Name:   Initial Ram Disk
Created:      Mon Apr  8 15:29:54 2024
Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
Data Size:    68217581 Bytes = 66618.73 KiB = 65.06 MiB
Load Address: 00000000
Entry Point:  00000000

root@smarcimx8mq4g:~# mkimage -A arm64 -O linux -T ramdisk -n "Initial Ram Disk" -d repacked_initramfs.cpio.gz repacked_initramfs.img
Image Name:   Initial Ram Disk
Created:      Mon Apr  8 15:30:21 2024
Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
Data Size:    68212934 Bytes = 66614.19 KiB = 65.05 MiB
Load Address: 00000000
Entry Point:  00000000

root@smarcimx8mq4g:~# ls -lA initramfs.img repacked_initramfs.img 
-rw-r--r-- 1 root root 68217645 Apr  8 15:29 initramfs.img
-rw-r--r-- 1 root root 68212998 Apr  8 15:30 repacked_initramfs.img

원래 initramfs에서 부팅하면 initramfs에서 실제 rootfs가 마운트되고 예상되는 로그인 프롬프트가 표시됩니다.

u-boot$ setenv loadinitrd ext4load mmc ${mmcdev}:2 ${initrd_addr} /root/initramfs.img
u-boot$ setenv mmcboot "echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then run loadinitrd ; booti ${loadaddr} ${initrd_addr} ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else echo wait for boot; fi;"
u-boot$ run bootcmd
Setting bus to 0
1050 bytes read in 13 ms (78.1 KiB/s)
Importing environment from mmc (uEnv.txt)...
30075392 bytes read in 1280 ms (22.4 MiB/s)
49035 bytes read in 20 ms (2.3 MiB/s)
Booting from mmc ...
49035 bytes read in 19 ms (2.5 MiB/s)
68217645 bytes read in 2849 ms (22.8 MiB/s)
## Loading init Ramdisk from Legacy Image at 43800000 ...
   Image Name:   Initial Ram Disk
   Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
   Data Size:    68217581 Bytes = 65.1 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 43000000
   Booting using the fdt blob at 0x43000000
   Using Device Tree in place at 0000000043000000, end 000000004300ef8a

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
...
[    7.655738] Freeing unused kernel memory: 3008K
[    7.669121] Run /init as init process
Loading, please wait...
[    7.715755] udevd[246]: starting version 3.2.9
...
smarcimx8mq4g login:

그러나 다시 패키징된 initramfs를 통해 다음을 볼 수 있습니다.

u-boot$ setenv loadinitrd ext4load mmc ${mmcdev}:2 ${initrd_addr} /root/repacked_initramfs.img
u-boot$ setenv mmcboot "echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then run loadinitrd ; booti ${loadaddr} ${initrd_addr} ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else echo wait for boot; fi;"
u-boot$ run bootcmd
Setting bus to 0
1050 bytes read in 13 ms (78.1 KiB/s)
Importing environment from mmc (uEnv.txt)...
30075392 bytes read in 1281 ms (22.4 MiB/s)
49035 bytes read in 19 ms (2.5 MiB/s)
Booting from mmc ...
49035 bytes read in 19 ms (2.5 MiB/s)
68212998 bytes read in 2853 ms (22.8 MiB/s)
## Loading init Ramdisk from Legacy Image at 43800000 ...
   Image Name:   Initial Ram Disk
   Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
   Data Size:    68212934 Bytes = 65.1 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 43000000
   Booting using the fdt blob at 0x43000000
   Using Device Tree in place at 0000000043000000, end 000000004300ef8a

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
...
[    6.868638] Freeing unused kernel memory: 3008K
[    6.880635] Run /init as init process
[    6.884549] Failed to execute /init (error -2)
[    6.889004] Run /sbin/init as init process
[    6.893169] Run /etc/init as init process
[    6.897247] Run /bin/init as init process
[    6.901328] Run /bin/sh as init process
[    6.905221] Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.
[    6.919390] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.10.9 #43
[    6.925394] Hardware name: Embedian SMARC-iMX8M Computer on Module HDMI (DT)
[    6.932440] Call trace:
[    6.932617] usb 3-1.2: new high-speed USB device number 3 using xhci-hcd
[    6.934895]  dump_backtrace+0x0/0x1b0
[    6.945239]  show_stack+0x18/0x68
[    6.948556]  dump_stack+0xd8/0x134
[    6.951957]  panic+0x174/0x33c
[    6.955012]  kernel_init+0xfc/0x118
[    6.958500]  ret_from_fork+0x10/0x34
[    6.962078] SMP: stopping secondary CPUs
[    6.966509] Kernel Offset: disabled
[    6.969997] CPU features: 0x0240002,2000200c
[    6.974264] Memory Limit: none
[    6.977324] ---[ end Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance. ]---

repacked-initramfs.cpio를 다시 추출하고 /init가 존재하며 initramfs.cpio와 동일한 권한, 소유권 및 sha1sum을 가지고 있음을 증명했습니다.

repacked_initramfs.cpio에 /init가 올바르게 있음에도 불구하고 커널이 /init를 찾지 못하게 만드는 재패키징 실수로는 어떤 것이 있습니까?

답변1

내 cpio 파이프라인에 추가했고 LC_ALL=C sort이제 커널 /initrepacked_initramfs.img.

sudo find . | LC_ALL=C sort | sudo cpio -o -H newc > ~/repacked_initramfs.cpio

커널은 initramfs 파일이 전체 경로를 기준으로 영숫자로 정렬될 것으로 예상해야 합니다. "/init"가 적절한 위치에 없으면 커널이 이를 찾을 수 없습니다.

관련 정보