在Ubuntu X86_64中构建arm ubuntu rootfs和调试arm应用
off999 2024-11-10 10:27 26 浏览 0 评论
我们常用的是使用buildroot、busybox、yocto进行构建arm嵌入式根文件系统,这种方式大家接触得应该都比较多了,构建也是比较简单,唯一得缺点是源得速度太慢了,有时候需要一天才能编译出来一个文件系统。
1. 下载ubuntu base包
我今天讲得是一个更简单得方法,从ubuntu-base进行构建,以ubuntu20.04为例,下载arm架构的ubuntu-base压缩包https://cdimage.ubuntu.com/ubuntu-base/releases/,可以看到有几类以后缀-armXX.tar.gz结尾的,它们的含义如下:
- ubuntu-base-20.04.3-base–arm64.tar.gz 适用于64位arm架构,几乎所有ARMv8-A都是64位处理器,例如ARM Cortex-A53、 ARM Cortex-A57、ARM Cortex-A72、ARM Cortex-A73、RM_Cortex-A76等。
- ubuntu-base-20.04.3-base-armhf.tar.gz 适用于32位带硬浮点arm处理器,hf(hard float),即带有浮点单元 (FPU),主要用于ARMv7-A,例如[ARM Cortex-A5、ARM Cortex-A7、ARM Cortex-A8、ARM Cortex-A9、ARM Cortex-A12、ARM Cortex-A15、ARM Cortex-A17。
压缩包25M左右,解压出来大概50多M,还是比较精简的,如果这个大小不能接受,就只能自己使用buildroot构建,经常用它来构建一个ramdisk. QSPIFlash就完全可以装下一个文件系统。
使用ubuntu-base的好处是,可以直接使用apt来安装你所需要的软件包,不需要一个一个的编译各种依赖环境。我们下载后解压可以看到,很多命令是没有的,基本的ifconfig,vim,file等命令都没有,当然实际运行环境是不需要这些软件包的。
如果你的嵌入式环境中没有网络,则我们可以直接在PC的Ubuntu中将需要的包通过apt安装好,再打包烧写到arm中。
下面讲一下具体方法:
2. 将ubuntu-base解压
将ubuntu-base包解压到准备的rootfs文件夹,这里为/mnt/ubuntu,下面命令根据实际情况更换
$sudo tar -xpvf ubuntu-base-20.04.3-base-armhf.tar.gz -C /mnt/ubuntu3. 安装qemu arm模拟器环境,可以直接在x86_64中运行和调试应用
通过apt安装qemu
sudo apt-get install multistrap qemu qemu-user-static binfmt-support dpkg-cross查看qemu版本
qemu-arm-static --version
qemu-arm version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.37)Ubuntu自带的 QEMU 版本有点老(我的18.04 LTS 附带的 QEMU 2.11),如果需要新版本则需要自己编译安装,当前最新版本是QEMU 6.1.0;
wget https://download.qemu.org/qemu-6.1.0.tar.xz
tar xvJf qemu-6.1.0.tar.xz
mkdir build
cd build
../qemu-6.1.0/configure --static --prefix="$PWD/user_static" --target-list=arm-softmmu --disable-system--disable-system不编译qemu-system-xx相关的程序,这里暂时不需要.
其中--target-list后面可以接不同的架构的qemu,比如arm-softmmu是针对arm平台的。aarch64-softmmu是针对arm64平台,也就是aarch64.
4. 安装binfmt
binfmt(Binary Format)是一个内核模块,它的用处如它的名字,通过二进制文件头来识别它的格式,从而指定用哪个解释器去启动——可以理解为二进制文件的hashbang(用处类似于在Python文件的第一行写上“#!/usr/bin/env python”)。有了它我们就可以像启动原生ELF一样启动一个ARM或其他任何QEMU支持的程序了。
sudo apt install qemu-user-binfmt
update-binfmts --display安装这个包会依赖安装系统软件源中的qemu-user。我们用不到它,但装这个包的意义在于它包含了几个自动向内核注册QEMU binfmt的脚本,这样我们就不需要再手动指定我们的ARM可执行文件需要哪个路径下的QEMU来执行,非常方便。安装成功后在命令行中执行“update-binfmts –display”。
我们此时可以测试一下,临时将环境变量QEMU_LD_PREFIX设置为我们要chroot进去的根目录,然后运行ARM设备中提取出的ELF可执行文件,如果不报错就可以了。如下a.out是我编译的arm的hello world,这个程序可在我的测试设备上正常运行。
5. 如何在x86_64中调试arm程序?不用在开发板中调试
编辑hello.c测试程序
#include <stdio.h>
int main()
{
printf("hello world!\r\n");
return 0;
}交叉编译arm程序
$ arm-linux-gnueabihf-gcc hello.c -o a.out
$ file a.out
a.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=222b024ba166e297b1ceb1dc97a906259712bb60, with debug_info, not stripped使用qemu在x86下运行arm程序
$ export QEMU_LD_PREFIX=/mnt/ubuntu
$ ./a.out
hello world!不加QEMU_LD_PREFIX环境变量,则会出现找不到库的错误提示/lib/ld-linux-armhf.so.3: No such file or directory.
/mnt/ubuntu是ubuntu base包的解压路径,也就是arm rootfs的根目录.
在这里每次都需要设置QEMU_LD_PREFIX环境变量.我们是否可以模拟arm的文件系统环境?直接运行程序呢? 答案是肯定的.这也是我们在x86环境中构建根文件系统的原因.
复制QEMU程序
拷贝qemu-arm-static或者我们自己编译的最新版本到刚刚解压出来的目录/mnt/ubuntu/usr/bin/:
$sudo cp /usr/bin/qemu-arm-static /mnt/ubuntu/usr/bin若是arm64则拷贝qemu-aarch64-static:
$sudo cp /usr/bin/qemu-aarch64-static /mnt/ubuntu/usr/bin当我们启动为ARM或其他架构编译的应用程序时,系统会调用binfmts识别它的类型并调用之前注册的interpreter(如/usr/bin/qemu-aarch64)来“翻译”启动。在chroot下,依然会从这个路径中寻找。因此如果使用chroot 后[6 小点讲解],这个路径下找不到QEMU,启动任何程序都会报错No such file or directory。这个报错会有很多歧义,因此一定要自己确认一下QEMU确实在rootfs的“/usr/bin”目录中。
以后拿到一个新的固件包,只需要解压到一个文件夹里,把对应架构的qemu拷贝进去,直接运行命令chroot即可。遇到需要调试的程序,我们通过运行qemu-arm -g 2331 /path/to/binary指定-g参数开启调试选项,也可以声明一个环境变量QEMU_GDB=2331,带上这个环境变量所启动的程序,都会自动开启GDB端口并等待调试器attach,调试起来是不是很方便呢?
6. chroot操作
方法1:使用原始的方法,来进入chroot环境
挂载和激活 /dev:通常激活 /dev 目录下设备的方式是在 /dev 目录挂载一个虚拟文件系统(比如 tmpfs),然后允许在检测 到设备或打开设备时在这个虚拟文件系统里动态创建设备节点。这个通常是在启动过程中由 udev 完成。由于我们的ubuntu-base新系统还没有 udev,也没有被引导,有必要手动挂载和激活 /dev 这可以通过绑定挂载宿主机系统的/dev 目录来实现。绑定挂载是一种特殊的挂载模式,它允许在另外的位置创建某个目录或挂载点的镜像。运行下面的命令来实现:
sudo mount -v --bind /dev /mnt/ubuntu/dev挂载虚拟文件系统:
sudo mount -vt devpts devpts /mnt/ubuntu/dev/pts -o gid=5,mode=620
sudo mount -vt proc proc /mnt/ubuntu/proc
sudo mount -vt sysfs sysfs /mnt/ubuntu/sys
sudo mount -vt tmpfs tmpfs /mnt/ubuntu/run
sudo cp /etc/resolve.conf /mnt/ubuntu/etc/进入chroot环境:
chroot /mnt/ubuntu我们可以编写一个bash脚本ch-mount.sh来完成挂载和后面的卸载操作
sudo bash ch-mount.sh -m ubuntu-rootfs/
ch-mount.sh的内容
#!/bin/bash
function mnt() {
echo "MOUNTING"
sudo mount -t proc /proc ${2}proc
sudo mount -t sysfs /sys ${2}sys
sudo mount -o bind /dev ${2}dev
sudo mount -o bind /dev/pts ${2}dev/pts
sudo chroot ${2}
}
function umnt(){
echo "UNMOUNTING"
sudo umount ${2}proc
sudo umount ${2}sys
sudo umount ${2}dev/pts
sudo umount ${2}dev
}
if ["$1" == "-m" ] && [ -n "$2" ] ;
then
mnt $1 $2
elif ["$1" == "-u" ] && [ -n "$2" ];
then
umnt $1 $2
else
echo ""
echo "Either 1'st, 2'nd or bothparameters were missing"
echo ""
echo "1'st parameter can be one ofthese: -m(mount) OR -u(umount)"
echo "2'nd parameter is the full pathof rootfs directory(with trailing '/')"
echo ""
echo "For example: ch-mount -m/media/sdcard/"
echo ""
echo 1st parameter : ${1}
echo 2nd parameter : ${2}
fi卸载使用sudo bash ch-mount.sh -u ubuntu-rootfs/
方法2:使用arch-chroot
linux发行版archlinux提供了一个自动化chroot的脚本arch-chroot,包含自动配置DNS文件、自动挂载虚拟文件系统等操作,用来维护linux系统非常方便,chroot时无需挂载等操作直接执行:
sudo arch-chroot /mnt/ubuntuarch-chroot是方法1的封装,除此之外有会对目标系统进行检测并预先配置.
经过上述步骤我们就进入chroot环境了.
更新源并安装需要的软件
修改/mnt/ubuntu/etc/apt/sources.list,修改之前做一个备份.
这里推荐使用中科大的源http://mirrors.ustc.edu.cn/ubuntu-ports/
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-backports main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse首先更新资源列表,然后安装必备的软件包,根据自己的需求:
# sudo sudo命令 # ssh ssh的client和server # vim vim编辑器 # net-tools ifconfig,netstat,route,arp等 # ethtool ethtool命令,显示、修改以太网设置 # wireless-tools iwconfig等,显示、修改无线设置 # ifupdown ifup,ifdown等工具 # network-manager Network Manager服务和框架,高级网络管理 # iputils-ping ping和ping6 # rsyslog 系统log服务 # bash-completion bash命令行补全 # htop htop工具,交互式进程查看器
apt-get install\
sudo \
ssh \
vim \
net-tools \
ethtool \
wireless-tools \
ifupdown \
network-manager \
iputils-ping \
rsyslog \
bash-completion \
htop \
--no-install-recommends也可通过chroot直接执行某个命令,例如修改root密码,其中/mnt/ubuntu是我们的rootfs目录:
sudo chroot /mnt/ubuntu passwd配置串口调试服务
制作的rootfs里,可能是不包含有串口登陆tty的,需要添加一个/etc/init/ttyPS0.conf文件才能从串口登陆。否则你会在串口看见KERNL的输出信息,但就是等不到登陆提示。
ttyPS0.conf,修改其内容如下:
echo "start on stopped rc or RUNLEVEL=[12345]" > /etc/init/ttyPS0.conf
echo "stop on runlevel [!12345]" >> /etc/init/ttyPS0.conf
echo "respawn" >> /etc/init/ttyPS0.conf
echo "exec /sbin/getty -L 115200 ttyPS0 vt102" >> /etc/init/ttyPS0.conf准备打包前,清除文件系统中的一些缓存数据
sudo apt-get clean
sudo rm -rf var/cache/*
sudo rm -rf var/lib/apt/lists/*7. 退出构建Core根文件系统
设置好Core根文件系统后,用exit命令退出chroot。
8. 打包做好的Core根文件系统
sudo tar –czvf ../ubuntu.tar.gz .
在根文件系统上一目录生成ubuntu.tar.gz的文档.
相关推荐
- photoshop最新软件版本(ps最新版本是)
-
你好,AdobePhotoshop的最新版本是PhotoshopCC2020。新版本的Photoshop具有更多的功能和改进,包括云同步,自动对象选择,增强的画笔和填充工具等。此外,新的Phot...
-
- 扫图识别图片在线(扫图识别app下载)
-
1、首先打开手机相册,然后选择你需要识别的图片;2、长按图片,在应用选择中选择“提取文字”;3、对于通过扫一扫识别图片后所得到的文字内容,我们可以进行分享或保存到便签中进行修改编辑,还可以转换到其它文档中进行处理。拓展资料:二维码是近年来在...
-
2026-01-17 16:03 off999
- 活跃气氛的10个小游戏(活跃气氛的10个小游戏简单)
-
我推荐手指儿歌律动小游戏,因为手指儿歌的话,会活动小朋友们的手指,手指活动完之后,我们就可以进行下一步的一些事情1、大合唱:准备一些歌曲,大家将歌词印在白板上,每人叫出句子,所有人一起唱歌,激发出非常...
- 全能播放器(EV 全能播放器)
-
在选择全能播放器时,可以考虑以下几个因素:格式支持、功能丰富、界面友好、播放流畅、兼容性强。目前市面上有许多优秀的全能播放器可供选择,如VLC媒体播放器、PotPlayer、KMPlayer等。它们都...
- 和平精英免费挂 锁头 透视(和平精英挂透视,锁头,自瞄)
-
apm的意思有很多种。apm在游戏中是指每分钟操作次数,也叫手速;APM也可以是AutomatedPeopleMoverSystem的缩写,意思是旅客自动捷运系统;APM还可能是Advanced...
- 爱思助手app下载安装(爱思助手下载 安装安卓)
-
不能在手机端直接下载,需要先下载PC端。安装步骤如下:第1步,安装爱思助手PC端用电脑访问爱思助手官网在产品中心下载并安装“爱思助手PC端V7版”第2步,安装爱思助手移动端打开爱思助手PC端用数据线连...
- 手机电视直播在线直播(免费观看电视在线高清直播)
-
1、准备一个U盘,在电脑上下载电视直播软件的安装包(apk格式的,如泰捷视频、电视猫、电视家等软件),复制并存储到U盘的根目录下;2、将U盘插入电视机的USB接口;3、启动电视机,进入智能电视主界面;...
- 万能密码破解器(万能破解wifi密码神器下载)
-
不真实因为万能歪歪密码器声称可以破解任意密码,但实际情况下,密码破解需要依靠强大的计算力和算法,而万能歪歪密码器只是一个简单的软件,无法实现这种高难度的破解。同时,使用万能歪歪密码器还会存在一定的安全...
- firefox国际版
-
中国版:原生集成了如鼠标手势,支付助手等国内用户常用功能的浏览器扩展;提供了与国内网址导航类似的"火狐导航"作为默认主页;设置项与国际版略有不同;除国际通行的mozilla账户外,也可使用...
- 轻颜相机(轻颜相机有实况拍照吗)
-
轻颜相机调视频背景虚化的方法是通过调整相机的景深模式来实现。首先,打开轻颜相机应用并选择拍摄模式。然后,在拍摄界面上方可以找到一个景深模式的选项。点击该选项后,会出现不同的景深效果供选择。选择合适的景...
- 华为浏览器(华为浏览器app下载安装)
-
华为浏览器,是华为手机上用的浏览器是他自己设定的,一般都是安卓版的,IE浏览器是windows操作系统自带的浏览器,是windows系统下的一个应用程序,与这个华为浏览器是,风马牛不相及没有任何联系,...
- pps网络电视官方下载(pps网络电视tv版)
-
你的网速不好吧,不行就把任务删除在重新下一次试试,在不行的话就重新安装客户端建议可以电视和手机同一WiFi里安装悟空遥控器,然后手机下载你需要安装到电视的软件APP,使用手机上的悟空遥控器安装本地...
- 腾讯qq免费下载安装最新版(腾讯qq下载安装2019版免费)
-
出现此种情况是由于电脑上之前安装的QQ软件某些后台程序还在运行当中,并没有关闭掉,解决方法:1、点开始-控制面板-添加删除程序,找到QQ程序删除,然后安装新的QQ版本。2、点开始-注销或者重启计算机都...
-
- qq极速版下载官网(·qq极速版下载)
-
极速版就是把完整版分成三部分。第一部分是飞车可以运行的最基础部分,这部分下载玩了就可以跑图了。余下部分会在不跑图的时间内自动下载。也可以自己设置。简单来说,极速就是在最少时间内可以玩到游戏。不可以,没有头条极速qq登录。只听说过头条极速登...
-
2026-01-17 12:51 off999
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
Python 批量卸载关联包 pip-autoremove
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
