时间轴

2025-12-31

init


环境

OS

使用wsl的archlinux

环境

compiler

ARM目前总共发布了8种架构:ARMv1、ARMv2、ARMv3、ARMv4、ARMv5、ARMv6、ARMv7、ARMv8。

针对于Cortex-A5x处理器可以使用aarch64-linux-gnu-gcc -march=armv8-a命令编译代码,ARM GNU编译器可通过下面的链接下载

我使用的是archlinux上通过pacman下载的aarch64-linux-gnu-gcc版本是15.1.0

aarch64-linux-gnu-gcc

编译内核

1
2
3
4
5
6
7
8
9
10
11
12
git clone --branch rpi-5.10.y --single-branch https://github.com/raspberrypi/linux.git
make mrproper
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_prepare
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j$(nproc)

# 这一步安装驱动,拷贝到根文件系统
make modules_install INSTALL_MOD_PATH=/home/zhaohang/repository/linux/busybox-1.37.0/_install/

mkdir -p ~/tftp/raspi4b
cp arch/arm64/boot/Image ~/tftp/raspi4b
cp arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dtb ~/tftp/raspi4b

输出:

  • arch/arm64/boot/Image
  • arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dtb

编译根文件系统

busybox

参考:

buildroot

Archlinux默认工具链及AUR提供的交叉工具链都是无法复制使用的,Buildroot在构建时会将工具链复制到工作目录执行,因此我们需要选择Portable的工具链二进制或者选择crosstool-NG编译工具链。

1
2
3
4
5
6
7
wget https://buildroot.org/downloads/buildroot-2025.11.tar.gz
# WSL下PATH含有空格,临时重新设置
export PATH=/home/zhaohang/.nvm/versions/node/v20.19.4/bin:/home/zhaohang/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib

tar xvf buildroot-2025.11.tar.gz

make menucofig

TODO

Yocto

TODO

内核模块

内核模块示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <linux/init.h>
#include <linux/module.h>

static int __init hello_world_init(void){
printk(KERN_INFO "hello world!\n");
return 0;
}

static void __exit hello_world_exit(void){
pr_info("hello world module exit\n");
}
module_init(hello_world_init);
module_exit(hello_world_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("even629");
MODULE_DESCRIPTION("hello world!");

external module

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DRIVER_NAME := hello_world

obj-m += $(DRIVER_NAME).o
KERNEL_SRC:=/home/zhaohang/repository/linux/linux-5.10.y-raspi

PWD ?=$(shell pwd)
ARCH = arm64
CROSS_COMPILE = aarch64-linux-gnu-


all: build

build:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNEL_SRC) M=$(PWD) modules

clean:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNEL_SRC) M=$(PWD) modules clean
rm -rf *.ko *.o *.mod.o *.mod.c *.symvers *.order .tmp*

.PHONY: all deploy qemu
deploy:
cp $(DRIVER_NAME).ko /home/zhaohang/repository/linux/busybox-1.37.0/_install
/bin/bash /home/zhaohang/repository/linux/busybox-1.37.0/deploy.sh

qemu:
qemu-system-aarch64 \
-M raspi4b \
-cpu cortex-a72 \
-m 2G \
-nographic \
-kernel /home/zhaohang/tftp/raspi4b/Image \
-dtb /home/zhaohang/tftp/raspi4b/bcm2711-rpi-4-b.dtb \
-initrd /home/zhaohang/tftp/initramfs.cpio.gz \
-append "console=ttyAMA0 earlycon=pl011,0xfe201000 rdinit=/linuxrc"

其中打包根文件系统的脚本deploy.sh如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

INSTALL_PATH=/home/zhaohang/repository/linux/busybox-1.37.0/_install

cd "$INSTALL_PATH" || exit 1

rm -rf ../initramfs.cpio.gz ~/tftp/initramfs.cpio.gz

find . | cpio -o -H newc | gzip -c > ../initramfs.cpio.gz

cp ../initramfs.cpio.gz ~/tftp

