Skip to main content

按需制定文件系统

一键编译ubuntu22.04文件系统镜像

1 安装依赖软件

#安装依赖软件
sudo apt-get install git ssh make gcc libssl-dev liblz4-tool expect g++ patchelf chrpath gawk texinfo chrpath diffstat binfmt-support qemu-user-static live-build bison flex fakeroot cmake gcc-multilib g++-multilib unzip device-tree-compiler ncurses-dev python-is-python3 python-dev-is-python3 -y

2 解压根文件系统

可在SDK中直接运行build_ubuntu.sh脚本 可直接将ubuntu22.04文件系统编译完成,如果需要自行编辑内核模块请参照2.8安装开发板驱动进行内容的修改

tip

完成此步骤后即可编译成功,无需进行对ubuntu文件系统进行手动编译中的内容。

对ubuntu文件系统进行手动编译

tip

此内容为开发者准备,如需自行定制文件系统,请按需对以下内容进行修改编译。

1 环境准备

1.1 下载ubuntu base

此处使用北京外国语大学镜像站加速下载,注意选择根据开发板架构选择arm64或其他架构。

wget https://mirrors.bfsu.edu.cn/ubuntu-cdimage/ubuntu-base/releases/22.04.2/release/ubuntu-base-22.04.2-base-arm64.tar.gz

1.2 安装依赖软件

#安装依赖软件
sudo apt-get install git ssh make gcc libssl-dev liblz4-tool expect g++ patchelf chrpath gawk texinfo chrpath diffstat binfmt-support qemu-user-static live-build bison flex fakeroot cmake gcc-multilib g++-multilib unzip device-tree-compiler ncurses-dev python-is-python3 python-dev-is-python3 -y

1.3 解压根文件系统

# 创建一个文件夹存放根文件系统
mkdir ubuntu_rootfs
# 解压到文件夹
sudo tar -xvf ubuntu-base-22.04-base-arm64.tar.gz -C ubuntu_rootfs/

1.4 配置根文件系统

1.配置根文件系统的网络、软件源等

# 配置网络,复制本机 resolv.conf 文件
sudo cp /etc/resolv.conf <SDK>/ubuntu_rootfs/etc/resolv.conf
sudo echo "nameserver 8.8.8.8" >> <SDK>/ubuntu_rootfs/etc/resolv.conf
sudo echo "nameserver 114.114.114.114" >> <SDK>/ubuntu_rootfs/etc/resolv.conf

2.更换软件源,此处选择北京外国语大学镜像站

# 编辑根文件系统中的软件源配置文件
sudo vim <SDK>/ubuntu_rootfs/etc/apt/sources.list

以下是Ubuntu 22.04 版本的镜像,请注意删除根文件系统 <SDK>/ubuntu_rootfs/etc/apt/sources.list 文件中原有的内容。

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
deb http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
deb http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse

# deb http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse
# # deb-src http://mirrors.bfsu.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 http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse
# # deb-src http://mirrors.bfsu.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse

3.配置仿真开发板运行环境

X86 架构下的Ubuntu 系统默认不支持Arm架构,可以通过安装 qemu-user-static 实现仿真运行,从而构建 ubuntu 文件系统。

# 拷贝 qemu-aarch64-static 到 ubuntu_rootfs/usr/bin/ 目录下。
sudo cp /usr/bin/qemu-aarch64-static <SDK>/ubuntu_rootfs/usr/bin/

1.5 挂载根文件系统

首先编写挂载脚本 mount.sh,用于挂载根文件系统运行所需要的设备和目录。

#!/bin/bash
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}
}
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 both parameters were missing"
echo ""
echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
echo ""
echo "For example: ch-mount -m /media/sdcard/"
echo ""
echo 1st parameter : ${1}
echo 2nd parameter : ${2}
fi

保存退出后给脚本增加执行权限,并挂载

# 增加脚本执行权限
sudo chmod +x mount.sh
# 挂载文件系统
./mount.sh -m ubuntu_rootfs/
# 进入根文件系统
sudo chroot ubuntu_rootfs/
warning
danger

不得在未卸载文件系统时再次挂载文件系统,会导致虚拟环境崩溃!!!

在后续完成根文件系统构建,并退出后,必须卸载文件系统,否则后续在构造镜像时会报错!!!

# 卸载文件系统
./mount.sh -u ubuntu_rootfs/

2 构建根文件系统

+++

2.1 为根文件系统安装必要软件

此处请确保你构建根文件系统的环境有网络连接

# 更新软件
apt update
apt upgrade -y
mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/
mkdir /var/lib/dpkg/info
apt-get update
apt-get install
# 必要工具
apt install vim bash-completion net-tools iputils-ping ifupdown ethtool ssh rsync udev htop rsyslog curl openssh-server apt-utils dialog nfs-common psmisc language-pack-en-base sudo kmod apt-transport-https gcc g++ make cmake fdisk -y

以下内容可选择安装

# 开发工具
apt install ninja-build build-essential ffmpeg libopencv-dev libv4l-dev v4l-utils yavta -y

2.2 修改root用户密码,添加新用户

# 修改 root 密码
passwd root
# 添加新用户并设置密码
adduser myt

修改/etc/sudoers文件,用于控制哪些用户可以以超级管理员身份使用root权限进行命令

# 编辑 /etc/sudoers 
vim /etc/sudoers

添加以下内容

myt      ALL=(ALL:ALL) ALL

2.3 设置主机名和主机解析

# 主机名
echo "RK3588" > /etc/hostname
# 主机 IP
echo "127.0.0.1 localhost" >> /etc/hosts
echo "127.0.0.1 RK3588" >> /etc/hosts
echo "127.0.0.1 localhost RK3588" >> /etc/hosts

2.4 配置网卡

