13. 构建基础根文件系统¶
借助SDK我们可以方便的一键构建Debian/Ubuntu镜像,构建基础文件系统的SDK脚本路径为:ebf-image-builder/scripts/debootstrap.sh
以下将讲解该脚本是如何构建文件系统的。
debootstrap.sh脚本使用了debootstrap工具来下载和安装所需的软件包,并创建一个基本的文件系统。
实现步骤操作如下:
1、设置必要的变量:
deb_arch:指定系统架构(如x86_64、armhf等)
deb_include:指定要包含的软件包列表
deb_exclude:指定要排除的软件包列表
deb_components:指定要包含的组件列表
deb_variant:指定使用的debootstrap变体(可选)
deb_distribution:指定发行版(debian或ubuntu)
deb_codename:指定发行版代号(如bionic、focal等)
tempdir:指定临时目录用于存储文件系统
2、设置APT代理(可选):
apt_proxy:指定APT代理(如果有)
3、设置镜像源:
deb_mirror:指定镜像源地址(默认为官方源)
4、运行debootstrap命令:
sudo debootstrap –no-merged-usr ${options} ${suite} “${target}” ${mirror}
此命令将在${target}目录中创建一个基本的Ubuntu文件系统,使用${mirror}指定的镜像源进行下载。
5、输出文件系统大小报告:
脚本会通过执行report_size函数来报告${target}目录的大小。
debootstrap.sh脚本内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | DIR=$PWD
. "${DIR}/.project"
check_defines () {
#http://linux.die.net/man/8/debootstrap
unset options
if [ ! "${deb_arch}" ] ; then
echo "scripts/deboostrap_first_stage.sh: Error: deb_arch undefined"
exit 1
else
options="--arch=${deb_arch}"
fi
if [ "${deb_include}" ] ; then
include=$(echo ${deb_include} | sed 's/ /,/g' | sed 's/\t/,/g')
#board_include=$(echo ${board_deb_include} | sed 's/ /,/g' | sed 's/\t/,/g')
options="${options} --include=${include},${board_include}"
fi
if [ "${deb_exclude}" ] ; then
exclude=$(echo ${deb_exclude} | sed 's/ /,/g' | sed 's/\t/,/g')
options="${options} --exclude=${exclude}"
fi
if [ "${deb_components}" ] ; then
components=$(echo ${deb_components} | sed 's/ /,/g' | sed 's/\t/,/g')
options="${options} --components=${components}"
fi
#http://linux.die.net/man/8/debootstrap
if [ "${deb_variant}" ] ; then
#--variant=minbase|buildd|fakechroot|scratchbox
options="${options} --variant=${deb_variant}"
fi
if [ ! "${deb_distribution}" ] ; then
echo "scripts/deboostrap_first_stage.sh: Error: deb_distribution undefined"
exit 1
fi
unset suite
if [ ! "${deb_codename}" ] ; then
echo "scripts/deboostrap_first_stage.sh: Error: deb_codename undefined"
exit 1
else
suite="${deb_codename}"
fi
case "${deb_distribution}" in
debian)
if [ ! -f /usr/share/debootstrap/scripts/${suite} ] ; then
sudo ln -s /usr/share/debootstrap/scripts/sid /usr/share/debootstrap/scripts/${suite}
fi
if [ ! -f /usr/share/keyrings/debian-archive-keyring.gpg ] ; then
options="${options} --no-check-gpg"
fi
;;
ubuntu)
if [ ! -f /usr/share/debootstrap/scripts/${suite} ] ; then
sudo ln -s /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/${suite}
fi
if [ ! -f /usr/share/keyrings/ubuntu-archive-keyring.gpg ] ; then
options="${options} --no-check-gpg"
fi
;;
esac
options="${options} --foreign"
unset target
if [ ! "${tempdir}" ] ; then
echo "scripts/deboostrap_first_stage.sh: Error: tempdir undefined"
exit 1
else
target="${tempdir}"
fi
unset mirror
if [ ! "${apt_proxy}" ] ; then
apt_proxy=""
fi
if [ ! "${deb_mirror}" ] ; then
case "${deb_distribution}" in
debian)
deb_mirror="deb.debian.org/debian"
;;
ubuntu)
deb_mirror="ports.ubuntu.com/"
;;
esac
fi
mirror="http://${apt_proxy}${deb_mirror}"
}
report_size () {
echo "Log: Size of: [${tempdir}]: $(du -sh ${tempdir} 2>/dev/null | awk '{print $1}')"
}
check_defines
echo "Log: Creating: [${deb_distribution}] [${deb_codename}] image for: [${deb_arch}]"
if [ "${apt_proxy}" ] ; then
echo "Log: using apt proxy: [${apt_proxy}]"
fi
echo "Log: Running: debootstrap in [${tempdir}]"
###FIXME: --no-merged-usr eventually we will support, but as of 1.0.101+ it's back, so default to pre...
echo "Log: [sudo debootstrap --no-merged-usr ${options} ${suite} ${target} ${mirror}]"
sudo debootstrap --no-merged-usr ${options} ${suite} "${target}" ${mirror}
report_size
#
|
第9到14行,deb_arch指定系统架构,deb_arch定义在ebf-image-builder/configs/boards/ebf_stm_mp157_star.conf
1 | deb_arch="armhf"
|
第16到20行,deb_include指定要包含的软件包列表,deb_include定义在ebf-image-builder/configs/common.conf
1 2 3 4 5 6 | deb_include="apt-transport-https ca-certificates connman curl dosfstools\
gnupg gnupg2 ifupdown initramfs-tools isc-dhcp-client nano \
net-tools netcat rsync sudo udhcpd parted mtd-utils mmc-utils\
rng-tools haveged wpasupplicant udhcpc openssh-server avahi-daemon\
gpiod kpartx jq libgpiod-dev rfkill usbutils exfat-fuse exfat-utils \
ssh alsa-utils"
|
第22到25行,deb_exclude指定要排除的软件包列表,deb_exclude定义在ebf-image-builder/configs/common.conf
1 2 | deb_exclude="aptitude aptitude-common groff-base info install-info man-db manpages\
manpages-dev tasksel tasksel-data"
|
第27到30行,deb_components指定要包含的组件列表,deb_components定义在ebf-image-builder/configs/common.conf
1 | deb_components="main universe multiverse"
|
第33到36行,deb_variant指定使用的debootstrap变体(可选),SDK中没有定义deb_variant
第38到40行,deb_distribution指定发行版(debian或ubuntu),定义在ebf-image-builder/configs/common.conf
1 2 3 4 5 | #debian
deb_distribution="lubancat"
#ubuntu
deb_distribution="ubuntu"
|
第44到49行,deb_codename指定发行版代号(如bionic、focal等),定义在ebf-image-builder/configs/common.conf
1 2 3 4 5 6 7 8 | deb_codename=$DISTRIB_RELEASE
...
if [[ $DISTRIB_RELEASE == bionic ]]; then
...
release="18.04"
...
if [[ $DISTRIB_RELEASE == focal ]]; then
release="20.04"
|
第51到69行,根据${deb_distribution}是Debian还是ubuntu,脚本会检查是否存在${suite}版本的debootstrap脚本,也就是前面的deb_codename发行版本。如果不存在,则会创建一个符号链接,Debian指向Sid版本,Sid是Debian不稳定版,Ubuntu指向gutsy版本,Ubuntu 7.10,然后脚本会检查是否存在ubuntu-archive-keyring.gpg密钥文件,如果不存在,则会将–no-check-gpg选项添加到${options}中。最后,脚本会将–foreign选项添加到${options}中,指示debootstrap创建一个基本系统,而不是完整的系统。
第71到77行,指定临时目录用于存储文件系统。
第79到82行,apt_proxy指定APT代理,SDK没有指定。
第83到93行,指定镜像源地址(默认为官方源)
第96到98行,通过执行report_size函数来报告${target}目录的大小。
第133行,运行debootstrap命令,将在${target}目录中创建一个基本的文件系统,使用${mirror}指定的镜像源进行下载。
以上,除了文件系统的发行版本,我们比较关心的是文件系统预安装了哪些软件包,定义在deb_include变量中,如果读者需要修改安装的软件包,修改common.conf文件中的deb_include变量即可。
可见,此构建文件系统的脚本十分依赖SDK中其他配置文件,建议完整构建系统镜像从而构建文件系统。