交叉编译linux内核并使用qemu运行

在x86_64架构的电脑上采用交叉编译的方式对程序进行编译,并部署到arm板子上运行是我们经常会遇到的,对于依赖关系不怎么复杂的程序,直接使用gcc-arm交叉编译工具,在x86_64电脑上(安装交叉编译工具链)即可编译,编译时指定gcc的版本和相关库的路径。但是对于复杂的程序,特别是依赖大量外部库的程序,使用这种方式就不太可行了。这里还是考虑弄一个较小的arm虚拟机来跑,然后在虚拟机里面把待编译代码放进去进行编译。相对于vbox和VMware这类虚拟机,qemu显然更轻量,更简单。本文参考我们工程实践和博文,给出了具体的操作步骤。整个流程如下所示:

其中,使用busybox生成rootfs的过程可以用更简单的rootbuild工具来实现。具体参考https://www.toutiao.com/article/7210659183681880610(这篇讲的是RISC-V Linux在qemu上的编译运行

如果是arm64的板子,本文的arm相关设置要改成arm64。

内核源码版本确定与编译

首先要确认目标板(也就是arm的开发板)上面运行的linux内核版本,因为不同内核版本里面的函数等可能存在差异,为了保证交叉编译的代码能够在目标板上可靠运行,需要在qemu上部署相同版本的内核版本,而这个版本显然就是编译出来的啦,而编译内核需要对应的源码,这就要求编译机上下载和目标板上相同的内核源码。

要确认目标板上的内核版本,可以使用uname -a查看。下图为在编译机上查看的结果(只为演示该命令及其结果)。

这里假设目标板上运行的是5.4.0-136的内核版本。也是我们要在qemu上运行的内核版本。

  1. linux源码下载

在编译机上下载5.4版本的linux,其链接:https://codeload.github.com/torvalds/linux/tar.gz/refs/tags/v5.4

并将源码放置如下位置:

/home/damon/00_code/02_gitee/linux_5.4/linux-5.4

2. 编译内核源码

2.1 选择编译工具

ubuntu本身自带gcc编译器,不过是针对X86平台的,我们现在要编译ARM架构的代码,也就是在X8平台上编译ARM架构的工具,叫做ARM GCC交叉编译器。

下载地址参考:https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz?revision=fed31ee5-2ed7-40c8-9e0e-474299a3c4ac&rev=fed31ee52ed740c89e0e474299a3c4ac&hash=2CF11736E3C6A019541AC00F83165C56

