移植 Ubuntu 的最小根文件系统
硬件 正点原子的I.MX6ULL开发板
环境系统 (Ubuntu 16.04,搭建好TFTP目录和NFS目录)
EMMC启动 10100110
使用 mfgtool 上位机固化系统(OTG 方式) 01000000
以 ALPHA 底板为例,请先插上开发板的 12v 电源,OTG 接口不能供电给开发板。底板拨码开关 BOOT_CFG 设置如下,设置为 USB 连接方式,“1”代码 ON,“0”代表“OFF”。
将拨码数字 2 处拨到 ON,其他的为 OFF。
下载
下载地址http://cdimage.ubuntu.com/
最小系统(根文件系统)选择ubuntu-base
Ubuntu 针对不同的 CPU 架构提供相应的 ubuntu base 根文件系统,有 amd64(64 位 X86)、 armhf、 i386(32 位 X86)、 powerpc、 ppc64el 等系统的。
我用的I.MX6ULL 是 Cortex-A 内核的 CPU,并且有硬件浮点运算单元,因此选择 armhf 版本。
在http://cdimage.ubuntu.com/ubuntu-base/releases/16.04.5/release/中找到“ubuntu-base-16.04.5-base-armhf.tar.gz”,也就是 16.04.5 版本的 ubuntu base 根文件系统,将其下载下来。
ubuntu 根文件系统构建
搭建TFTP目录
-TFTP(Trivial File Transfer Protocol,简单文件传输协议)是 TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。我们可以使用 TFTP 来加载内核 zImage、设备树和其他较小的文件到开发板 DDR 上,从而实现网络挂载。
示例中~/tmp/tftp
目录为tftp目录有需要自行替换
~(用户目录为)/home/alientek
安装和配置 xinetd
安装
sudo apt-get install xinetd
查询/etc/下是否存在 xinetd.conf 文件,没有的话则自己新建一个。
sudo vi /etc/xinetd.conf
xinetd.conf 文件内容如下:
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
# Please note that you need a log_type line to be able to use log_on_success
# and log_on_failure. The default is the following :
# log_type = SYSLOG daemon info
}
includedir /etc/xinetd.d
TFTP 目录
新建 TFTP 目录,这里建立在 ~/tmp 目录下,目录名为 tftp。将 tftp 目录赋予
可读可写可执行权限。
创建
mkdir -p ~/tmp/tftp
赋予权限
sudo chmod ~/tmp/tftp
tftp-hpa 和 tftpd-hpa 服务程序
安装 tftp-hpa 和 tftpd-hpa 服务程序
sudo apt-get install tftp-hpa tftpd-hpa
打开 tftpd-hpa 配置文件
sudo vi /etc/default/tftpd-hpa
修改 tftp 目录为 TFTP 服务器工作目录
执行以下指令创建/etc/xinetd.d/tftp 配置文件。(如果没有 xinetd.d 这个目录,可以先自己手
动创建)
sudo vi /etc/xinetd.d/tftp
/etc/xinetd.d/tftp文件内容
注意 server_args = -s 后面要添加自己的 tftp 工作路径。
servicetftp
{
socket_type = dgram
wait = yes
disable = no
user = root
protocol = udp
server = /usr/sbin/in.tftpd
server_args = -s /home/alientek/tmp/tftp -c
#log_on_success += PID HOST DURATION
#log_on_failure += HOST
per_source = 11
cps =100 2
flags =IPv4
}
重启 tftpd-hpa 服务
sudo service tftpd-hpa restart
重启 xinetd 服务
sudo service xinetd restart
至此创建完成
搭建NFS目录
网络文件系统,英文 Network File System(NFS),是由 SUN 公司研制的 UNIX 表示层协议(presentation layer protocol),能使使用者访问网络上别处的文件就像在使用自己的计算机一样。我们可以在 Ubuntu 上制作开发板的根文件系统,然后使用 NFS 来加载根文件系统到开发板的DDR 上。
示例中~/tmp/nfs
目录为nfs目录有需要自行替换
~(用户目录为)/home/alientek
安装 NFS 服务
安装 NFS
sudo apt-get install nfs-kernel-server
NFS 共享目录
新建 NFS 共享目录,并给予 NFS 目录可读可写可执行权限。
sudo mkdir ~/tmp/nfs
sudo chmod 777 ~/tmp/nfs/
配置 NFS 服务
执行以下指令打开 etc/exports 文件
sudo vi /etc/exports
进入 etc/exports 文件,在最后添加如下内容
/home/alientek/tmp/nfs *(rw,sync,no_root_squash)
/home/alientek/tmp/nfs 表示 NFS 共享的目录
*表示允许所有的网络段访问
rw 表示访问者具有可读写权限
sync 表示将缓存写入设备中,可以说是同步缓存的意思
no_root_squash 表示访问者具有 root 权限。
重启 NFS 服务器
sudo /etc/init.d/nfs-kernel-server restart
查看 NFS 共享目录
showmount -e
如果输出正确则配置完成
解压缩 ubuntu base 根文件系统
为了存放 ubuntu base 根文件系统,先在 PC 的 Ubuntu 系统中的 nfs 目录下创建一个名为 ubuntu_rootfs 的目录,命令如下:
cd /home/alientek/tmp/nfs
mkdir ubuntu_rootfs
将“ubuntu-base-16.04.5-base-armhf.tar.gz”拷贝到上面创建的“rootfs”目录中,然后使用如下命令对其解压缩:
sudo tar -zxvf ubuntu-base-16.04.5-base-armhf.tar.gz
ubuntu base 解压以后就是大家最常见的 linux 根文件系统,但是目前还不能直接使用,还需要对其做一些其他的配置。
安装 qemu
需要在 PC 的 Ubuntu 上安装 qemu 工具,命令如下:
sudo apt-get install qemu-user-static
将刚刚安装的 qemu-user-static 拷贝到刚刚解压出来的 ubuntu base 目录中,也就是rootfs/usr/bin 目录下,命令如下:
cd /home/alientek/tmp/nfs/ubuntu_rootfs
sudo cp /usr/bin/qemu-arm-static ./usr/bin/
设置软件源
我们在 ubuntu 下使用 apt-get 安装软件的时候,是从网上下载软件并安装的,因此需要指定软件源。
在设置软件源之前先将 Ubuntu 主机下的 DNS 配置文件/etc/resolv.conf 拷贝到根文件系统中,命令如下:
(nameserver 223.6.6.6)
cd /home/alientek/tmp/nfs/ubuntu_rootfs
sudo cp /etc/resolv.conf ./etc/resolv.conf
设置软件源,打开根文件系统中的 ubuntu_rootfs/etc/apt/sources.list 文件,在此文件最后面添加软件源,比如国内常用的清华源、中科大源等等,这些软件源可以直接在网上查找。
cd /home/alientek/tmp/nfs/ubuntu_rootfs
vim ./etc/apt/sources.list
根据网上的推荐,我们使用如下所示的中科大软件源(这里非常感谢一位网名为“兔子”的网友提醒并测试):
#中科大源
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-backports main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-proposed main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-backports main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-proposed main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe
也可使用清华源:
清华源地址:https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/
arm需要使用 ubuntu-ports 镜像:(https://mirror.tuna.tsinghua.edu.cn/help/ubuntu-ports/)[https://mirror.tuna.tsinghua.edu.cn/help/ubuntu-ports/]
ubuntu16.04 的 ARM 源
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-updates main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-backports main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-backports main restricted universe multiverse
# deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-security main restricted universe multiverse
# # deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-security main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse
# deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-proposed main restricted universe multiverse
# # deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-proposed main restricted universe multiverse
ubuntu22.04 的 ARM 源
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse
# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse
在主机挂载并配置根文件系统
在主机挂载根文件系统
接下来将上面制作的根文件系统挂载到主机上,需要挂载 proc、sys、dev、dev/pts 等文件系统,最后使用 chroot 将主机的根文件系统切换到我们前面制作的根文件系统中。这里我们通过两个脚本文件来完成挂载和卸载操作,首先是挂载脚本 mount.sh,在rootfs 目录下创建一个名为 mount.sh 的 shell 脚本,然后在里面输入如下所示内容:
#!/bin/bash
echo "MOUNTING"
sudo mount -t proc /proc /home/alientek/tmp/nfs/ubuntu_rootfs/proc
sudo mount -t sysfs /sys /home/alientek/tmp/nfs/ubuntu_rootfs/sys
sudo mount -o bind /dev /home/alientek/tmp/nfs/ubuntu_rootfs/dev
sudo mount -o bind /dev/pts /home/alientek/tmp/nfs/ubuntu_rootfs/dev/pts
sudo chroot /home/alientek/tmp/nfs/ubuntu_rootfs
再编写一个卸载的脚本文件,新建名为 unmount.sh 的 shell 脚本,在里面输入如下所示内容:
#!/bin/bash
echo "UNMOUNTING"
sudo umount /home/alientek/tmp/nfs/ubuntu_rootfs/proc
sudo umount /home/alientek/tmp/nfs/ubuntu_rootfs/sys
sudo umount /home/alientek/tmp/nfs/ubuntu_rootfs/dev
sudo umount /home/alientek/tmp/nfs/ubuntu_rootfs/dev/pts
最后给予 mount.sh 和 unmount.sh 这两个 shell 脚本可执行权限,命令如下:
sudo chmod 777 mount.sh unmount.sh
一切准备就绪以后执行 mount.sh 脚本,将制作的根文件系统挂载到主机下,输入如下命令:
./mount.sh
安装常用的命令和软件
由于 ubuntu base 是一个最小根文件系统,很多命令和软件都没有,因此我们需要先安装一下常用的命令和软件,输入如下命令(注意!是在电脑的 Ubuntu 下输入这些命令,因为现在电脑的 Ubuntu 正挂载着我们移植的 Ubuntu-base 根文件系统):
更新列表
apt update
更新包(这一步可以忽略)
apt upgrade
安装1(1和2选一个就行)
apt install -y sudo vim kmod net-tools ethtool ifupdown language-pack-en-base rsyslog htop iputils-ping wget curl apt-transport-https
安装2(1和2选一个就行)
apt update
apt install sudo
apt install vim
apt install kmod
apt install net-tools
apt install ethtool
apt install ifupdown
apt install language-pack-en-base
apt install rsyslog
apt install htop
apt install iputils-ping
apt install wget
apt install curl
apt install apt-transport-https
我们就先安装这些命令和软件,保证 ubuntu base 根文件系统能够在开发板上正常启动即可,等启动以后再根据实际情况继续安装其他的命令和软件。
设置 root 用户密码
设置一下 root 用户的密码,这里我设置简单一点,root 用户密码也设置为“root”,相当于用户名和密码一样,命令如下:
passwd root
输入“passwd root”以后会让你输入 root 用户密码,输入两次
设置本机名称和 IP 地址
输入如下命令设置本机名称和 IP 地址:
echo "alientek_imx6ul" > /etc/hostname
echo "127.0.0.1 localhost" >> /etc/hosts
echo "127.0.0.1 alientek_imx6ul" >> /etc/hosts
设置串口终端
ubuntu 根文件系统在开发板上启动以后我们通常也希望串口终端正常工作,这里根据网友的介绍需要创建一个链接。首先确定自己所使用的串口设备文件,比如正点原子的 ALPHA 开发 板 使 用 的 UART1 对 应 的 串 口 设 备 文 件 为 ttymxc0 ,我们需要添加一个名为 getty@ttymxc0.service 的链接,链接到 getty@.service 服务上,输入如下命令:
ln -s /lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/getty@ttymxc0.service
设置好以后就可以退出根文件系统了,输入如下命令退出:
exit
退出以后再执行一下 unmount.sh 脚本取消挂载,命令如下:
./unmount.sh
至此,ubuntu base 根文件系统就已经制作好了,接下来就是挂载到开发板上去测试。
打包:
cd ubuntu_rootfs
tar -jcvf ubuntu_rootfs.tar.bz2 *
ubuntu 根文件系统测试
nfs 挂载测试
tftp和nfs都搭建完成后,在tftp中放入zImage和imx6ull-alientek-emmc.dtb;
并在开发板uboot中设置好tftp和nfs(bootargs和bootcmd)
首先设置开发板uboot的网络相关信息
I.MX6U-ALPHA 开发板有两个网口:ENET1 和 ENET2,一定要连接 ENET2(靠近com3口那一侧的),不能连接错了
环境变量 | 描述 |
---|---|
ipaddr | 开发板 ip 地址,可以不设置,使用 dhcp 命令来从路由器获取 IP 地址。 |
ethaddr | 开发板的 MAC 地址,一定要设置。 |
gatewayip | 网关地址。 |
netmask | 子网掩码。 |
serverip | 服务器 IP 地址,也就是 Ubuntu 主机 IP 地址,用于调试代码。 |
配置网络相关环境
setenv ipaddr 192.168.1.120
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.163
saveenv
也可使用dhcp指令从路由器获取ip键入dhcp
即可(路由器需要打开dhcp功能/开发板和电脑直连也不可以使用)。
注意,网络地址环境变量的设置要根据自己的实际情况,确保 Ubuntu 主机和开发板的 IP 地址在同一个网段内,比如我现在的开发板和电脑都在 192.168.1.0 这个网段内,所以设置开发板的 IP 地址为 192.168.1.120,我的 Ubuntu 主机的地址为 192.168.1.163,因此 serverip 就是 192.168.1.253。ethaddr 为网络 MAC 地址,是一个 48bit 的地址,如果在同一个网段内有多个开发板的话一定要保证每个开发板的 ethaddr 是不同的,否则通信会有问题!设置好网络相关的环境变量以后,使用ping命令测试以下是否可以正常访问Ubuntu主机
ping 192.168.1.163
如果提示host 192.168.1.163 is alive
则代表网络通讯正常
其次设置开发板tftp和nfs
根文件系统已经制作完成了,接下来就是测试
从网络启动 linux 系统的唯一目的就是为了调试!不管是为了调试 linux 系统还是 linux 下的驱动。每次修改 linux 系统文件或者 linux 下的某个驱动以后都要将其烧写到 EMMC 中去测试,这样太麻烦了。我们可以设置 linux 从网络启动,也就是将 linux 镜像文件和根文件系统都放到 Ubuntu 下某个指定的文件夹中,这样每次重新编译 linux 内核或者某个 linux 驱动以后只需要使用 cp 命令将其拷贝到这个指定的文件夹中即可,这样就不用需要频繁的烧写 EMMC,这样就加快了开发速度。我们可以通过 nfs 或者 tftp 从 Ubuntu 中下载 zImage 和设备树文件,根文件系统的话也可以通过 nfs 挂载。这里我们使用 tftp 从 Ubuntu 中下载 zImage 和设备树文件,前提是要将 zImage 和设备树文件放到 Ubuntu 下的 tftp 目录中。
- 搭建好tftp并且放入zImage和设备树文件(dtb文件),nfs目录是制作好的根文件系统
- 设置 bootargs 和 bootcmd 这两个环境变量
先用 tftp 从 Ubuntu 中下载 zImage 和设备树文件到开发板,再用 nfs 挂载根文件系统,在 uboot 里面设置 bootargs 和 bootcmd 环境变量的值如下:
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000'
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs \
nfsroot=192.168.1.163:/home/alientek/tmp/nfs/ubuntu_rootfs,proto=tcp rw \
ip=192.168.1.120:192.168.1.163:192.168.1.1:255.255.255.0::eth0:off'
saveenv
bootargs格式参考:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs \
nfsroot=虚拟机 IP 地址:文件系统路径,proto=tcp rw \
ip=开发板 IP 地址:虚拟机 IP 地址:网关:子网掩码::开发板网口:off'
saveenv
设置完成后,执行 boot 指令可以启动挂载。
boot
如果能ping通ip不能ping通域名,则可能是dns配置问题,检查两处:
查看这两个文件是否有
/etc/resolv.confnameserver 223.6.6.6
/etc/systemd/resolved.conf
DNS=223.6.6.6
(223.6.6.6是阿里公共dns,可以替换成自己的)。
如果没有添加上面的阿里公共dns,然后sudo /etc/init.d/networking restart
重启网卡即可。
ubuntu 根文件系统烧写
通过 nfs 挂载根文件系统测试成功,接下来就可以使用 MfgTool 将 ubuntu 根文件系统烧写到开发板上的 EMMC 或者 NAND 中,烧写方法我们已经在《第三十九章 系统烧写》章节做了详细的讲解(正点原子官方文档是在Windows下进行烧写,这里以Ubuntu下进行烧写为例)。
打包 ubuntu 根文件系统
首先打包 ubuntu 根文件系统,命令如下:
cd ubuntu_rootfs
sudo tar -jcvf ubuntu_rootfs.tar.bz2 *
打包完成以后就可以使用 MfgTool 工具将 ubuntu 根文件系统烧写到开发板的 EMMC 或NAND 中。
烧写 ubuntu 根文件系统
暂未挂在上,明天再试
[...]准备工作PC 机 Ubuntu 默认已经搭建好 TFTP 和 NFSTFTP 中放有 zImage 和 imx6ull-alientek-emmc.dtb(设备树文件)我这里 tftp 中放有 zImage 和 imx6ull-alientek-emmc.dtb (正点原子官方提供的,未做更改)两个文件NFS 中放有 rootfs (开发版的系统文件)本教程中是从 http://cdimage.u[...]