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

Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动

文章目录

  • 1、 buildroot源码获取
  • 2、buildroot配置
  • 3、buildroot编译
  • 4、挂载根文件系统

在上一篇 Qemu开发ARM篇-4、kernel交叉编译运行演示中,我们编译了kernel,并在qemu上进行了运行,但到最后,在挂载根文件系统时候,挂载失败,这是因为我们还没有根文件系统,在本章中,我们将制作根文件系统。

rootfs制作方式有很多方式,如busyBoxbuildrootYocto等,在该篇章中,我们使用buildroot来制作根文件系统,主要考虑到busyBox制作完还需要手动首改一些启动配置比较繁琐,而Yocto如果电脑配置不是很好,编译时间过长,比较麻烦。

1、 buildroot源码获取

buildroot源码:github链接
在src目录下使用mkdir buildroot && cd buildroot创建buildroot路径,并使用如下命令获取buildroot源码:

mkdir buildroot && cd buildroot
git clone https://github.com/buildroot/buildroot.git

buildroot版本,因为master分支的源码会不停地更新,因此在这里我们选择一个确定版本作为开发,在这里尽量选择一个比较稳定的buildroot版本,本次选择2022.11作为本次使用版本:

使用如下命令切换分支:

cd buildroot/
git checkout 2022.11 -b 2022.11

在这里插入图片描述

后续,我们将使用2022.11这个版本进行开发。

2、buildroot配置

buildroot编译需要先进行配置,在buildroot目录~/project/qemu/src/buildroot/buildroot输入如下命令进入配置页面。

make menuconfig

在这里插入图片描述
1、配置Target option
主要配置以下几项:1、架构选择Arm(little endian)contex-A9,其他选择如下图。
在这里插入图片描述

2、配置交叉编译工具链
这里我们配置为外部交叉工具链,也就是配置成我们前面自己下载的交叉编译工具链:
进入Toolchain选项:
在这里插入图片描述
需要配置的项目和其对应的内容如下:
在这里插入图片描述
在这里插入图片描述

1:选择External toolchain,即外部工具链
2:选择Custom toolchain:即我们自己下载的工具链
3: 选择Pre-installed toolchain:即我们自己的工具链
4:输入我们自己工具链的路径,这里就是我们前面编译uboot和kernel的工具链的路径
5:输入我们自己交叉编译工具链的前缀:这里为:arm-linux-gnueabi
6:选择我们工具链的版本:我们是7.5版本,因此在这里选择7.x
7:选择工具链kernel head:我们工具链的版本为:·4.10·,这里选择4.10.x
8:选择使用glibc
9:选中我们gcc支持的一些特性
10:选中我们gcc支持的一些特性

3、System configuration
该选项主要配置系统的一些参数:如初始化程序类型、主机名、密码以及欢迎语等,进入该选项,进行如下配置:
在这里插入图片描述

1:配置主机名:可根据自己需求进行更改
2:配置欢迎语:可根据自己需求进行更改
3: 初始化系统程序:这里我们选择systemd
4:使能root等,并设置密码:我这里设置为123456
5:修改shell为bash
其他的保持默认即可

4、kernel配置选项
因为我们前面自己下载了kernel,因此这里我们不需要选择内核,将内核取消勾选。
在这里插入图片描述
5、Target packages配置选项
该配置选项用来配置一些软件包,这里我们选中ssh功能
包选择路径如下:
Target packages->Networking applications->openssh
在这里插入图片描述
6、Filesystem images配置选项
该选项用来配置生成的文件系统以什么方式存在,在这里我们选择ext4格式:
在这里插入图片描述

7、Bootloaders配置选项
因为我们前面自己下载了uboot,因此这里我们不需要选择bootloader,将bootloader取消勾选。
在这里插入图片描述
配置完成记得使用下面菜单栏中的Save保存配置。

8、为了不用每次都这么繁琐的进行配置,我们需要将这次的配置文件保存下来,
使用如下命令保存我们的配置文件到confis目录下,并使用git将其提交到本地库:

cp .config configs/vexpress_a9_defconfig
git add configs/vexpress_a9_defconfig
git commit -m "add vexpress_ap_defconfig"

在这里插入图片描述

3、buildroot编译

在script目录使用touch build_roofs.sh && chmod 777 build_roofs.sh命令创建编译脚本,并在编译脚本输入如下内容:

#!/bin/bash
cd ~/project/qemu/src/buildroot/buildroot
make vexpress_a9_defconfig O=~/project/qemu/out/rootfs-arm
make menuconfig O=~/project/qemu/out/rootfs-arm
make O=~/project/qemu/out/rootfs-arm
cd ~/project/qemu

