0 背景
有一个很厉害的师兄针对我们实验室的需求设计了一块控制板,以beaglebone为基础,由于更改了一些底层的硬件,所以重新定制编译的内核,并预先烧写到了板子的flash中。现在需要安装ubuntu的文件系统,以使用ROS的相关功能函数库。前一段时间我在beaglebone官网下载了其提供的预编译好的根文件系统,修改挂载设置fstab文件后顺利启动,但是不能支持图形界面,不知是内核支持的原因还是文件系统的原因。前面琢磨了如何编译适用于ARM架构的内核(编译适用于ARM的linux内核并进行QEMU仿真),为了今后在需要时按自己的意愿修改文件系统,最近两天一直在研究如何定制自己的根文件系统,参考了几篇经验帖,结合自己的实践,特记录于此。
图1 Ubuntu rootfs定制流程
1 获得ubuntu基本裸系统
1.1 利用debootstrap工具
参考ubuntu提供的网站https://wiki.ubuntu.com/ARM/RootfsFromScratch/QemuDebootstrap
由于我要跨平台运行,所以不能简单地进行本机编译,在网上查询专门有一个模拟不同机器架构的软件qemu,而在ubuntu中对其支持良好。所以首先在PC主机ubuntu系统中安装qemu模拟器:
sudo apt-get install qemu-user-static
然后就可以利用下面的命令获得一个基本的ubuntu裸文件系统:
sudoqemu-debootstrap --arch armhf --variant=minbase --verbose trusty /mnt/rootfs/
生成的minbase文件系统大小为123M。
manqemu-debootstrap可以看到其原理:
The qemu-debootstrap wrapper calls debootstrap(8) making use of the --foreign and --second-stage options, and copies the appropriate qemu-user-static(1) binary into place inorder to install cross-architecture chroots. In order for it to work seamlessly, the binfmt-support package must be installed.
也就是qemu-debootstrap调用debootstrap函数,并且把qemu-user-static的二进制文件qemu-arm-static复制到目标目录中以用于跨平台编译。qemu-debootstrap的参数选项和debootstrap相同,具体的可以查看debootstrap的用法。
1.2 从ubuntu官网下载
我们也可以从ubuntu官方网站下载其提供的最小裸文件系统。
mkdir~/ubuntu-rootfs
cd ubuntu-rootfs
# 下载Ubuntu Core rootfs
wget http://cdimage.ubuntu.com/ubuntu-core/releases/14.04.1/release/ubuntu-core-14.04-core-armhf.tar.gz
解压Ubuntu Core rootfs tar包,注意一定要用sudo
sudo tar -xzvf ubuntu-core-14.04-core-armhf.tar.gz
# 退回到上一级目录
cd ..
由于我们要chroot,所以需要能够在chroot环境执行armhf版本的binary,所以我们要接触linux的binfmt机制和qemu static解释器
sudo apt-getinstall qemu-user-static
sudo cp/usr/bin/qemu-arm-static ubuntu-rootfs /usr/bin/
先将本机的dns配置复制到目标rootfs,后面联网时会用到
sudo cp -b/etc/resolv.conf ~/ubuntu-rootfs/etc/resolv.conf
2 挂载相关文件系统并chroot
挂载proc, sys, dev, dev/pts等文件系统,我们可以编写一个bash脚本ch-mount.sh来完成挂载和后面的卸载操作,下载ch-mount.sh至当前目录,执行如下操作:
sudo bashch-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
3 配置网络服务
一旦进入了chroot的环境,我们需要修改/etc/apt/sources.list的内容。去掉除以deb-src开头的所有库的注释,这里可能需要用到vim编辑器,所以最好是在chroot之前就在主机目录下把ubuntu-rootfs//etc/apt/sources.list的内容修改好,因为一旦chroot后,裸根文件系统很可能没有安装vim编辑器。网络的dns我们在第一步中已经复制过来了。
4 安装所需软件包
apt-get update
首先更新资源列表,然后安装必备的软件包,根据自己的需求:
#language-pack-en-base 英文翻译的mo文件
# sudo sudo命令
# ssh ssh的client和server
# 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\
language-pack-en-base \
sudo \
ssh \
net-tools \
ethtool \
wireless-tools \
ifupdown \
network-manager \
iputils-ping \
rsyslog \
bash-completion \
htop \
--no-install-recommends
5 设置用户相关
adduser Ubuntu,然后根据提示设置密码。
设置主机名称:
echo"ubuntu-arm">/etc/hostname
设置本机入口ip:
echo"127.0.0.1 localhost">>/etc/hosts
echo"127.0.1.1 ubuntu-arm">>/etc/hosts
允许自动更新dns:
dpkg-reconfigureresolvconf
设置时区:
dpkg-reconfiguretzdata
6 配置串口调试服务
在用debootstrap制作的rootfs里,是不包含有串口登陆tty的。需要添加一个/etc/init/ttyS0.conf文件才能从串口登陆。否则你会在串口看见KERNL的输出信息,但就是等不到登陆提示。
cp tty1.confttyS0.conf
vi ttyS0.conf,修改其内容如下:
start on stoppedrc or RUNLEVEL=[12345]
stop on runlevel[!12345]
respawn
exec /sbin/getty-L 115200 ttyS0 vt102
由于最后要利用SD卡在板子上启动,需要修改/etc/fstab 的内容,以便根文件系统能够正确地挂载,否则不能正确挂载根文件系统将导致系统无法启动。由于在内核中设置的根文件系统的挂载目录是SD卡的第五分区,于是如下设置:
#
/dev/mmcblk0p5 / ext4 defaults,noatime,errors=remount-ro 0 1
/dev/mmcblk0p1 /boot/uboot vfat defaults,noatime 0 0
然后exit退出chroot,执行sudo bash ch-mount.sh -m ubuntu-rootfs/卸载相关文件系统即可。
我利用debootstrap工具完成的根文件系统包的大小为:
sudo du -s -h rootfs
288M rootfs
而利用ubuntu官方网站提供的裸系统制作的根文件系统包的大小为:
sudo du -s -hubuntu-core-rootfs
276M ubuntu-core-rootfs
为什么我自己做的会稍微大一点儿呢?我什么也没有多加啊,都是按照最简化来的。
参考文献:
[1] https://wiki.ubuntu.com/ARM/RootfsFromScratch/QemuDebootstrap
[2] http://gnu-linux.org/building-ubuntu-rootfs-for-arm.html
[3] http://blog.csdn.net/wjs1033/article/details/44559035
[4] https://uframer.gitbooks.io/beaglebone-black-notes/content/building_ubuntu_rootfs_for_arm.html
祝枫
2016年6月18日于深圳
---------------------------------------------------分割线--------------------------------------------------------------
2016年6月20日记:
今天试了下前两天自己做的系统,分别是在ubuntu系统下基于debootstrap制作的最小文件系统和在ubuntu官网提供的ubuntu-core的基础上修改的文件系统。观察其启动过程,应该是都通过了文件系统检查并已成功启动,因为kernel输出的启动信息都到了* Stopping System Vrunlevel compatibility[ OK ],然而都是无法正常显示登陆界面,致使无法登陆。查询原因,应该是串口登录设置不正确,针对根据debootstrap制作的无论怎么修改串口设置,都不见成效,最后只能暂时放下。根据ubuntu-core更改的系统,一开始也是启动到相同的位置就卡住了,由于之前从beaglebone官网上下载的能够正常启动的文件系统就是beaglebone根据ubuntu-core更改的,于是我参考了一下之前下载的那个文件系统中的串口登录设置,发现其/etc/init/文件夹下有一个名为serial.conf的文件,打开后其内容如下:
start on stoppedrc RUNLEVEL=[2345]
stop on runlevel[!2345]
respawn
exec /sbin/getty115200 ttyO0
额,竟然是ttyO0,不是tty00!!!!!怪不得刚才在第一个文件系统中尝试tty00没有反应,在linux下O和0可真像啊。。。对了,在第二个系统中我是直接把那个serial.conf复制过去的,然后就正常气动了。要不然让我写成了tty00,又不知道要再在这里卡多少天呢,但是这也暴露了对于文件系统内部的知识,我还是很欠缺的。把第一个系统中的串口登录配置也改为serial.conf时,成功启动!
在成功启动的系统中,又遇到了用户权限问题,系统里面没有root用户权限。应该是当时没有修改debootstrap的root密码导致的。在PC上通过chroot更改根目录后,执行:
passwd root修改root密码后,在板子上就可以通过su –切换至超级用户,然后修改/etc/sudoers里面的内容,在root行下加上这句:
user ALL=(ALL:ALL) ALL,然后user就可以获得root权限了。
至此,一个自己定制并成功安装的ubuntu for ARM最小根文件系统就完成了。
---------------------
作者:mountzf
来源:CSDN
原文:https://blog.csdn.net/mountzf/article/details/51707853
版权声明:本文为博主原创文章,转载请附上博文链接!