安装:sudo apt-get install -y gcc-arm-linux-gnueabihf qemu
依赖:sudo apt-get install -y bison flex libncurses5-dev
- 上位机:ubuntu server 18.04.6
- 开发板:QEMU emulator version 2.11.1
- arm32:vexpress-a9 ,ddr最大1G
- arm32:vexpress-a15,ddr最大4G
linux + 简易文件系统
info
linux
-
编译
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig -
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
-
- Kernel hacking > printk and dmesg options
- Show timing information on printks #打印时间
- Enable dynamic printk() support #打开动态debug机制
- Device Drivers > Generic Driver Options
- Support for uevent helper #支持热插拔
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 -
验证
- qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic
- qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -nographic
自制文件系统
#include <stdio.h>
void main()
{
printf("\033[1;36m Hello qemu!\033[m\n");
while(1);
}
采用静态库编译: arm-linux-gnueabihf-gcc -static -o init init.c
linux2.6 内核支持两种格式的 initrd(虚拟文件系统),一种是 linux2.4 内核那种传统格式的文件系统镜像 image-initrd,其核心文件就是 /linuxrc
另外一种格式的 initrd 是 cpio 格式的,这种格式的 initrd 使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init,本文将这种 initrd 称为 cpio-initrd。
将init制作成cpio镜像
- echo init | cpio -o --format=newc > initramfs
qemu
- qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -initrd …/initramfs
- qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -nographic -initrd …/initramfs
- 停止qemu:ctrl + a,x(组合键ctrl+a,之后再按x)
linux + busybox
info
linux
-
编译
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig -
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
-
- Kernel hacking > printk and dmesg options
- Show timing information on printks #打印时间
- Enable dynamic printk() support #打开动态debug机制
- Device Drivers > Generic Driver Options
- Support for uevent helper #支持热插拔
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 -
验证
- qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic
- qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -nographic
busybox
-
编译
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig -
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
-
Settings —>
- [*] Build static binary (no shared libs) #使用静态库
-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 -
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- install
- 生成结果位于:当前根目录下的_install文件夹下
- 备注:默认安装到根目录下的_install,若想更改,可以通过menuconfig里面的选项更改
-
制作文件系统镜像
-
根目录构建
-
mkdir -p rootfs/{dev,etc/init.d,lib,proc,sys}
cp -raf busybox-1.34.1/_install/* rootfs
sudo mknod -m 666 rootfs/dev/tty1 c 4 1
sudo mknod -m 666 rootfs/dev/tty2 c 4 2
sudo mknod -m 666 rootfs/dev/tty3 c 4 3
sudo mknod -m 666 rootfs/dev/tty4 c 4 4
sudo mknod -m 666 rootfs/dev/console c 5 1
sudo mknod -m 666 rootfs/dev/null c 1 3
mount -t proc proc /proc
mount -t sysfs sysfs /sys
/sbin/mdev -s
echo /sbin/mdev > /proc/sys/kernel/hotplug
sudo chmod +x rootfs/etc/init.d/rcS
-
制作启动镜像
- 一定要在rootfs目录下执行,否则会失败
- cd rootfs;find ./ | cpio -o --format=newc > …/rootfs.img #制作成cpio镜像
-
启动
- cd linux-5.15;qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append “root=/dev/ram rdinit=sbin/init console=ttyAMA0” -nographic -initrd …/rootfs.img
- cd linux-5.15;qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -append “root=/dev/ram rdinit=sbin/init console=ttyAMA0” -nographic -initrd …/rootfs.img
-
执行demo
- code:https://gitee.com/tianzong2019/bookcode/blob/drv/6.chardev/example
- 编译后,启动qemu执行mdrv.ko(手动创建设备节点)
- 加载设备
- insmod mdrv.ko
- mknod /dev/miscdev c 10 2
- /dev/miscdev 设备节点名称
- c b和c 分别表示块设备和字符设备
- 10 MAJOR表示主设备号
- 2 MINOR表示次设备号
- 使用手动mknod则需要配置静态的主次设备号
- 卸载设备
- rmmod mdrv.ko
- rm -rf /dev/miscdev
- 最方便的方法,就是打开kernel的uevent helper,使能自动创建设备节点
启动脚本
上述的命令较多,使用脚本一键执行
#!/bin/bash
rdir=`pwd`
rootfs=${rdir}/rootfs
linux=${rdir}/linux-5.15
busybox=${rdir}/busybox-1.34.1
rcs=${rootfs}/etc/init.d/rcS
if [ -d "rootfs" ];then
echo "rm -rf rootfs"
rm -rf rootfs*
fi
mkdir -p ${rootfs}/{dev,etc/init.d,lib,proc,sys}
cp -raf ${busybox}/_install/* rootfs
sudo mknod -m 666 ${rootfs}/dev/tty1 c 4 1
sudo mknod -m 666 ${rootfs}/dev/tty2 c 4 2
sudo mknod -m 666 ${rootfs}/dev/tty3 c 4 3
sudo mknod -m 666 ${rootfs}/dev/tty4 c 4 4
sudo mknod -m 666 ${rootfs}/dev/console c 5 1
sudo mknod -m 666 ${rootfs}/dev/null c 1 3
echo "#!/bin/sh" >> ${rcs}
echo "mount -t proc proc /proc" >> ${rcs}
echo "mount -t sysfs sysfs /sys" >> ${rcs}
echo "/sbin/mdev -s" >> ${rcs}
echo "echo /sbin/mdev > /proc/sys/kernel/hotplug" >> ${rcs}
sudo chmod 777 ${rcs}
cd rootfs;find ./ | cpio -o --format=newc > ../rootfs.img
vex=vexpress-${1:-a9}
vexdtb=vexpress-v2p-`[ ${1:-a9} == a9 ] && echo ca9.dtb || echo ca15-tc1.dtb`
qemu-system-arm -M ${vex} -m ${2:-128}M -kernel ${linux}/arch/arm/boot/zImage -dtb ${linux}/arch/arm/boot/dts/${vexdtb} -append "root=/dev/ram rdinit=sbin/init console=ttyAMA0" -nographic -initrd ../rootfs.img
|