echo "cp initramfs.cpio.gz ~/tftp"

遇到一个问题是 aarch64-linux-gnu-gcc 编译时没 print 目前没找到解决办法,在 stackoverflow 上详细描述了具体问题:

built-in module

drivers/char(以字符驱动为例)创建文件夹helloworld,然后将驱动源代码放入,然后创建Kconfig文件

1
2
3
4
5
config HELLO_WORLD
bool "helloworld support"
default y
help
helloworld

更改drivers

1
2
3
emacs ../Kconfig
# 添加
source "drivers/char/helloworld/Kconfig"

在驱动源码里创建Makefile

1
obj-$(CONFIG_helloworld) += helloworld.o

然后在上一级的Makefile中添加:

1
2
3
emacs ../Makefile
# 添加
obj-y += helloworld/

然后编译内核即可

启动

直接指定内核启动

qemu 运行

qemu版本

1
2
3
$ qemu-system-aarch64 --version
QEMU emulator version 10.1.2
Copyright (c) 2003-2025 Fabrice Bellard and the QEMU Project developers

运行

1
2
3
4
5
6
7
8
9
qemu-system-aarch64 \
-M raspi4b \
-cpu cortex-a72 \
-m 2G \
-nographic \
-kernel /home/zhaohang/tftp/raspi4b/Image \
-dtb /home/zhaohang/tftp/raspi4b/bcm2711-rpi-4-b.dtb \
-initrd /home/zhaohang/tftp/initramfs.cpio.gz \
-append "console=ttyAMA0 earlycon=pl011,0xfe201000 rdinit=/linuxrc"

结果:

command + a, 然后按 x 可以退出qemu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
$ qemu-system-aarch64 \
-M raspi4b \
-cpu cortex-a72 \
-m 2G \
-nographic \
-kernel /home/zhaohang/tftp/raspi4b/Image \
-dtb /home/zhaohang/tftp/raspi4b/bcm2711-rpi-4-b.dtb \
-initrd /home/zhaohang/tftp/initramfs.cpio.gz \
-append "console=ttyAMA0 earlycon=pl011,0xfe201000 rdinit=/linuxrc"

