制作linux根文件系统
前言:
本文记录制作linux根文件系统的过程。
环境:ubuntu 20.04 server版,x86_64
1、编译busybox
1.1、获取busybox源码
可以从官网下载需要的版本:BusyBox
对版本无要求,可使用笔者上传gitee的版本:busybox-1.33.0: busybox源码 (gitee.com)
1.2、交叉编译busybox
使用menuconfig修改关注的配置,将.config另存为xxx_deconfig,下次编译直接使用。接着编译,笔者的环境可直接编译通过。
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- menuconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-
2、制作rootfs.img镜像
2.1、创建文件系统需要的一些目录。
mkdir bin dev etc home lib lib64 mnt proc sbin sys tmp usr usr/bin usr/sbin usr/lib usr/lib64 var -p
2.2、创建inittab并填充内容
inittab文件时init进程的配置文件,文件里的配置遵循如下格式:
label:runlevel:action:process
笔者查到的action有:
action | |
---|---|
sysinit | 系统初始化,只有系统开机或重新启动的时候,对应process才会被执行一次 |
respawn | 当process终止后马上启动一个新的 |
ctrlaltdel | 当用户按下ctrl+alt+del这个组合键的时候执行对应的process |
shutdown | 系统关闭时执行 |
可执行如下命令:
touch etc/inittab
cat > etc/inittab <<EOF
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
::respawn:-/bin/sh
# Start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
EOF
2.3、创建启动脚本rcS
mkdir etc/init.d/ -p
touch etc/init.d/rcS
cat > etc/init.d/rcS <<EOF
#!/bin/sh
#This is the first script called by init process
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
EOF
2.4、编辑fstab配置文件
fstab也是配置文件,记录了自动挂载的配置信息
touch etc/fstab
cat > etc/fstab <<EOF
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
EOF
2.5、编辑profile文件
profile也是配置文件,用于设置系统级的环境变量和启动程序,在这个文件下配置会对所有用户生效。当用户登录(login)时,文件会被执行。
touch etc/profile
cat >etc/profile <<EOF
#!/bin/sh
export HOSTNAME=rk3566
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
#export PS1="[\[\033[01;32m\]$USER@\[\033[00m\]\[\033[01;34m\]$HOSTNAME\[\033[00m\ \W]\$ "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
EOF
2.6、拷贝动态库
从编译工具链处拷贝动态库到根文件系统,并strip。
#拷贝库路径
SYSROOT=$(${CROSS_COMPILE}gcc -print-sysroot)
cp -rf ${SYSROOT}/lib/*.so* ${ROOMFS_DIR}/lib/
cp -rf ${SYSROOT}/lib64/*.so* ${ROOMFS_DIR}/lib64/
cp -rf ${SYSROOT}/usr/lib/*.so* ${ROOMFS_DIR}/usr/lib/
cp -rf ${SYSROOT}/usr/lib64/*.so* ${ROOMFS_DIR}/usr/lib64/
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib64/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/usr/lib64/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib/*
2.7、安装busybox
cd ${BUSYBOX_DIR}
make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} install CONFIG_PREFIX=${ROOMFS_DIR}
cd ${ROOMFS_DIR}
在编译完成的busybox根目录下执行install命令,会将busybox安装到根文件系统中,并创建支持命令的软连接,这样根文件系统中的命令和init进程就都有了。
2.8、制作根文件系统镜像
dd if=/dev/zero of=${ROOMFS_IMG} bs=1M count=${ROOMFS_SIZE}
${MAKE_FS_TOOL} ${ROOMFS_IMG}
mkdir ../tempfs
sudo mount ${ROOMFS_IMG} ../tempfs
sudo cp -rfp ${ROOMFS_DIR}/* ../tempfs/
sudo umount ../tempfs
rm -rf ../tempfs
e2fsck -p -f ${ROOMFS_IMG}
resize2fs -M ${ROOMFS_IMG}
- 用dd命令得到空镜像,
- 用文件系统制作工具(笔者使用的ext4文件系统,所以这里用的工具是mkfs.ext4)将文件系统安装到镜像里
- 将空的文件系统镜像挂在到空目录
- 将上文制作好的根文件系统拷贝到镜像里
- 对新制作的根文件系统镜像进行盘检
- 调整根文件系统的大小
附录:
第二章所有步骤可通过如下脚本完成。所以总的来说制作根文件系统镜像就两步,一是编译busybox,二是执行mkromfs.sh脚本
#!/bin/sh
ROOMFS_DIR=/home/nx666/codes/tspi_pack/image/romfs
BUSYBOX_DIR=/home/nx666/codes/busybox-1.33.0
CROSS_COMPILE=aarch64-none-linux-gnu-
ARCH=arm64
ROOMFS_IMG=/home/nx666/codes/tspi_pack/image/rootfs.img
ROOMFS_SIZE=128 # -M
MAKE_FS_TOOL=mkfs.ext4
HOSTNAME=rk3566
USER=root
HOME=root
rm -rf ${ROOMFS_DIR}/*
cd ${ROOMFS_DIR}
mkdir bin dev etc home lib lib64 mnt proc sbin sys tmp usr usr/bin usr/sbin usr/lib usr/lib64 var -p
touch etc/inittab
cat > etc/inittab <<EOF
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
::respawn:-/bin/sh
# Start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
EOF
mkdir etc/init.d/ -p
touch etc/init.d/rcS
cat > etc/init.d/rcS <<EOF
#!/bin/sh
#This is the first script called by init process
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
EOF
touch etc/fstab
cat > etc/fstab <<EOF
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
EOF
touch etc/profile
cat >etc/profile <<EOF
#!/bin/sh
export HOSTNAME=rk3566
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
#export PS1="[\[\033[01;32m\]$USER@\[\033[00m\]\[\033[01;34m\]$HOSTNAME\[\033[00m\ \W]\$ "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
EOF
#添加权限
chmod 777 etc/*
chmod 777 etc/init.d/*
#拷贝库路径
SYSROOT=$(${CROSS_COMPILE}gcc -print-sysroot)
cp -rf ${SYSROOT}/lib/*.so* ${ROOMFS_DIR}/lib/
cp -rf ${SYSROOT}/lib64/*.so* ${ROOMFS_DIR}/lib64/
cp -rf ${SYSROOT}/usr/lib/*.so* ${ROOMFS_DIR}/usr/lib/
cp -rf ${SYSROOT}/usr/lib64/*.so* ${ROOMFS_DIR}/usr/lib64/
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib64/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/usr/lib64/*
${CROSS_COMPILE}strip ${ROOMFS_DIR}/lib/*
#安装busybox , buysbox需先编译完成
cd ${BUSYBOX_DIR}
make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} install CONFIG_PREFIX=${ROOMFS_DIR}
cd ${ROOMFS_DIR}
#制作根文件系统镜像
dd if=/dev/zero of=${ROOMFS_IMG} bs=1M count=${ROOMFS_SIZE}
${MAKE_FS_TOOL} ${ROOMFS_IMG}
mkdir ../tempfs
sudo mount ${ROOMFS_IMG} ../tempfs
sudo cp -rfp ${ROOMFS_DIR}/* ../tempfs/
sudo umount ../tempfs
rm -rf ../tempfs
e2fsck -p -f ${ROOMFS_IMG}
resize2fs -M ${ROOMFS_IMG}