当前位置: 首页 > news >正文

记录QUME上模拟ARM运行环境(内核 2.6.30)

下载安装包

# 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

注意Linuxgcc版本匹配支持!

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 <rob@landley.net> 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/initrdDevice 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)
解决:未安装文件系统

参考文章

  • 嵌入式linux:make 参数 ARCH与CROSS_COMPILE
  • linux解压.xz文件
  • 教你编译一个基于arm的Linux内核,并用qemu模拟器测试
  • arm系列的交叉编译器各版本的区别
  • 使用qemu进行arm64架构linux开发学习

相关文章:

  • JavaWeb开发之——MySQL数据模型(04)
  • c语言分层理解(c语言字符串+内存库函数)
  • Es6的promise和async
  • Java项目本地部署宝塔搭建实战java中小医院管理系统源码
  • java 低耦合观察者模式
  • 七、OCR-PaddlePaddle训练源码解析系列-文字识别
  • 数据结构与算法之非递归遍历二叉树
  • Unity技术手册 - 创建物体有几种方式?
  • threejs中各种的对像详细介绍
  • 代码优化~关注核心逻辑,封装常用规则
  • Android车载开发基础学习——蓝牙通信是如何实现的?
  • 智慧政务、数字化优先与数字机器人,政务领域正在开启“政务新视界”
  • DES算法是对称算法吗,能否通过在线工具进行DES解密?
  • 【车间调度】基于GA/PSO/SA/ACO/TS优化算法的车间调度比较(Matlab代码实现)
  • springBoot 的默认线程池-ThreadPoolTaskExecutor
  • 【EOS】Cleos基础
  • Angular Elements 及其运作原理
  • Apache Zeppelin在Apache Trafodion上的可视化
  • CSS 提示工具(Tooltip)
  • Mocha测试初探
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • 大数据与云计算学习:数据分析(二)
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 二维平面内的碰撞检测【一】
  • 后端_MYSQL
  • 基于组件的设计工作流与界面抽象
  • 前端存储 - localStorage
  • 驱动程序原理
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 十年未变!安全,谁之责?(下)
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 应用生命周期终极 DevOps 工具包
  • 在Mac OS X上安装 Ruby运行环境
  • 追踪解析 FutureTask 源码
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​queue --- 一个同步的队列类​
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # 达梦数据库知识点
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (C语言)球球大作战
  • (LeetCode) T14. Longest Common Prefix
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)重识new
  • 、写入Shellcode到注册表上线
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)