qemu-system-aarch64: warning: bcm2711 dtc: brcm,bcm2711-pcie has been disabled!
qemu-system-aarch64: warning: bcm2711 dtc: brcm,bcm2711-rng200 has been disabled!
qemu-system-aarch64: warning: bcm2711 dtc: brcm,bcm2711-thermal has been disabled!
qemu-system-aarch64: warning: bcm2711 dtc: brcm,bcm2711-genet-v5 has been disabled!
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
[ 0.000000] Linux version 5.10.110-v8+ (zhaohang@cyberboy) (aarch64-linux-gnu-gcc (GCC) 15.1.0, GNU ld (GNU Binutils) 2.44) #1 SMP PREEMPT Wed Dec 31 13:58:35 CST 2025
[ 0.000000] Machine model: Raspberry Pi 4 Model B
[ 0.000000] earlycon: pl11 at MMIO 0x00000000fe201000 (options '')
[ 0.000000] printk: bootconsole [pl11] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] Reserved memory: created CMA memory pool at 0x000000002c000000, size 64 MiB
[ 0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
[ 0.000000] Zone ranges:
[ 0.000000] DMA [mem 0x0000000000000000-0x000000003bffffff]
[ 0.000000] DMA32 empty
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x000000003bffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000003bffffff]
[ 0.000000] percpu: Embedded 32 pages/cpu s91416 r8192 d31464 u131072
[ 0.000000] Detected PIPT I-cache on CPU0
[ 0.000000] CPU features: detected: Spectre-v2
[ 0.000000] CPU features: detected: Spectre-v4
[ 0.000000] CPU features: detected: ARM errata 1165522, 1319367, or 1530923
[ 0.000000] CPU features: detected: Spectre-BHB
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 241920
[ 0.000000] Kernel command line: console=ttyAMA0 earlycon=pl011,0xfe201000 rdinit=/linuxrc
[ 0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 871688K/983040K available (11456K kernel code, 1948K rwdata, 3968K rodata, 3648K init, 1255K bss, 45816K reserved, 65536K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[ 0.000000] ftrace: allocating 35594 entries in 140 pages
[ 0.000000] ftrace: allocated 140 pages with 3 groups
[ 0.000000] rcu: Preemptible hierarchical RCU implementation.
[ 0.000000] rcu: RCU event tracing is enabled.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=4.
[ 0.000000] Trampoline variant of Tasks RCU enabled.
[ 0.000000] Rude variant of Tasks RCU enabled.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] GIC: Using split EOI/Deactivate mode
[ 0.000000] random: get_random_bytes called from start_kernel+0x3c0/0x59c with crng_init=0
[ 0.000000] arch_timer: cp15 timer(s) running at 62.50MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1cd42e208c, max_idle_ns: 881590405314 ns
[ 0.000193] sched_clock: 56 bits at 62MHz, resolution 16ns, wraps every 4398046511096ns
[ 0.010464] Console: colour dummy device 80x25
[ 0.012840] Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=250000)
[ 0.014064] pid_max: default: 32768 minimum: 301
[ 0.016215] LSM: Security Framework initializing
[ 0.020951] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.021396] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.045807] cgroup: Disabling memory control group subsystem
[ 0.083754] rcu: Hierarchical SRCU implementation.
[ 0.090257] EFI services will not be available.
[ 0.096869] smp: Bringing up secondary CPUs ...
[ 0.102608] Detected PIPT I-cache on CPU1
[ 0.103412] CPU1: Booted secondary processor 0x0000000001 [0x410fd083]
[ 0.109872] Detected PIPT I-cache on CPU2
[ 0.110218] CPU2: Booted secondary processor 0x0000000002 [0x410fd083]
[ 0.114286] Detected PIPT I-cache on CPU3
[ 0.114544] CPU3: Booted secondary processor 0x0000000003 [0x410fd083]
[ 0.115437] smp: Brought up 1 node, 4 CPUs
[ 0.117473] SMP: Total of 4 processors activated.
[ 0.117813] CPU features: detected: 32-bit EL0 Support
[ 0.118151] CPU features: detected: CRC32 instructions
[ 0.118532] CPU features: detected: 32-bit EL1 Support
[ 0.578725] CPU: All CPU(s) started at EL2
[ 0.579912] alternatives: patching kernel code
[ 0.598893] devtmpfs: initialized
[ 0.622587] Enabled cp15_barrier support
[ 0.623314] Enabled setend support
[ 0.625268] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.626042] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[ 0.633888] pinctrl core: initialized pinctrl subsystem
[ 0.646644] DMI not present or invalid.
[ 0.649138] NET: Registered protocol family 16
[ 0.666179] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[ 0.668378] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
[ 0.669231] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[ 0.670265] audit: initializing netlink subsys (disabled)
[ 0.672976] audit: type=2000 audit(0.636:1): state=initialized audit_enabled=0 res=1
[ 0.676692] thermal_sys: Registered thermal governor 'step_wise'
[ 0.679732] cpuidle: using governor menu
[ 0.681470] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[ 0.683105] ASID allocator initialised with 65536 entries
[ 0.685145] Serial: AMBA PL011 UART driver
[ 0.732159] bcm2835-mbox fe00b880.mailbox: mailbox enabled
[ 0.745081] raspberrypi-firmware soc:firmware: Attached to firmware from 1970-01-05T00:12:17, variant unknown
[ 0.748848] raspberrypi-firmware soc:firmware: Firmware hash is ffffffc01076a644ffffffc00208f410ffffff80
[ 0.822131] bcm2835-dma fe007000.dma: DMA legacy API manager, dmachans=0x1
[ 0.837203] vgaarb: loaded
[ 0.839372] SCSI subsystem initialized
[ 0.840912] usbcore: registered new interface driver usbfs
[ 0.841539] usbcore: registered new interface driver hub
[ 0.843435] usbcore: registered new device driver usb
[ 0.845401] usb_phy_generic phy: supply vcc not found, using dummy regulator
[ 0.861298] clocksource: Switched to clocksource arch_sys_counter
[ 1.389615] VFS: Disk quotas dquot_6.6.0
[ 1.390036] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 1.391320] FS-Cache: Loaded
[ 1.392956] CacheFiles: Loaded
[ 1.430221] NET: Registered protocol family 2
[ 1.432440] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[ 1.441074] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[ 1.442094] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[ 1.442942] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
[ 1.443407] TCP: Hash tables configured (established 8192 bind 8192)
[ 1.446113] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
[ 1.446615] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
[ 1.448824] NET: Registered protocol family 1
[ 1.454548] RPC: Registered named UNIX socket transport module.
[ 1.454926] RPC: Registered udp transport module.
[ 1.455348] RPC: Registered tcp transport module.
[ 1.455688] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 1.456251] PCI: CLS 0 bytes, default 64
[ 1.462406] Trying to unpack rootfs image as initramfs...
[ 1.613750] Freeing initrd memory: 2620K
[ 1.622022] hw perfevents: enabled with armv8_cortex_a72 PMU driver, 7 counters available
[ 1.623833] kvm [1]: IPA Size Limit: 44 bits
[ 1.630628] kvm [1]: vgic interrupt IRQ9
[ 1.633763] kvm [1]: Hyp mode initialized successfully
[ 1.640641] Initialise system trusted keyrings
[ 1.643688] workingset: timestamp_bits=46 max_order=18 bucket_order=0
[ 1.654869] zbud: loaded
[ 1.662206] FS-Cache: Netfs 'nfs' registered for caching
[ 1.665400] NFS: Registering the id_resolver key type
[ 1.666028] Key type id_resolver registered
[ 1.666374] Key type id_legacy registered
[ 1.667309] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 1.667733] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[ 1.672284] Key type asymmetric registered
[ 1.672591] Asymmetric key parser 'x509' registered
[ 1.673460] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
[ 1.675599] io scheduler mq-deadline registered
[ 1.675906] io scheduler kyber registered
[ 1.686720] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 0 config (0 80)
[ 1.687615] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 1 config (0 81)
[ 1.688402] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 2 config (0 82)
[ 1.689028] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 3 config (0 83)
[ 1.690019] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 4 config (0 84)
[ 1.691028] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 5 config (0 85)
[ 1.691837] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 6 config (0 86)
[ 1.692510] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 7 config (0 87)
[ 1.695839] bcm2708_fb soc:fb: FB found 1 display(s)
[ 1.718250] Console: switching to colour frame buffer device 100x30
[ 1.722108] bcm2708_fb soc:fb: Registered framebuffer for display 0, size 800x480
[ 1.734253] bcm2835-aux-uart fe215040.serial: there is not valid maps for state default
[ 1.739449] vc-mem: phys_addr:0x00000000 mem_base=0x00000000 mem_size:0x00000000(0 MiB)
[ 1.744011] gpiomem-bcm2835 fe200000.gpiomem: Initialised: Registers at 0xfe200000
[ 1.795533] brd: module loaded
[ 1.827118] loop: module loaded
[ 1.830068] bcm2835-power bcm2835-power: ASB register ID returned 0x00000000
[ 1.834080] Loading iSCSI transport class v2.0-870.
[ 1.847058] usbcore: registered new interface driver r8152
[ 1.847425] usbcore: registered new interface driver lan78xx
[ 1.848003] usbcore: registered new interface driver smsc95xx
[ 1.849618] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)
[ 1.853436] usbcore: registered new interface driver uas
[ 1.854435] usbcore: registered new interface driver usb-storage
[ 1.855744] mousedev: PS/2 mouse device common for all mice
[ 1.863346] bcm2835-wdt bcm2835-wdt: Broadcom BCM2835 watchdog timer
[ 1.875392] sdhci: Secure Digital Host Controller Interface driver
[ 1.875688] sdhci: Copyright(c) Pierre Ossman
[ 1.880324] mmc-bcm2835 fe300000.mmcnr: could not get clk, deferring probe
[ 1.883910] sdhci-pltfm: SDHCI platform and OF driver helper
[ 1.891370] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 2 config (0 82)
[ 1.892339] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 2 state (0 82)
[ 1.895277] leds-gpio: probe of leds failed with error -5
[ 1.898076] ledtrig-cpu: registered to indicate activity on CPUs
[ 1.899717] hid: raw HID events driver (C) Jiri Kosina
[ 1.900620] usbcore: registered new interface driver usbhid
[ 1.900923] usbhid: USB HID core driver
[ 1.902099] ashmem: initialized
[ 1.914219] Initializing XFRM netlink socket
[ 1.914676] NET: Registered protocol family 17
[ 1.916084] Key type dns_resolver registered
[ 1.918003] registered taskstats version 1
[ 1.918337] Loading compiled-in X.509 certificates
[ 1.921669] Key type ._fscrypt registered
[ 1.921956] Key type .fscrypt registered
[ 1.922228] Key type fscrypt-provisioning registered
[ 1.946131] uart-pl011 fe201000.serial: there is not valid maps for state default
[ 1.947582] uart-pl011 fe201000.serial: cts_event_workaround enabled
[ 1.948980] fe201000.serial: ttyAMA0 at MMIO 0xfe201000 (irq = 21, base_baud = 0) is a PL011 rev2
[ 1.951840] printk: console [ttyAMA0] enabled
[ 1.951840] printk: console [ttyAMA0] enabled
[ 1.952714] printk: bootconsole [pl11] disabled
[ 1.952714] printk: bootconsole [pl11] disabled
[ 1.956755] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 6 config (0 86)
[ 1.958798] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 6 config (0 86)
[ 1.959403] reg-fixed-voltage: probe of sd_vcc_reg failed with error -5
[ 1.962175] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 5 config (0 85)
[ 1.963390] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 5 config (0 85)
[ 1.963832] reg-fixed-voltage: probe of cam1_regulator failed with error -5
[ 1.965762] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 4 config (0 84)
[ 1.967667] raspberrypi-exp-gpio soc:firmware:gpio: Failed to get GPIO 4 config (0 84)
[ 1.968063] gpio-regulator: probe of sd_io_1v8_reg failed with error -5
[ 1.971127] bcm2835-aux-uart fe215040.serial: there is not valid maps for state default
[ 1.972594] bcm2835-aux-uart fe215040.serial: error -ENOSPC: unable to register 8250 port
[ 1.973450] bcm2835-aux-uart: probe of fe215040.serial failed with error -28
[ 1.976078] mmc-bcm2835 fe300000.mmcnr: mmc_debug:0 mmc_debug2:0
[ 1.976376] mmc-bcm2835 fe300000.mmcnr: DMA channel allocated
[ 2.011143] of_cfs_init
[ 2.014686] of_cfs_init: OK
[ 2.022747] uart-pl011 fe201000.serial: no DMA platform data
[ 2.068740] Freeing unused kernel memory: 3648K
[ 2.072213] Run /linuxrc as init process