(上述为arm架构,而不是arm64架构,所有的交叉编译gcc版本可以从https://developer.arm.com/downloads/-/gnu-a查看,注意,7.5版本之前不是arm维护的)

我将其解压放置在以下目录:

/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf

2.2 编译配置

基于ARM架构的配置,我们选择./arch/arm/configs/vexpress_defconfig配置。

直接上编译脚本:

注意事项:如果你的环境是第一次配置,第一次编译的时候大概率会出错,按照错误提示按照依赖工具即可继续编译。

# 根据个人存放的Linux源码目录,修改成自己的目录路径
cd /home/damon/00_code/02_gitee/linux_5.4/linux-5.4

# 清理工程
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- distclean

# 配置文件选择:
./arch/arm/configs/vexpress_defconfigmake ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- vexpress_defconfig

# 打开图形配置界面,我们选择默认配置
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- menuconfig

2.3 编译内核

编译内核时,执行如下命令:

# -j8,可以根据实际核数修改,可以提速编译
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- -j8

编译成功后,我们可以得到内核镜像文件zImage和设备树文件dtb。内核镜像文件就是我们将来要启动的qemu虚拟机的核心文件,我们的交叉编译就是要在这个内核镜像文件上跑,设备树文件就是内核启动后加载它并生成设备节点的文件。

zImage的路径如下:

/home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot

同时,对应vexpress_defconfig配置下生成的设备树文件:vexpress-v2p-ca9.dtb,在dts目录下

内核编译好了,如何将它启动呢?

安装QEMU

一般地,学习嵌入式linux,手头上要有一块开发板,一个支持linux开发的开发板少则几百块,贵则上千块。如果你只是想玩一玩,看一看,完全没必要花这些钱,那么没有开发板该如何启动Linux内核呢?

我们可以采用qemu搭建运行环境

qemu是“Quick Emulation”的缩写,是一个用C语言编写的开源虚拟化软件。它可以模拟硬件,在指定的硬件平台上搭建运行开发环境。我们暂时无需知道其工作原理,直接拿来安装使用。

  1. 源码安装

QEMU官网:https://www.qemu.org/

下载安装:

wget https://download.qemu.org/qemu-7.1.0.tar.xz
tar xvJf qemu-7.1.0.tar.xz
cd qemu-7.1.0
./configure
make

2. 二进制安装

安装qemu工具

sudo apt-get install qemu

测试qemu是否安装成功:

Qemu起kernel

现在我们有了kernel镜像文件和设备树文件,我们按照qemu的指令启动:

qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/zImage -dtb /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"

启动日志:

省略......
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.4.0+ #1
Hardware name: ARM-Versatile Express
[<80110e90>] (unwind_backtrace) from [<8010c4a4>] (show_stack+0x10/0x14)
[<8010c4a4>] (show_stack) from [<80764c24>] (dump_stack+0x90/0xa4)
[<80764c24>] (dump_stack) from [<8012147c>] (panic+0x110/0x310)
[<8012147c>] (panic) from [<80a01584>] (mount_block_root+0x204/0x2b4)
[<80a01584>] (mount_block_root) from [<80a01758>] (mount_root+0x124/0x148)
[<80a01758>] (mount_root) from [<80a018d0>] (prepare_namespace+0x154/0x198)
[<80a018d0>] (prepare_namespace) from [<8077bd44>] (kernel_init+0x8/0x110)
[<8077bd44>] (kernel_init) from [<801010e8>] (ret_from_fork+0x14/0x2c)
Exception stack(0x9e493fb0 to 0x9e493ff8)
3fa0:                                     00000000 00000000 00000000 00000000
3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---

看最后一行:启动到一半出错了,Kernel Painc!!!

看到Panic,"慌不慌" ?不过kernel会将Panic的原因也打印出来:Unable to mount root fs.

不能挂在到rootfs上,什么是rootfs呢?没有它,我们该如何做一个呢?

制作rootfs

root fs的中文名叫根文件系统。文件我们好理解,比如我们常见的office文件、图片、视频、压缩包等等都叫文件。文件系统可以理解为能解析识别这些文件的文件,或者说是管理各种文件的系统。

那什么是根呢?就是Linux内核启动所挂载的第一个文件系统,所以这个根字也体现了它的重要性!

一句话总结:rootfs是Linux内核启动挂载的第一个文件系统,系统引导启动程序会在根文件系统挂载之后,从中把一些基本的初始化脚本和服务等加载到内存中去运行。现在就是缺少这个根文件系统,导致内核没法挂载根文件系统,之后的操作也没法进行。

1. 如何制作一个rootfs

1.1 使用busybox制作rootfs

制作rootfs我们要借用一个工具:BusyBox,忙碌盒子,这个盒子会提供大量Linux命令和工具的软件。

BusyBox的官网地址为:https://busybox.net/,最新的版本已经达到1.36.0。

我们不追求最新,因为最新的往往会存在一些兼容性或未知BUG,使用我之前用过的1.32.0版本,下载链接:https://busybox.net/downloads/busybox-1.32.0.tar.bz2

解压、配置、编译BusyBox和编译Linux的流程差不多,此处就直接贴脚本了:

cd/home/damon/00_code/02_gitee/busy_box
tar -vxjf busybox-1.32.0.tar.bz2 /home/damon/00_code/02_gitee/busy_box/busybox-1.32.0
# 手动修改CROSS_COMPILE和ARCH
export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabihf-
make defconfig
make menuconfig

配置完后编译

make
# 编译好的东西,我把它安装到 /home/damon/00_code/02_gitee/busy_box/rootfs目录下
make install CONFIG_PREFIX=/home/damon/00_code/02_gitee/busy_box/rootfs

安装完毕,文件目录显示如下:

可以看到rootfs中有3个文件夹和一个链接文件,具体作用先不展开,此时busybox的工作就完成了,但是此时的rootfs还不能使用,还缺少一些东西,接下来继续补充。

cd /home/damon/00_code/02_gitee/busy_box/rootfs

# 创建lib目录,并添加库文件(这些库文件都是从GCC中获取的)
mkdir lib
cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/lib
cp *so* /home/damon/00_code/02_gitee/busy_box/rootfs/lib/ -d

cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/lib
cp *so* *.a /home/damon/00_code/02_gitee/busy_box/rootfs/lib/ -d

# 向usr/lib目录添加库文件
cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/lib
cp *so* *.a /home/damon/00_code/02_gitee/busy_box/rootfs/usr/lib/ -d

# 创建其他文件目录
cd /home/damon/00_code/02_gitee/busy_box/rootfs
mkdir dev proc mnt sys tmp etc  root

此时一个可以使用的rootfs便制作完成了,rootfs目录如下图所示:

1.2 使用buildroot巩固制作rootfs

这里是使用Risc V的交叉编译,我没有尝试arm架构的,但是原理是一样的。

文件系统可以用busybox、buildroot等工具制作,busybox需要自己一步一步的做出来,过程比较麻烦。更便捷的做法是使用buildroot,它可以自动帮我们完成。

下载地址:https://buildroot.org/download.html

下载后解压:

tar -xvf buildroot-2022.02.6.tar.gz

进入buildroot菜单配置界面:

cd buildroot-2022.02.6
make menuconfig

选择RISC-V架构

Target options--->
   Target Architecture (i386)  --->
      (X) RISCV

选择ext文件系统类型:

Filesystem images  --->
  [*] ext2/3/4 root filesystem 

保存后编译:

make -j8

编译需要花一些时间,buildroot前期大部分时间去编译工具链了。 编译完后,生成文件在output/images目录下:

rootfs.ext2是我们需要用到的。

2. 如何使用rootfs

rootfs一般放到SD卡或者磁盘中,让内核去读取启动。我手头上没有SD卡,在PC上划出一块磁盘又比较浪费。我们就制作一个SD卡镜像,它是为qemu创建的虚拟SD卡。执行脚本如下:

cd /home/damon/00_code/02_gitee
# 制作rootfs.ext4.img文件
dd if=/dev/zero of=rootfs.ext4.img bs=1M count=500
# 图片截取的是32M,后面实际应用时,发现32M不够用,就修改成了500M
# 格式化
mkfs.ext4 rootfs.ext4.img

以上等同于使用buildroot得到的镜像文件,相当于是一个空的ext4文件系统,buildroot得到的是空的ext2文件系统。下面就是往这个文件系统里面存放rootfs里面的东西,让它变成一个可以独立使用的磁盘分区或者设备文件。

# 将rootfs.ext4.img挂载到/mnt/rootfs
mkdir -p /mnt/rootfs
mount -t ext4 -o loop rootfs.ext4.img /mnt/rootfs
# 将rootfs内所有文件拷贝至rootfs.ext4.img
cp -a /home/damon/00_code/02_gitee/busy_box/rootfs/* /mnt/rootfs/
# 卸载
umount /mnt/rootfs
# 此时得到一个装有rootfs的镜像
/home/damon/00_code/02_gitee/rootfs.ext4.img

现在rootfs做好了,我们去修复上面的Panic.

重新启动kernel

我们在原有的qemu命令基础上指定rootfs的镜像文件,重新启动:

qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/zImage -dtb /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -sd /home/damon/00_code/02_gitee/rootfs.ext4.img -append "root=/dev/mmcblk0 rw console=ttyAMA0"

启动日志如下:

之前的kernel panic没有了,但是又有新的告警了,一般错误是必须要修复的,而告警内容是可以忽略的,除非影响到了使用和性能。

当前告警在循环打印无法打开,/dev/tty2 /dev/tty3 /dev/tty4, 看到这个我们显然知道是缺少串口设备,按照如下脚本添加,并更新镜像文件。

sudo mknod dev/tty2 c 5 1
sudo mknod dev/tty3 c 5 1
sudo mknod dev/tty4 c 5 1

此时Linux操作系统起来了,完整的详细的启动日志如下:

damon@ubuntu:~/00_code/02_gitee$ qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/zImage -dtb /home/damon/00_code/02_gitee/linux_5.4/linux-5.4/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -sd /home/damon/00_code/02_gitee/rootfs.ext4.img -append "root=/dev/mmcblk0 rw console=ttyAMA0"

WARNING: Image format was not specified for '/home/damon/00_code/02_gitee/rootfs.ext4.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
pulseaudio: set_sink_input_volume() failed
pulseaudio: Reason: Invalid argument
pulseaudio: set_sink_input_mute() failed
pulseaudio: Reason: Invalid argument
Booting Linux on physical CPU 0x0
Linux version 5.4.0+ (damon@ubuntu) (gcc version 9.2.1 20191025 (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10))) #1 SMP Sat Jan 14 15:12:10 CST 2023
CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
OF: fdt: Machine model: V2P-CA9
Memory policy: Data cache writeback
Reserved memory: created DMA memory pool at 0x4c000000, size 8 MiB
OF: reserved mem: initialized node vram@4c000000, compatible id shared-dma-pool
cma: Reserved 16 MiB at 0x7f000000
CPU: All CPU(s) started in SVC mode.
percpu: Embedded 19 pages/cpu s45516 r8192 d24116 u77824
Built 1 zonelists, mobility grouping on.  Total pages: 130048
Kernel command line: root=/dev/mmcblk0 rw console=ttyAMA0
printk: log_buf_len individual max cpu contribution: 4096 bytes
printk: log_buf_len total cpu_extra contributions: 12288 bytes
printk: log_buf_len min size: 16384 bytes
printk: log_buf_len: 32768 bytes
printk: early log buf free: 14808(90%)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 492108K/524288K available (7168K kernel code, 425K rwdata, 1728K rodata, 1024K init, 155K bss, 15796K reserved, 16384K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu:     RCU event tracing is enabled.
rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
GIC CPU mask not found - kernel will fail to boot.
GIC CPU mask not found - kernel will fail to boot.
L2C: platform modifies aux control register: 0x02020000 -> 0x02420000
L2C: DT/platform modifies aux control register: 0x02020000 -> 0x02420000
L2C-310 enabling early BRESP for Cortex-A9
L2C-310 full line of zeros enabled for Cortex-A9
L2C-310 dynamic clock gating disabled, standby mode disabled
L2C-310 cache controller enabled, 8 ways, 128 kB
L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46420001
random: get_random_bytes called from start_kernel+0x310/0x4bc with crng_init=0
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
clocksource: arm,sp804: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275 ns
Failed to initialize '/smb@4000000/motherboard/iofpga@7,00000000/timer@12000': -22smp_twd: clock not found -2
Console: colour dummy device 80x30
Calibrating local timer... 97.07MHz.
Calibrating delay loop... 1179.64 BogoMIPS (lpj=5898240)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mount point-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
CPU: Testing write buffer coherency: ok
CPU0: Spectre v2: using BPIALL workaround
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
Setting up static identity map for 0x60100000 - 0x60100060
rcu: Hierarchical SRCU implementation.
smp: Bringing up secondary CPUs ...
smp: Brought up 1 node, 1 CPU
SMP: Total of 1 processors activated (1179.64 BogoMIPS).
CPU: All CPU(s) started in SVC mode.devtmpfs: initialized
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 0
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
hw-breakpoint: debug architecture 0x4 unsupported.
Serial: AMBA PL011 UART driver10009000.
uart: ttyAMA0 at MMIO 0x10009000 (irq = 29, base_baud = 0) is a PL011 rev1printk: console [ttyAMA0] enabled1000a000.
uart: ttyAMA1 at MMIO 0x1000a000 (irq = 30, base_baud = 0) is a PL011 rev11000b000.
uart: ttyAMA2 at MMIO 0x1000b000 (irq = 31, base_baud = 0) is a PL011 rev11000c000.
uart: ttyAMA3 at MMIO 0x1000c000 (irq = 32, base_baud = 0) is a PL011 rev1
OF: amba_device_add() failed (-19) for /smb@4000000/motherboard/iofpga@7,00000000/wdt@f000
OF: amba_device_add() failed (-19) for /memory-controller@100e0000
OF: amba_device_add() failed (-19) for /memory-controller@100e1000
OF: amba_device_add() failed (-19) for /watchdog@100e5000
irq: type mismatch, failed to map hwirq-75 for interrupt-controller@1e001000!
SCSI subsystem initializedusbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Advanced Linux Sound Architecture Driver Initialized.
clocksource: Switched to clocksource arm,sp804
NET: Registered protocol family 2tcp_listen_port
addr_hash hash table entries: 512 (order: 0, 6144 bytes, linear)
TCP established hash table entries: 4096 (order: 2, 16384 bytes, linear)
TCP bind hash table entries: 4096 (order: 3, 32768 bytes, linear)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
hw perfevents: enabled with armv7_cortex_a9 PMU driver, 1 counters available
workingset: timestamp_bits=30 max_order=17 bucket_order=0
squashfs: version 4.0 (2009/01/31) Phillip Lougher
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
9p: Installing v9fs 9p2000 file system supportio scheduler mq-deadline registeredio scheduler kyber registereddrm-clcd-pl111 1001f000.
clcd: assigned reserved memory node vram@4c000000drm-clcd-pl111 1001f000.
clcd: using device-specific reserved memorydrm-clcd-pl111 1001f000.
clcd: initializing Versatile Express PL111drm-clcd-pl111 1001f000.
clcd: core tile graphics presentdrm-clcd-pl111 1001f000.
clcd: this device will be deactivatedError: Driver 'vexpress-muxfpga' is already registered, aborting...drm-clcd-pl111 10020000.
clcd: initializing Versatile Express PL111drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCDphysmap-flash 40000000.
flash: physmap platform flash device: [mem 0x40000000-0x43ffffff]40000000.
flash: Found 2 x16 devices at 0x0 in 32-bit bank. 
Manufacturer ID 0x000000 Chip ID 0x000000Intel/Sharp Extended Query Table at 0x0031Using buffer write methodphysmap-flash 40000000.
flash: physmap platform flash device: [mem 0x44000000-0x47ffffff]40000000.
flash: Found 2 x16 devices at 0x0 in 32-bit bank.
 Manufacturer ID 0x000000 Chip ID 0x000000Intel/Sharp Extended Query Table at 0x0031
Using buffer write methodConcatenating MTD devices:(0): "40000000.flash"
(1): "40000000.flash"into device "40000000.flash"
physmap-flash 48000000.
psram: physmap platform flash device: [mem 0x48000000-0x49ffffff]
ibphy: Fixed MD
IO Bus: probedlibphy: smsc911x-mdio: probe
dsmsc911x 4e000000.
ethernet eth0: MAC Address: 52:54:00:12:34:56isp1760 4f000000.
...
profile: using arm/armv7-ca9
NET: Registered protocol family 17
9pnet: Installing 9P2000 support
Registering SWP/SWPB emulation handler
Error: Driver 'vexpress-muxfpga' is already registered, aborting...
drm-clcd-pl111 10020000.
clcd: initializing Versatile Express PL111
drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCD
Error: Driver 'vexpress-muxfpga' is already registered, aborting...
drm-clcd-pl111 10020000.
clcd: initializing Versatile Express PL111
drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCD
input: AT Raw Set 2 keyboard as /devices/platform/smb@4000000/smb@4000000:motherboard/smb@4000000:motherboard:iofpga@7,00000000/10006000.kmi/serio0/input/input0
mmc0: new SD card at address 4567
Error: Driver 'vexpress-muxfpga' is already registered, aborting...
drm-clcd-pl111 10020000.
clcd: initializing Versatile Express PL111drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCDmmcblk0: mmc0:4567 QEMU! 500 MiB
Error: Driver 'vexpress-muxfpga' is already registered, aborting...
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCDrtc-pl031 10017000.
rtc: setting system clock to 2023-01-14T15:23:16 UTC (1673709796)
ALSA device list:
  #0: ARM AC'97 Interface PL041 rev0 at 0x10004000, irq 24
input: ImExPS/2 Generic Explorer Mouse as /devices/platform/smb@4000000/smb@4000000:motherboard/smb@4000000:motherboard:iofpga@7,00000000/10007000.kmi/serio1/input/input2
Error: Driver 'vexpress-muxfpga' is already registered, aborting...
drm-clcd-pl111 10020000.
clcd: initializing Versatile Express PL111drm-clcd-pl111 10020000.
clcd: DVI muxed to daughterboard 1 (core tile) CLCD
random: fast init done
EXT4-fs (mmcblk0): recovery complete
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
ext4 filesystem being mounted at /root supports timestamps until 2038 (0x7fffffff)
VFS: Mounted root (ext4 filesystem) on device 179:0.
Freeing unused kernel memory: 1024KRun /sbin/init as init process
random: crng init done
can't run '/etc/init.d/rcS': No such file or directory
Please press Enter to activate this console.
Please press Enter to activate this console.
Please press Enter to activate this console.
Please press Enter to activate this console./ #

我们完成了Linux源码的编译和启动!之后,可以将待编译的程序放到qemu虚拟机中进行编译(其实就是放到rootfs的某个目录下面),当不使用qemu时,退出即可,然后卸载rootfs对应的磁盘分区或者sd卡等。

参考链接

先让Linux代码跑起来 (qq.com)

https://www.toutiao.com/article/7210659183681880610

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值