今天,我们要来作Alpine Linux的initramfs bootstrapping。
在近代的大型distro中,多半都会善用early stage userspace,去进行比较复杂的rootfs初始化;各家的initramfs风格、打造方式可以差距到非常大,例如Arch Linux的工具是mkinitcpio
、Gentoo的则是Dracut
、Debian体系则是initramfs-tools
。
可是虽然风格回异,这些initramfs的基本精神与流程皆是:从/proc/cmdline去拿到kernel boot arguements,然後爬看看有没有initramfs要预处理的option,例如可能是nbd啦、或着initramfs特有的特技,例如Gentoo可以支援livenet
这个透过http去拿rootfs的方式;然後处理好rootfs mounting後,便会透过 switch_root 或着 pivot_root的方式去更换root node、然後启动rootfs上的 init system ,例如 systemd
或着 openrc
等等。
然而,这边一样有个鸡蛋问题,那就是这些initramfs的生成,通常是在一个native的环境底下,进行self-bootstrapping的;但是我们现在还没有native的环境可以用,那怎麽办呢?依笔者前年的作法,那便是去偷Alpine on ARMv7的来用XDDDDD
首先我们去 Alpine 官网下载 Generic ARM (ARMv7) 的 tar 包下来,解压缩完,可以在boot资料夹底下看到 initramfs-lts
这个gzip压缩过的cpio档案。那麽,就来拆包吧:
mkdir extract
cd extract
cat ../initramfs-lts | gzip -d -c | cpio -idv
接着 tree 一下来看有哪些东西:
├── bin
│ ├── busybox
│ └── sh -> /bin/busybox
├── dev
├── etc
│ ├── apk
│ │ └── keys
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── fstab
│ ├── group
│ ├── mdev.conf
│ ├── modprobe.d
│ │ ├── aliases.conf
│ │ ├── blacklist.conf
│ │ ├── i386.conf
│ │ └── kms.conf
│ └── passwd
├── init
├── lib
│ ├── firmware
│ │ ├── ene-ub6250
│ │ │ ├── ms_init.bin
│ │ │ ├── msp_rdwr.bin
│ │ │ ├── ms_rdwr.bin
│ │ │ ├── sd_init1.bin
│ │ │ ├── sd_init2.bin
│ │ │ └── sd_rdwr.bin
│ │ └── qcom
│ ├── libcryptsetup.so.12 -> libcryptsetup.so.12.6.0
│ ├── libcryptsetup.so.12.6.0
│ ├── libdevmapper.so.1.02
│ ├── libkmod.so.2 -> libkmod.so.2.3.7
│ ├── libkmod.so.2.3.7
│ ├── libssl.so.1.1
│ ├── libuuid.so.1 -> libuuid.so.1.3.0
│ ├── libuuid.so.1.3.0
│ ├── libz.so.1 -> libz.so.1.2.11
│ ├── libz.so.1.2.11
│ ├── mdev
│ │ ├── dvbdev
│ │ ├── ide_links
│ │ ├── usbdev
│ │ ├── usbdisk_link
│ │ └── xvd_links
│ └── modules
│ └── 5.10.61-0-lts
│ ├── kernel
│ │ ├── arch
│ │ │ └── arm
│ │ │ └── lib
│ │ │ └── xor-neon.ko
│ │ ├── block
│ │ │ └── t10-pi.ko
......
此时,因为我们只要最基础的骨架,firmware
跟modules
这部份是给wifi firmware还有一些driver的,就直接大刀阔斧的干掉。紧接着开始去我们之前千辛万苦打出来Alpine package repo捞出对应的骨干来用:
sudo apk -vv --allow-untrusted -X /path/to/packages/main/ -U --arch riscv32 --root $PWD/tmp_rootfs --initdb add alpine-base mkinitfs
紧接着就是非常手工艺地,把busybox、各式 shared object一个个换进去ARM initramfs里面。
做完替换後,我们先把这份initramfs扔进一个loop dev image里面,给之前buildroot的rv32 qemu virt试验看看:
``
$ qemu-system-riscv32 -M virt -bios output/images/fw_jump.elf -kernel output/images/Image -append "rootwait root=/dev/vda rw init=/init" -drive file=/path/to/images.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev user,id=net0 -device virtio-net-device,netdev=net0 -nographic
OpenSBI v0.9
/ __ \ / | _ _ |
| | | | __ ___ _ __ | ( | |) || |
| | | | '_ \ / _ \ '_ \ ___ | _ < | |
| |__| | |) | __/ | | |) | |) || |
_/| ./ _|| ||/|____/__|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : timer,mfdeleg
Platform HART Count : 1
Firmware Base : 0x80000000
Firmware Size : 124 KB
Runtime SBI Version : 0.2
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*
Domain0 Region00 : 0x80000000-0x8001ffff ()
Domain0 Region01 : 0x00000000-0xffffffff (R,W,X)
Domain0 Next Address : 0x80400000
Domain0 Next Arg1 : 0x82200000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART ISA : rv32imafdcsu
Boot HART Features : scounteren,mcounteren,time
Boot HART PMP Count : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 32
Boot HART MHPM Count : 0
Boot HART MHPM Count : 0
Boot HART MIDELEG : 0x00000222
Boot HART MEDELEG : 0x0000b109
[ 0.000000] Linux version 5.10.7 (ruinland@ruinland-x1c) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.08-235-g287a359090) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #2 SMP Sun Sep 12 22:40:18 CST 2021
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80400000
[ 0.000000] efi: UEFI not found.
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000080400000-0x0000000087ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080400000-0x0000000087ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080400000-0x0000000087ffffff]
[ 0.000000] SBI specification v0.2 detected
[ 0.000000] SBI implementation ID=0x1 Version=0x9
[ 0.000000] SBI v0.2 TIME extension detected
[ 0.000000] SBI v0.2 IPI extension detected
[ 0.000000] SBI v0.2 RFENCE extension detected
[ 0.000000] SBI v0.2 HSM extension detected
...
[ 0.669946] EXT4-fs (vda): mounting ext2 file system using the ext4 subsystem
[ 0.679685] EXT4-fs (vda): warning: mounting unchecked fs, running e2fsck is recommended
[ 0.697676] EXT4-fs (vda): mounted filesystem without journal. Opts: (null)
[ 0.699126] ext2 filesystem being mounted at /root supports timestamps until 2038 (0x7fffffff)
[ 0.700403] VFS: Mounted root (ext2 filesystem) on device 254:0.
[ 0.706050] devtmpfs: mounted
[ 0.761174] Freeing unused kernel memory: 204K
[ 0.763022] Run /init as init process
[ 1.348089] Alpine Init 3.5.0-r0
Alpine Init 3.5.0-r0
[ 1.362497] Loading boot drivers...
虽然 `nlplug-findfs` 这只Alpine initramfs拿来rootfs find and mount的helper会trigger runtime failure,但那可能是因为我们还没有给他正确root dev的关系,我们下一章,就来debug吧~
<<: Day10 在 Next.js 安装 apollo-graphql,串接 WordPress GraphQL API(下)
>>: [第十天]从0开始的UnityAR手机游戏开发-Vuforia多张图卡辨识
由於Object一般都很大,几十GB都属於正常现象,所以上传或下载的过程中难免回遇到网路不稳的问题导...
setTimeout setTimeout:定时器,只执行一次,属於非同步,因此就算设定 0 秒执行...
大家好~ 我是五岁~ 今天来继续改善昨天的九尾狐草图吧~ 首先把耳朵厚度加厚了,并且加上毛茸茸的前饰...
简介 官方github连结: 英文文档 、 中文文档 ExcelJS 这个套件可以高弹性的将资料汇出...
从刚开始看程序码总觉得他们是蚯蚓, 我终於找到一件比做设计还难的事, 当然学习的过程, 没有我想像中...