Please press Enter to activate this console.
~ # insmod my_driver.ko
[ 19.030715] my_driver: loading out-of-tree module taints kernel.
[ 19.040713] alloc_chrdev_region ok
[ 19.041036] major allocated: 241
[ 19.041063] minor allocated: 0
[ 19.041707] cdev_add ok
[ 19.043310] my_driver: Module loaded
~ # rmmod my_driver.ko
[ 24.994821] unregister_chrdev_region ok
[ 24.995218] my_driver: Module unloaded
~ #

u-boot启动

这种方法暂时启动不起来,不知道为什么

编译u-boot

1
2
3
4
5
6
7
git clone https://github.com/u-boot/u-boot.git
make clean
make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- rpi_4_defconfig

make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
cp u-boot.bin ~/tftp/raspi4b/u-boot.bin
cp u-boot ~/tftp/raspi4b/u-boot

最终编译生成ELF格式的可执行文件 u-boot 和纯二进制文件u-boot.bin,其中 QEMU 可以启动的为ELF格式的可执行文件 u-boot。

制作SD卡镜像

制作sd卡镜像,并将它格式化成fat格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
dd if=/dev/zero of=/home/zhaohang/tftp/raspi4b/sd.img bs=1M count=256

sudo pacman -S dosfstools
sudo fdisk /home/zhaohang/tftp/raspi4b/sd.img
# n 新建分区
# p 主分区
# 1 分区号 1
#(enter) 默认起始(通常是2048)
# +128M 大小 128MB
# t # 修改分区类型
# 1 # 选择分区 1
# b # 设置为 W95 FAT32