#下载network-manager
apt-get install network-manager

在安装 network-manager时需要选择时区,请根据需要自动选择

ubuntu22.04.2.4.png

Network-Manager 服务会自动配置网卡,但是其默认配置文件将 Ethernet 加入了黑名单,会导致 Ubuntu 提示 unmanned。

# 编辑文件
vim /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
# 文件内容修改为
[keyfile]
unmanaged-devices=*,except:type:ethernet,except:type:wifi,except:type:gsm,except:type:cdma

RK3588开发板有两块网卡,因此将两块网卡默认配置为自动DHCP获取。

# 网卡0
echo "auto eth0" > /etc/network/interfaces.d/eth0
echo "iface eth0 inet dhcp" >> /etc/network/interfaces.d/eth0
# 网卡1
echo "auto eth1" > /etc/network/interfaces.d/eth1
echo "iface eth1 inet dhcp" >> /etc/network/interfaces.d/eth1

在实际测试中网口必须接入网线系统才能正常启动,就是在不联网的情况下,每次开机都要等待很久,卡在网络连接上5分钟。

修改下面这个文件
vim /lib/systemd/system/networking.service

将里面的TimeoutStartSec=5min 修改为:

TimeoutStartSec=5sec

2.5 禁用系统休眠

# 设置禁止休眠
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
# 查看休眠状态
systemctl status sleep.target

2.6 修改ssh配置文件

1.配置ssh_config

$ sudo vim /etc/ssh/ssh_config				
# 去掉PasswordAuthentication yes前面的"#"号

ubuntu22.04.2.4.png

2.配置sshd_config

$ sudo vim /etc/ssh/sshd_config	

# 在PermitRootLogin prohibit-password这行行首加上"#"
# 在此行下面添加新一行
PermitRootLogin yes

ubuntu22.04.2.6.2.png

2.7设置开机自动扩容根目录

/usr/local/bin目录下创建autoexpand.sh脚本

vim autoexpand.sh

脚本内容如下

#!/bin/bash

ROOT_PARTITION=$(lsblk | grep "/$" | awk '{print $1}'| sed 's/^..//')
DEVICE=${ROOT_PARTITION%p*}
ROOT_DIR=/dev/${ROOT_PARTITION}
NUM="${ROOT_PARTITION: -1}"

echo -e "\n" | parted /dev/${DEVICE} resizepart ${NUM}
echo -e "\n" | resize2fs ${ROOT_DIR}

echo '扩容根目录已完成'

给予脚本可执行权限

sudo chmod +x autoexpand.sh

创建systemd服务

/ect/systemd/system/下创建autoexpand.service

内容如下

[Unit]
Description=Run My Script Once at Boot

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'if [ ! -f /tmp/auto_expand_done ]; then /usr/local/bin/autoexpand.sh; touch /tmp/auto_expand_done; fi'

[Install]
WantedBy=multi-user.target

启用此服务

sudo systemctl enable autoexpand.service

在烧录后,根目录将自动扩容到最大

2.8安装开发板驱动

在SDK目录下运行./build.sh menuconfig

打开Kernel(Kernel (Embedded in an Android-style boot image)

defconfig fragments 中添加rockchip_linux_docker.config

ubuntu22.04.2.8.png

将自己所需的驱动或内核模块在kernel中修改<SDK>/kernel/arch/arm64/configs目录下的

rockchip_linux_deconfig或者rockchip_linux_docker.config

修改完成后编译kernel来获取驱动模块

# 在SDK根目录下执行命令,生成驱动文件
./build.sh kernel

所编译的模块在<SDK>/output/kernel-modules/lib目录下将此modlues目录复制到<SDK>/ubuntu_roofs/lib

cp -r <SDK>/output/kernel-modules/lib/modlues <SDK>/ubuntu_roofs/lib

3 打包根文件系统镜像

3.1打包镜像

使用SDK目录下mk-image.sh脚本打包

# 打包
sudo ./mk-image.sh

mk-image.sh脚本内容如下

#!/bin/bash -e # 使用bash解释器,并开启错误检查模式

TARGET_ROOTFS_DIR=./ubuntu_rootfs # 定义目标根文件系统目录路径
ROOTFSIMAGE=ubuntu-rootfs.img # 定义根文件系统镜像文件名
EXTRA_SIZE_MB=300 # 定义额外的磁盘空间大小
IMAGE_SIZE_MB=$(( $(sudo du -sh -m ${TARGET_ROOTFS_DIR} | cut -f1) + ${EXTRA_SIZE_MB} )) # 计算根文件系统镜像文件大小

echo Making rootfs! # 输出提示信息

if [ -e ${ROOTFSIMAGE} ]; then # 如果根文件系统镜像文件已经存在,则删除
rm ${ROOTFSIMAGE}
fi

dd if=/dev/zero of=${ROOTFSIMAGE} bs=1M count=0 seek=${IMAGE_SIZE_MB} # 创建指定大小的空白镜像文件

sudo mkfs.ext4 -d ${TARGET_ROOTFS_DIR} ${ROOTFSIMAGE} # 在指定目录下创建ext4文件系统,并将其写入到镜像文件中

echo Rootfs Image: ${ROOTFSIMAGE} # 输出根文件系统镜像文件名

3.2 烧录镜像

打包镜像完成后,会生成 ubuntu-rootfs.img 文件,使用该文件烧录进开发板即可。

按需修改parameter文件,来修改rootfs的地址和大小(此处修改rootfs的大小不可小于 ubuntu-rootfs.img 文件大小)

FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: RK3588
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
GROW_ALIGN: 0
CMDLINE:mtdparts=:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00b00000@0x00078000(rootfs),0x00040000@0x00b78000(oem),-@0x00e80000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
uuid:boot=7A3F0000-0000-446A-8000-702F00006273