定制适用于ARM平台的Ubuntu rootfs(根文件系统)

来源:互联网 发布:算法精解:c语言描述pdf 编辑:程序博客网 时间:2024/05/16 15:02


文章来源:http://www.th7.cn/system/lin/201606/169260.shtml


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 -xpfubuntu-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/bashfunction 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 $2elif ["$1" == "-u" ] && [ -n "$2" ];then    umnt $1 $2else    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   rw,noatime                0   0

/dev/mmcblk0p1   /boot/uboot vfat   rw,user,umask=000         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



0 0