下载源码
根文件系统是根据busybox来制作的,下载地址:Index of /downloads,这里使用的是1.36.0版本。
注意:一般你使用什么版本的交叉编译器来编译linux内核时,文件系统中的所有程序也要使用同样的交叉编译器来编译。
下载完成后解压:
mkdir rootfs
cd rootfs
wget https://busybox.net/downloads/busybox-1.36.0.tar.bz2
tar -jxf busybox-1.36.0.tar.bz2
配置busybox
cd busybox-1.36.0/
make defconfig
make menuconfig
进入Busybox Settings,配置如下参数:
Settings --->
(/usr/local/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-linux-gnu-) Cross compiler prefix
( -march=armv8-a) additional CFLAGS
[ ] Build static binary (no shared libs) // 禁止使用静态编译
[*] Build Shared libbusybox
Linux System Utilities --->
[] nsenter
Coreutils --->
[] sync
Miscellaneous Utilities --->
自己选择
Networking Utilities --->
[*] Support /etc/networks
[*] udhcpc (24 kb)
[*] Verify that the offered address is free, using ARP ping
[*] Do not pass malformed host and domain names
(/usr/share/udhcpc/default.script) Absolute path to config script
(/usr/share/udhcpc/default6.script) Absolute path to config script for IPv6
Linux System Utilities --->
[*] mdev (17 kb)
[*] hexdump
Linux Module Utilities --->
[*] depmod (27 kb)
[*] Support module.aliases file
[*] Support module.symbols file
(/lib/modules) Default directory containing modules
(modules.dep) Default name of modules.dep
编译安装
make
然后查看当前路径下是否存在busybox
:
ll busybox
执行make install
make install
make install
的目的就是将编译生成的可执行程序及其依赖的库文件、配置文件、头文件安装到当前系统中指定(一般都可以自己指定安装到哪个目录下,如果不指定一般都有个默认目录)的目录下,默认被安装到_install
目录下:
ll _install/
total 92
drwxr-xr-x 6 root root 4096 9月 25 14:30 ./
drwxr-xr-x 38 root root 4096 9月 25 14:30 ../
drwxr-xr-x 2 root root 4096 9月 25 14:30 bin/
drwxr-xr-x 2 root root 4096 9月 25 14:30 lib64/
-rwxr-xr-x 1 root root 67392 9月 25 14:28 linuxrc*
drwxr-xr-x 2 root root 4096 9月 25 14:30 sbin/
drwxr-xr-x 4 root root 4096 9月 25 14:30 usr/
里面有5个文件:bin
、sbin
、usr
这三个目录里都是二进制命令工具,lib64
里面是库文件,这还不足以构成 一个可用的根文件系统,必须进行其它完善工作,才能构建一个可用的根文件系统。
构建根文件系统
新建一个目录用来存放制作的根文件系统,可以命名为busybox_install
。将利用busybox
生成的二进制文件及目录,即_install
目录下的所有文件及目录复制到busybox_install
目录下
mkdir …/busybox_install
cp -a _install/* …/busybox_install/
添加库文件
cd …/busybox_install
mkdir lib
找到交叉编译工具里的动态库复制到lib
目录下:
cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/lib/*so* ./lib/
cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/lib64/*so* ./lib64/
cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/usr/lib/*so* ./lib/
cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/usr/lib64/*so* ./lib64/
-a
表示保留权限,复制软链接本身,递归复制。
查看库文件:
ls ./lib
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install# ls ./lib
ld-linux-aarch64.so.1 libinproctrace.so
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install# ls ./lib64/
libanl.so libcrypt.so.1 libhwasan.so.0.0.0 libnss_db.so.2 libstdc++.so.6.0.30-gdb.py
libanl.so.1 libc.so libitm.so libnss_dns.so.2 libthread_db.so
libasan.so libc.so.6 libitm.so.1 libnss_files.so.2 libthread_db.so.1
libasan.so.8 libdl.so.2 libitm.so.1.0.0 libnss_hesiod.so libtsan.so
libasan.so.8.0.0 libgcc_s.so liblsan.so libnss_hesiod.so.2 libtsan.so.2
libatomic.so libgcc_s.so.1 liblsan.so.0 libpcprofile.so libtsan.so.2.0.0
libatomic.so.1 libgfortran.so liblsan.so.0.0.0 libpthread.so.0 libubsan.so
libatomic.so.1.2.0 libgfortran.so.5 libmemusage.so libresolv.a libubsan.so.1
libBrokenLocale.so libgfortran.so.5.0.0 libm.so libresolv.so libubsan.so.1.0.0
libBrokenLocale.so.1 libgomp.so libm.so.6 libresolv.so.2 libutil.so.1
libbusybox.so.1.36.0 libgomp.so.1 libnsl.so.1 librt.so.1
libc_malloc_debug.so libgomp.so.1.0.0 libnss_compat.so libstdc++.so
libc_malloc_debug.so.0 libhwasan.so libnss_compat.so.2 libstdc++.so.6
libcrypt.so libhwasan.so.0 libnss_db.so libstdc++.so.6.0.30
这里只是拷贝动态链接库。一般开发程序使用动态编译需要板子上动态库的支持才能运行,所以拷贝动态库。
构建etc目录
初始化配置脚本放在在/etc
目录下,用于系统启动所需的初始化配置脚本。
busybox
提供了一些初始化范例脚本,在examples/bootfloppy/etc/
目录下:
cd busybox-1.36.0/
ll examples/bootfloppy/etc/
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox-1.36.0# ll examples/bootfloppy/etc/
total 24
drwxr-xr-x 3 root root 4096 1月 3 2023 ./
drwxr-xr-x 3 root root 4096 1月 3 2023 ../
-rw-r--r-- 1 root root 33 1月 3 2023 fstab
drwxr-xr-x 2 root root 4096 1月 3 2023 init.d/
-rw-r--r-- 1 root root 100 1月 3 2023 inittab
-rw-r--r-- 1 root root 133 1月 3 2023 profile
在busybox_install
目录,创建etc
文件夹:
cd ../
cd busybox_install
mkdir etc
将这些配置文件复制到新制作的根文件系统etc
目录下。
cp -a ../busybox-1.36.0/examples/bootfloppy/etc/* ./etc
ll etc
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install# ls etc/
fstab init.d inittab profile
修改etc/inittab
文件
etc/inittab
文件是init
进程解析的配置文件,通过这个配置文件决定执行哪个进程,何时执行
将文件修改为:
# 系统启动时
::sysinit:/etc/init.d/rcS
# 系统启动按下Enter键时
::askfirst:-/bin/sh
# 按下Ctrl+Alt+Del键时
::ctrlaltdel:/sbin/reboot
# 系统关机时
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
# 系统重启时
::restart:/sbin/init
以上内容定义了系统启动时,关机时,重启时,按下Ctrl+Alt+Del
键时执行的进程。
修改etc/fstab
etc/fstab
文件存放的是文件系统信息。在系统启动后执行/etc/init.d/rcS
文件里/bin/mount -a
命令时,自动挂载这些文件系统。
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
这里我们挂载的文件系统有三个proc
、sysfs
和tmpfs
,在内核中proc
和sysfs
默认都支持,而tmpfs
是没有支持的,我们需要添加tmpfs
的支持。
修改etc/profile
文件(环境变量)
etc/profile
文件作用是设置环境变量,每个用户登录时都会运行它,将文件内容修改为:
# 主机名
export HOSTNAME=NanoPC-T4 # NanoPC-T6
# 用户名
export USER=root
# 用户目录
export HOME=/root
# 终端默认提示符
export PS1="[$USER@$HOSTNAME:\$PWD]\# "
# 环境变量
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# 动态库路径
export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
新建 S40network
需要创建etc/init.d/S40network
文件:
#!/bin/sh
#
# Start the network....
#
# Debian ifupdown needs the /run/network lock directory
mkdir -p /run/network
case "$1" in
start)
printf "Starting network: "
/sbin/ifup -a
[ $? = 0 ] && echo "OK" || echo "FAIL"
;;
stop)
printf "Stopping network: "
/sbin/ifdown -a
[ $? = 0 ] && echo "OK" || echo "FAIL"
;;
restart|reload)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
udhcpc
配置
拷贝文件simple.script
到根文件系统的/usr/share/udhcpc/
目录下,更名为default.script
;
mkdir -p ./usr/share/udhcpc
cp ../busybox-1.36.0/examples/udhcp/simple.script ./usr/share/udhcpc
mv ./usr/share/udhcpc/simple.script ./usr/share/udhcpc/default.script
再将default.script
中RESOLV_CONF=”/etc/resolv.conf”
更改为RESOLV_CONF=”/tmp/resolv.conf”
;
vim ./usr/share/udhcpc/default.script
RESOLV_CONF="/tmp/resolv.conf"
......
我们配置一下网络DHCP
,这样系统启动以后就会自动设置好网络;
mkdir -p etc/network/interfaces.d
vim etc/network/interfaces
# interface file auto-generated by buildroot
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
mkdir etc/network/if-down.d
vim etc/network/if-down.d/dhcp-down.sh
#!/bin/sh
# This file is executed by ifupdown in pre-up, post-up, pre-down and
# post-down phases of network interface configuration.
# run this script only for interfaces which have dhcp-down option
[ -z "$IF_DHCP_DOWN" ] && exit 0
$IF_DHCP_DOWN $IFACE
exit 0
mkdir etc/network/if-up.d
vim etc/network/if-up.d/dhcp-up.sh
#!/bin/sh
# This file is executed by ifupdown in pre-up, post-up, pre-down and
# post-down phases of network interface configuration.
# run this script only for interfaces which have dhcp-up option
[ -z "$IF_DHCP_UP" ] && exit 0
$IF_DHCP_UP $IFACE&
exit 0
修改etc/init.d/rcS
文件
#!/bin/sh
# 挂载 /etc/fstab 中定义的所有文件系统
/bin/mount -a
# 挂载虚拟的devpts文件系统用于用于伪终端设备
/bin/mkdir -p /dev/pts
/bin/mount -t devpts devpts /dev/pts
# 扫描并创建节点
/sbin/mdev -s
# 加载网卡驱动
/sbin/modprobe r8125
# 配置网络
/sbin/udhcpc
# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do
# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue
case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set start
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i start
;;
esac
done
整个udhcpc
的框架是可执行文件/sbin/udhcpc
、脚本文件/usr/share/udhcpc/default.script
、DNS
配置文件/tmp/resolv.conf
。在rcS
中启动udhcpc
,默认使用default.script
脚本已达到自动配置ip
、route
等。
修改init.d
文件权限:
chmod -R 777 etc/init.d/*
构建dev
目录
创建dev
文件夹
mkdir dev
创建终端文件:
mknod dev/console c 5 1
mknod dev/null c 1 3
构建其他文件
mkdir mnt proc tmp sys root
ll
制作根文件系统镜像(每次修改后从这里生成镜像)
ext4
建立根文件系统挂载点busybox_rootfs
:
cd rootfs
mkdir busybox_rootfs
创建空镜像文件busybox_ext4_rootfs.img
,大小300m
,具体需要的大小可以通过du build -h
查看我们根文件系统大小调整;
root@liu-virtual-machine:/home/liu/rockchip/rootfs# dd if=/dev/zero of=busybox_ext4_rootfs.img bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB, 300 MiB) copied, 2.69688 s, 117 MB/s
root@liu-virtual-machine:/home/liu/rockchip/rootfs# ll busybox_ext4_rootfs.img
-rw-r--r-- 1 root root 314572800 9月 25 15:13 busybox_ext4_rootfs.img
root@liu-virtual-machine:/home/liu/rockchip/rootfs# mkfs.ext4 busybox_ext4_rootfs.img
打印:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# mkfs.ext4 busybox_ext4_rootfs.img
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done
Creating filesystem with 307200 1k blocks and 76912 inodes
Filesystem UUID: 24ab381d-6da0-4f5d-b436-92620c105d29
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
将该镜像文件挂载到busybox_rootfs
:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# mount busybox_ext4_rootfs.img busybox_rootfs
然后将busybox_install
的文件复制到该空文件夹中:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# cp ./busybox_install/* ./busybox_rootfs/ -af
使用df
命令可以查看是否已经挂载:
df busybox_rootfs/
root@liu-virtual-machine:/home/liu/rockchip/rootfs# df busybox_rootfs/
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop4 287237 98691 169090 37% /home/liu/rockchip/rootfs/busybox_rootfs
将之前挂载的卸载掉:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# umount busybox_rootfs
root@liu-virtual-machine:/home/liu/rockchip/rootfs# ll busybox_rootfs/
total 8
drwxr-xr-x 2 root root 4096 9月 25 15:12 ./
drwxrwxr-x 5 liu liu 4096 9月 25 15:13 ../
此时我们已经得到了ext4
根文件系统镜像busybox_ext4_rootfs.img
:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# ll busybox_ext4_rootfs.img
-rw-r--r-- 1 root root 314572800 9月 25 15:17 busybox_ext4_rootfs.img
删除文件夹busybox_rootfs
:
root@liu-virtual-machine:/home/liu/rockchip/rootfs# ls
busybox-1.36.0 busybox-1.36.0.tar.bz2 busybox_ext4_rootfs.img busybox_install busybox_rootfs
root@liu-virtual-machine:/home/liu/rockchip/rootfs# rm -rf busybox_rootfs
root@liu-virtual-machine:/home/liu/rockchip/rootfs#
用e2fsck
修复及检测镜像文件系统,resize2fs
减小镜像文件的大小;
root@liu-virtual-machine:/home/liu/rockchip/rootfs# e2fsck -p -f busybox_ext4_rootfs.img
busybox_ext4_rootfs.img: 512/76912 files (1.2% non-contiguous), 118654/307200 blocks
root@liu-virtual-machine:/home/liu/rockchip/rootfs# resize2fs -M busybox_ext4_rootfs.img
resize2fs 1.44.1 (24-Mar-2018)
Resizing the filesystem on busybox_ext4_rootfs.img to 211535 (1k) blocks.
The filesystem on busybox_ext4_rootfs.img is now 211535 (1k) blocks long.
root@liu-virtual-machine:/home/liu/rockchip/rootfs# ll busybox_ext4_rootfs.img
-rw-r--r-- 1 root root 216611840 9月 25 15:20 busybox_ext4_rootfs.img
root@liu-virtual-machine:/home/liu/rockchip/rootfs# du -sh busybox_ext4_rootfs.img
98M busybox_ext4_rootfs.img
最终得到的ext4
根文件系统镜像busybox_ext4_rootfs.img
大小为114MB
。
创建用户和密码
打开etc/inittab
添加以下:
::sysinit:-/bin/login
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install/etc# vi passwd
zhisensor:x:0:0:/zhisensor:/:/bin/sh
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install/etc# cp /etc/shadow .
将其他无用的东西删掉,剩余内容如下:
XXXX:$6$9.Nm/YXB$AAxDFTB9sPpyN7Als4rOKqprtX.LbnRkHoyLXviwNqnwMk9Ue1DmWIFZEMEzWOCeL9I6Y856nNeIatFSeomOP/:19866:0:99999:7:::
root@liu-virtual-machine:/home/liu/rockchip/rootfs/busybox_install/etc# cp /etc/group .
将其他无用的东西删掉,剩余内容如下:
XXXX:x:1000:
按章节:制作根文件系统镜像(每次修改后从这里生成镜像) 生成镜像
为了便于打包,执行以下脚本即可
package.sh
mkdir busybox_rootfs
dd if=/dev/zero of=busybox_ext4_rootfs.img bs=1M count=300
mkfs.ext4 busybox_ext4_rootfs.img
mount busybox_ext4_rootfs.img busybox_rootfs
cp ./busybox_install/* ./busybox_rootfs/ -af
umount busybox_rootfs
rm -rf busybox_rootfs
e2fsck -p -f busybox_ext4_rootfs.img
resize2fs -M busybox_ext4_rootfs.img
du -sh busybox_ext4_rootfs.img
参考文章:https://www.cnblogs.com/zyly/p/17389525.html