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

0 背景

有一个很厉害的师兄针对我们实验室的需求设计了一块控制板,以beaglebone为基础,由于更改了一些底层的硬件,所以重新定制编译的内核,并预先烧写到了板子的flash中。现在需要安装ubuntu的文件系统,以使用ROS的相关功能函数库。前一段时间我在beaglebone官网下载了其提供的预编译好的根文件系统,修改挂载设置fstab文件后顺利启动,但是不能支持图形界面,不知是内核支持的原因还是文件系统的原因。前面琢磨了如何编译适用于ARM架构的内核(编译适用于ARM的linux内核并进行QEMU仿真),为了今后在需要时按自己的意愿修改文件系统,最近两天一直在研究如何定制自己的根文件系统,参考了几篇经验帖,结合自己的实践,特记录于此。

定制适用于ARM平台的Ubuntu rootfs(根文件系统)_第1张图片


                                                                          图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  
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(嵌入式系统设计,liunx相关)