然后执行该脚本./script/build_roofs.sh进行编译编译过程会从网络下载软件包,如果网络不是很好,有可能会编译失败,所以尽量进行全局科学上网。

或者也可以从该连接下载笔者在编译时下载好的包,将其下载下来,替换buildroot目录下的dl目录即可。

编译完成之后,根文件系统在out/rootfs-arm/images目录下:
在这里插入图片描述
其中rootfs.ext4即是我们编译出来的ext4格式的根文件系统。

4、挂载根文件系统

在上一篇Qemu开发ARM篇-4、kernel交叉编译运行演示中,我们编译了kernel,但是在启动的时候,由于没有挂载根文件系统,导致panic,无法进入系统,现在我们已经编译出了根文件系统了,我们来挂载它。

在这里我们通过qemu的SD卡的形式将根文件系统挂载上去,SD卡要求文件系统大小为2的N次方,我们看看我们编译的rootfs大小:
在这里插入图片描述
可以看到rootfs.ext4是rootfs.ext2的软连接,查看rootfs.ext2文件大小,可以看到是60M,不满足SD大小要求,使用如下命令拷贝一份rootfs.ext2并将其resize到64M:

 cp rootfs.ext2 rootfs.ext2_tem
 qemu-img resize rootfs.ext2_tem 64M

在script目录使用touch run_kernel_with_rootfs.sh && chmod 777 run_kernel_with_rootfs.sh命令创建运行脚本,并在运行脚本输入如下内容:

#!/bin/bash
qemu-system-arm -M vexpress-a9 -m 512M \
 -kernel ~/project/qemu/out/kernel-arm/arch/arm/boot/zImage \
 -dtb ~/project/qemu/out/kernel-arm/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
 -nographic \
 -no-reboot \
 -append "root=/dev/mmcblk0 rw init=/usr/sbin/init console=ttyAMA0" \
 -sd ~/project/qemu/out/rootfs-arm/images/rootfs.ext2_tem

参数解释:

-kernel:指定内里路径,这里使用zImage
-dtb:指定设备树地址
-nographic:不使用图形化界面
-no-reboot:不重启
-append:因为我们这里还没有使用uboot引导kernel,因此需要借助qemu的-append参数传递bootargs参数。root指定根文件系统路径,因为我们SD直接就是ext4的文件系统没有进行分区,因此是/dev/mmcblk0,rw:挂载为可读写,init:指定系统初始化程序,因为我们在编译rootfs的时候指定的是systemd,因此这里我们需要指定为/usr/sbin/init(该init其实就是systemd的一个软连接,可以在进入板端进行查看器连接属性),console:使用串口

然后运行./script/run_kernel_with_rootfs.sh启动内核,如下:
在这里插入图片描述
可以看到已经成功进行启动了,并挂载成功了根文件系统,输入用户名root,密码:123456(密码为前面配置buildroot的时候设置的)


http://www.kler.cn/news/325174.html

相关文章:

  • 常见字符函数和字符串函数(上)
  • 在Linux中修改vm.max_map_count参数的步骤
  • InternVL 微调实践
  • C#里使用最简单的线程调用界面更新的方法
  • 【蚂蚁HR-注册/登录安全分析报告】
  • 基于大数据技术的颈椎病预防交流与数据分析及可视化系统
  • 【Webpack】优化前端开发环境的热更新效率
  • 上交所系统被股民买崩了?原因竟然是...
  • 宠物智能听诊器科技赋能宠物医疗
  • ad布线的常见错误123
  • JavaScript网站设计案例:如何构建一个交互性强、性能优异的网站
  • win10系统K8S安装教程
  • MYSQL的安装和升级
  • 【unity进阶知识4】封装unity协程工具,避免 GC(垃圾回收)
  • Vue76 编程式路由导航
  • 云手机的默认ip地址是什么
  • (补充)3DMAX初级小白班第三课:创建物体+物体材质编辑
  • gateway--网关
  • 【spring】 -Dlog4j.configurationFile配置log4j2的自定义路径
  • mac Wireshark You do not have permission to capture on device “rvio“.
  • Java 编码系列:集合框架(List、Set、Map 及其常用实现类)
  • 从0到1教你学会写测试总结
  • Emiya 家今天的饭C++
  • 封装axios请求
  • C++ 中是#pragma once
  • cefsharp新版本OnBeforeResourceLoad 禁止http自动跳转https显示404错误解决办法 含代码
  • 在Ubuntu中自动挂载SMB/CIFS共享
  • Springboot2笔记核心技术——1.基础入门
  • Java-数据结构-Map和Set-(二)-哈希表 |ू・ω・` )
  • 第八届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)