# n 新建第二个分区
# p 主分区
# 2 分区号 2
# (enter) 默认起始
# (enter) 默认终止
# t # 修改分区类型
# 2 # 选择分区 1
# 83 # 设置为 Linux
# p
Command (m for help): p
Disk /home/zhaohang/tftp/raspi4b/sd.img: 256 MiB, 268435456 bytes, 524288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x8cf943ea

Device Boot Start End Sectors Size Id Type
/home/zhaohang/tftp/raspi4b/sd.img1 2048 264191 262144 128M b W95 FAT32
/home/zhaohang/tftp/raspi4b/sd.img2 264192 524287 260096 127M 83 Linux
# w 写入并退出

把编译好的kernel Image和DTB文件拷贝到sd.img中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ sudo losetup -Pf --show /home/zhaohang/tftp/raspi4b/sd.img
/dev/loop0
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 256M 0 loop
├─loop0p1 259:0 0 128M 0 part
└─loop0p2 259:1 0 127M 0 part
sda 8:0 0 388.6M 1 disk
sdb 8:16 0 186M 1 disk
sdc 8:32 0 1G 0 disk [SWAP]
sdd 8:48 0 1T 0 disk /mnt/wslg/distro

# 格式化第一个分区为 FAT32(boot 分区)
$ sudo mkfs.vfat /dev/loop0p1
# 格式化第二个分区为 ext4(rootfs 分区)
$ sudo mkfs.ext4 /dev/loop0p2

