# gnu-gcc交叉编译链
sudo apt-get install gcc-arm-linux-gnueabi
# qume
sudo apt-get install qemu-system-arm
# Linux 2.6.30.4
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz
# busybox-1.28.4
wget https://busybox.net/downloads/busybox-1.28.4.tar.bz2
# 其他环境
apt-get -y install g++-arm-linux-gnueabihf libexpat1-dev libncurses5-dev
注意Linux
和gcc
版本匹配支持!
root@huawei linux-2.6.30.4 # find . -name "compiler-gcc*" [130]
./include/linux/compiler-gcc4.h
./include/linux/compiler-gcc.h
./include/linux/compiler-gcc3.h
Linux huawei 5.4.0-100-generic #113-Ubuntu SMP Thu Feb 3 18:43:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
设备平台:
Ubuntu
5.4.0-100-generic
x86_64
新建目录qume-linux
mkdir qume-linux
cd ./qume-linux
tar -xzvf linux-2.6.30.4.tar.gz
tar -jxvf busybox-1.28.4.tar.bz2
cd busybox-1.28.4
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
# 此处要安装图形库
make menuconfig # 选择Setting->Build Options [*]Build static binary(no shared libs)
make install
完成后会在目录中生成_install
目录,本目录存放了编译好的文件系统需要的命令集合
此处有两种方法可以生成最小根文件系统,一种是使用虚拟内存文件系统,一种是直接新建物理节点(可见参考链接部分),下面 主要介绍使用虚拟内存文件系统
第一个方法
mkdir boot_demo
cd ./boot_demo
# 把busybox中的busybox文件复制到一个新的目录
cp -r /root/test_linux/busybox-1.35.0/_install/bin/busybox ./busybox
mkdir initramfs
cd ./initramfs/
mkdir bin
mv ../busybox .
mv ./busybox ./bin/
vim init
chmod +x init
其中init
文件
#!/bin/busybox sh
/bin/busybox echo "Hello Linux"
/bin/busybox sh
最后写成makefile
生成即可
initramfs:
cd ./initramfs_dir && find . -print0 | cpio -ov --null --format=newc | gzip -9 > ../initramfs.img
run:
qemu-system-arm \
-M vexpress-a9 \
-dtb vexpress-v2p-ca9.dtb \
-kernel zImage \
-initrd initramfs.img \
-m 1G \
-nographic \
-append "earlyprintk=serial,ttyS0 console=ttyS0"
第二个方法
我们使用ramfs的方式来为内核提供根文件系统,内核默认的配置没有支持ramfs设备,我们需要添加对应的支持(CONFIG_BLK_DEV_RAM=y)
make ARCH=arm menuconfig
Device Drivers
Block devices
BLK_DEV_RAM
内核支持了ramfs设备之后,我们通过给qemu传递参数指定本机的相关文件作为ramfs的文件系统传递到内核,修改qemu启动命令
qemu-system-aarch64 -machine virt \
-cpu cortex-a53 \
-nographic \
-smp 1 \
-m 2048 \
-kernel linux-4.19.171/arch/arm64/boot/Image \
-append "root=/dev/ram0 rootfstype=ramfs rw init=/init" \
-initrd initramfs.cpio.gz
打包脚本mkinitramfs.sh
内容:
#!/bin/sh
# Copyright 2006 Rob Landley and TimeSys Corporation.
# Licensed under GPL version 2
if [ $# -ne 2 ]
then
echo "usage: mkinitramfs directory imagename.cpio.gz"
exit 1
fi
if [ -d "$1" ]
then
echo "creating $2 from $1"
(cd "$1"; find . | cpio -o -H newc | gzip) > "$2"
else
echo "First argument must be a directory"
exit 1
fi
./mkinitramfs.sh rootfs/ initramfs.cpio.gz
第三个方法
创建rootfs根目录
mkdir -p rootfs/{dev,etc/init.d,lib}
把busybox-1.20.2中的文件复制到rootfs根目录下,主要是一些基本的命令
cp busybox-1.20.2/_install/* -r rootfs/
把交叉编译工具链中的库文件复制到rootfs根目录的lib文件夹下
sudo cp -P /usr/arm-linux-gnueabi/lib/* rootfs/lib/
制作根文件系统镜像 根文件系统镜像就相当于一个硬盘,就是把上面rootfs根目录中的所有文件复制到这个硬盘中。
# 生成512M大小的磁盘镜像
qemu-img create -f raw disk.img 512M
# 把磁盘镜像格式化成ext4文件系统
mkfs -t ext4 ./disk.img
# 将rootfs根目录中的所有文件复制到磁盘镜像中 操作步骤是:创建挂载点-挂载-复制文件-卸载。
mkdir tmpfs
sudo mount -o loop ./disk.img tmpfs/
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs
# 检查
file disk.img
此时启动命令为
# append表示传递给内核的参数 一般有根文件系统设备 文件系统类型 第一个进程名称
qemu-system-arm -M vexpress-a9 -m 512M -kernel ./linux-4.14.212/arch/arm/boot/zImage -dtb ./linux-4.14.212/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd disk.img
如果选择的是虚拟内存文件系统,请在配置内核的时候打开支持
Gneral setup
->initramfs/initrd
和Device Drivers
->Block devices
->Ram block device support
# ARCH:编译arch/目录下的哪一个子目录
# CROSS_COMPILE:即交叉编译器的前缀
make ARCH=arm CROSS_COMPILE=gcc-arm-linux-gnueabi-
make dtbs
qemu-system-arm
-M vexpress-a9
-m 256M -kernel arch/arm/boot/zImage
-append "rdinit=/linuxrc console=ttyAMA0 loglevel=8"
-dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb
-nographic
# 以上命令中参数含义如下;
# -M:指定硬件芯片框架
# -m:指定运行内存大小
# -kernel:指定运行的内核镜像
# -dtb:指定具体芯片的配置信息
# -nographic:指定不使用图形界面
运行结果
# ...
1000a000.uart: ttyAMA1 at MMIO 0x1000a000 (irq = 38, base_baud = 0) is a PL011 rev1
1000b000.uart: ttyAMA2 at MMIO 0x1000b000 (irq = 39, base_baud = 0) is a PL011 rev1
1000c000.uart: ttyAMA3 at MMIO 0x1000c000 (irq = 40, base_baud = 0) is a PL011 rev1
rtc-pl031 10017000.rtc: registered as rtc0
rtc-pl031 10017000.rtc: setting system clock to 2022-09-14T14:39:19 UTC (1663166359)
amba 10020000.clcd: Fixing up cyclic dependency with 0-0039
drm-clcd-pl111 10020000.clcd: DVI muxed to daughterboard 1 (core tile) CLCD
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111
drm-clcd-pl111 10020000.clcd: DVI muxed to daughterboard 1 (core tile) CLCD
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/bus@40000000/bus@40000000:motherboard-bus@40000000/bus@40000000:motherboard-bus@40000000:iofpga@7,00000000/10006000.kmi/serio0/input/input0
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111
ALSA device list:
#0: ARM AC'97 Interface PL041 rev0 at 0x10004000, irq 32
drm-clcd-pl111 10020000.clcd: DVI muxed to daughterboard 1 (core tile) CLCD
Freeing unused kernel image (initmem) memory: 1024K
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111
Run /linuxrc as init process
can't run '/etc/init.d/rcS': No such file or directory
Please press Enter to activate this console. input: ImExPS/2 Generic Explorer Mouse as /devices/platform/bus@40000000/bus@40000000:motherboard-bus@40000000/bus@40000000:motherboard-bus@40000000:iofpga@7,00000000/10007000.kmi/serio1/input/input2
drm-clcd-pl111 10020000.clcd: DVI muxed to daughterboard 1 (core tile) CLCD
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111
ls
/ # ls
bin dev linuxrc root sbin usr
/ # pwd
/
/ # mkdir mnt
/ # ls
bin dev linuxrc mnt root sbin usr
/ #
我觉得可以写一个
makefile
或者一个.sh
来实现自动处理
报错:can't open /dev/tty3: No such file or directory
解决:
sudo mknod tty1 c 4 1
sudo mknod tty2 c 4 2
sudo mknod tty3 c 4 3
sudo mknod tty4 c 4 4
报错:---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
解决:查看init
文件格式与kernel
文件格式匹配
报错:---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
解决:未安装文件系统
ubuntu 交叉编译arm linux 内核小例子
从源码编译安装 Linux 内核之二
参考文章