# 挂载 boot 分区(FAT32)
$ sudo mount /dev/loop0p1 /mnt/
# 拷贝内核和设备树,uboot
$ sudo cp ~/tftp/raspi4b/Image /mnt/
$ sudo cp ~/tftp/raspi4b/bcm2711-rpi-4-b.dtb /mnt/
$ sudo cp ~/tftp/raspi4b/u-boot.bin /mnt/
$ sudo umount /dev/loop0p1

# 挂载 rootfs 分区(ext4)
$ sudo mount /dev/loop0p2 /mnt
# 拷贝rootfs
$ sudo cp ~/tftp/initramfs.cpio.gz /mnt
$ cd /mnt
# 解压 initramfs.cpio.gz 到当前目录(即 rootfs 根)
$ sudo gunzip -c ~/tftp/initramfs.cpio.gz | sudo cpio -idmv
$ sudo rm initramfs.cpio.gz
$ cd ~
$ sudo umount /dev/loop0p2

$ sudo losetup -d /dev/loop0

qemu运行

QEMU可以模拟sd卡等外设。我们就把编译好的固件放在一个模拟的sd卡上,让QEMU从这张模拟的sd卡上启动Linux系统。

1
2
3
4
5
6
7
qemu-system-aarch64 \
-M raspi4b \
-cpu cortex-a72 \
-m 2G \
-nographic \
-kernel /home/zhaohang/tftp/raspi4b/u-boot
-sd /home/zhaohang/tftp/raspi4b/sd.img

参考