嵌入式Linux根文件系统制作 (BusyBox+Initramfs)
利用BusyBox制作rootfs本文介绍如何使用BusyBox构建rootfs,具体包括BusyBox的安装、配置、编译以及跟文件目录的相关修改和需注意点等内容当前系统环境介绍:OS:Ubuntu20.04.1 LTSBusyBox: BusyBox 1.32.0Corss Compiler:riscv64-unknown-linux-gnu [注]: 这是针对riscv64架构的编译器,该工具
利用BusyBox制作rootfs
本文介绍如何使用BusyBox构建rootfs,具体包括BusyBox的安装、配置、编译以及跟文件目录的相关修改和需注意点等内容
当前系统环境介绍:
OS:Ubuntu20.04.1 LTS
BusyBox: BusyBox 1.32.0
Corss Compiler:riscv64-unknown-linux-gnu [注]: 这是针对riscv64架构的编译器,该工具链支持的abi方式是lp64d
ARCH:rv64imafdc [注]: 这代表该架构是基于RISC-V 64位IMAFDC(RV64GC),胜任通用任务的一种架构
[详释]:
“I” 基本整数集,其中包含整数的基本计算、Load/Store和控制流,所有的硬件实现都必须包含这一部分。
“M” 标准整数乘除法扩展集,增加了整数寄存器中的乘除法指令。
“A” 标准操作原子扩展集,增加对储存器的原子读、写、修改和处理器间的同步。
“F” 标准单精度浮点扩展集,增加了浮点寄存器、计算指令、L/S指令。
“D” 标准双精度扩展集,扩展双精度浮点寄存器,双精度计算指令、L/S指令。
I+M+F+A+D 被缩写为 “G” ,共同组成通用的标量指令。
在后续ISA的版本迭代过程中,RV32G和RV64G总是保持不变。
1、获取BusyBox源码
1.1、
进入BusyBox
的官网主页https://www.busybox.net,可以看到当前最新发布的BusyBox
版本,直接点击就可以下载到本地目录。
1.2、
如上图,目前的最新版本为BusyBox 1.32.0
,直接点击下载到本地目录并将其解压
imaginemiracle@:busybox-1.32.0$ ls
busybox-1.32.0.tar.bz2
imaginemiracle@:busybox-1.32.0$ tar -jxvf busybox-1.32.0.tar.bz2
imaginemiracle@:busybox-1.32.0$ ls
busybox-1.32.0 busybox-1.32.0.tar.bz2
imaginemiracle@:busybox-1.32.0$ cd busybox-1.32.0/
imaginemiracle@:busybox-1.32.0$ ls
applets configs editors klibc-utils Makefile modutils qemu_multiarch_testing size_single_applets.sh
applets_sh console-tools examples libbb Makefile.custom networking README sysklogd
arch coreutils findutils libpwdgrp Makefile.flags NOFORK_NOEXEC.lst runit testsuite
archival debianutils include LICENSE Makefile.help NOFORK_NOEXEC.sh scripts TODO
AUTHORS docs init loginutils make_single_applets.sh printutils selinux TODO_unicode
Config.in e2fsprogs INSTALL mailutils miscutils procps shell util-linux
2、配置BusyBox
(1) 创建目录结构
该目录用于保存BusyBox
编译出的目录文件
imaginemiracle@:busybox-1.32.0$ mkdir rootfs_install
imaginemiracle@:busybox-1.32.0$ ls
busybox-1.32.0 busybox-1.32.0.tar.bz2 rootfs_install
(2) menuconfig配置
imaginemiracle@:busybox-1.32.0$ cd busybox-1.32.0/
imaginemiracle@:busybox-1.32.0$ make menuconfig
2.1、
进入Settings设置
2.2、
取消不需要的配置,主要设置交叉编译工具链路径Cross Compiler Perfix
和make install的安装路径即刚才创建的目录路径Destination path for 'make install'
3、编译
imaginemiracle@:busybox-1.32.0$ make ARCH=rv64imafdc
imaginemiracle@:busybox-1.32.0$ make install
imaginemiracle@:busybox-1.32.0$ cd ../rootfs_install
imaginemiracle@:rootfs_install$ ls
bin linuxrc sbin usr
3.3、
编译成功后会在刚才所创建的目录里生成这样的目录结构,正常会生成三个目录和一个文件,分别是bin
、sbin
和usr
目录和一个linuxrc
文件;
与常规见到的跟文件系统相比较少了很多东西,因此需要手动的添加和修改这些文件。
当然,如果在menuconfig
中或在make install
的时候不添加指定目录,make install会默认将生成的目录结构保存在busybox
源码下的"_install"
目录里,Destination path for 'make install'
的默认值是./_install
。
4、添加其它常用目录
imaginemiracle@:rootfs_install$ mkdir bin dev etc lib proc sbin sys usr mnt tmp var
imaginemiracle@:rootfs_install$ mkdir usr/bin usr/lib usr/sbin lib/modules
5、为/etc目录添加基本的配置文件
添加这些基本的配置文件方法有很多,这里直接使用busybox
中带有的examples
来修改使用。
imaginemiracle@:rootfs_install$ cp -a ../busybox-1.32.0/examples/bootfloppy/etc/ ./
imaginemiracle@:rootfs_install$ ls etc/
fstab init.d inittab profile
5.1、
其中值得注意的是inittab
文件,该文件是文件系统启动后访问的第一个脚本,后续的文件都由它制定。
- (1) 打开并对
inittab
文件进行修改(根据实际情况进行修改)
##########拷贝过来的源文件
#指定系统的启动脚本为/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
#指定打开一个登录会话
::respawn:-/bin/sh
#指定在第三个虚拟终端打开一个无须登录验证的shell
tty2::askfirst:-/bin/sh
#指定当按下ctrl+alt+del组合键时的执行命令
::ctrlaltdel:/bin/umount -a -r
======================================分割线=========================================
##########修改后的inittab
# Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mkdir -p /dev/shm
::sysinit:/bin/mount -a
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# Put a getty on the serial port
console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot
# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
- (2)
fstab
文件,该文件定义了文件系统中的各个挂载点(根据实际情况修改)
##########拷贝过来的源文件
proc /proc proc defaults 0 0
======================================分割线=========================================
##########修改后的fstab
# <file system> <mount pt> <type> <options> <dump> <pass>
/dev/root / ext2 rw,noauto 0 1
proc /proc proc defaults 0 0
devpts /dev/pts devpts defaults,gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs mode=0777 0 0
tmpfs /tmp tmpfs mode=1777 0 0
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
sysfs /sys sysfs defaults 0 0
- (3)
profile
文件,该文件会在进入终端登录之后第一个运行的脚本。这个文件应该会很熟悉,平时的系统环境变量修改就在这里(根据实际情况修改)
##########拷贝过来的源文件
# /etc/profile: system-wide .profile file for the Bourne shells
echo
echo -n "Processing /etc/profile... "
# no-op
echo "Done"
echo
======================================分割线=========================================
##########修改后的profile
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
if [ "$PS1" ]; then
if [ "`id -u`" -eq 0 ]; then
export PS1='# '
else
export PS1='$ '
fi
fi
export PAGER='/bin/more '
export EDITOR='/bin/vi'
# Source configuration files from /etc/profile.d
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
. $i
fi
unset i
done
5.1、终端的用户登录验证相关文件的添加
[注]: 若在BusyBox的编译选项中打开shadow功能则需要在etc目录下添加这些文件
添加方式
(1)
根据格式自己编写文件内容;
(2)
使用BusyBox
的adderuser
工具生成。
- (3)
passwd
文件(内容根据实际情况修改)
#passwd文件编写格式以及各字段意义(7个字段分别使用“:”间隔)
#[用户名]:[是否使用加密口令,x表示有,不填写表示无,使用MD5、DES加密]:[用户ID]:[组ID]:[注释字段]:[登录目录]:[使用的shell]
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:99:99:nobody:/home:/bin/false
- (4)
group
文件
#group文件编辑格式以及各字段意义(4个字段分别用":"间隔)
#[组名]:[是否使用加密口令]:[组ID]:[指向各用户名指针的数组]
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
kmem:x:9:
wheel:x:10:root
cdrom:x:11:
dialout:x:18:
floppy:x:19:
video:x:28:
audio:x:29:
tape:x:32:
www-data:x:33:
operator:x:37:
utmp:x:43:
plugdev:x:46:
staff:x:50:
lock:x:54:
netdev:x:82:
nogroup:x:99:
users:x:100:`(3.1)`
- (5)
shadow
文件
#shadow文件编辑格式以及各字段意义(9个字段分别用":"间隔)
#[用户名]:[加密后的口令,空代表不需要口令登录,”*“代表帐号被禁用]:[从1970/01/01到口令最近被修改的天数]:[口令在多少天内不能被用户修改]:[口令在多少天后必须被修改(0为没有修改过)]:[口令过期多少天后用户账号被禁止]:[口令在到期多少天内给用户发出警告]:[口令自1970年1月1日被禁止的天数]:[保留字段]
#[注1]: 第二个字段中的加密字符串是根据自己设置的密码加密生成的,如下的字符串代表当前root用户密码加密后的口令
#[注2]: UNIX规定1970/01/01 0点 是时间纪元
root:$1$W.ejfkhq$v0bHAgc4RxSgzFtjRKggP.:10933:0:99999:7:::
daemon:*:10933:0:99999:7:::
bin:*:10933:0:99999:7:::
sys:*:10933:0:99999:7:::
sync:*:10933:0:99999:7:::
mail:*:10933:0:99999:7:::
www-data:*:10933:0:99999:7:::
operator:*:10933:0:99999:7:::
nobody:*:10933:0:99999:7:::
6、为/dev目录添加基本的设备文件
在调试时需要通过串口打印和发送消息到终端显示,因此在/dev
下串口控制台和终端这两个设备文件(确切的说这里的是设备节点)是必须的。
#若创建出来的跟文件系统没有后/dev目录,先用mkdir创建出dev目录
#创建控制台设备节点
imaginemiracle@:dev$ sudo mknod -m 666 console c 5 1
#创建终端的设备节点
imaginemiracle@:dev$ sudo mknod -m 666 null c 1 3
imaginemiracle@:dev$ ls
console null
7、创建init
在根目录创建init
imaginemiracle@:rootfs_install$ ln -s ./bin/busybox init
imaginemiracle@:rootfs_install$ ls
bin dev etc init lib lib64 linuxrc media mnt opt proc root run sbin sys tmp usr var
8、使用Initramfs制作根文件系统
需要查看Initramfs的详细介绍请点击该链接::
Initramfs-Ubuntu
[注] 使用交叉编译工具链工具将其编译生成自己所适用的内核镜像以及通过bootloader的加载方式本文不做过多赘述,根据实际情况进行操作即可
在完成rootfs的构建之后,通过配置内核支持Initramfs,并设置好rootfs的路径即可编译出带有文件系统的vmliunx
(1)
使用 make menuconfig
命令进入内核配置菜单
(2)
配置General setup —> [*]Initial RAM filesystem and RAM disk (initramfs/initrd) support
(3)
配置General setup —> ()Initramfs source file(s) [注]在括号里写入构建的rootfs路径,绝对路径和相对路径均可
(4)
make
重新编译生成内核镜像
(5)
由于笔者使用的环境是sifive
提供的对risc-v
架构支持的Linux
内核以及由伯里克分校(Berkely)
大学写的Berkeley Boot Loader(BBL)
,生成的镜像会将BBL
和内核文件vmliux
打包进一个bbl.bin
文件中(这里的vmlinux是使用交叉编译工具链中的stripped在缩减过的)。
(6)
上板运行,由于该内核是未添加对NETWorking
的支持的,因此会在文件系统的某些脚本执行打印一些异常信息。
##到此使用BusyBox和Initramfs的方式生成Linux根文件系统的方法介绍完毕
##附
#以下是当前rootfs的目录结构,根据实际需求进行
imaginemiracle@:rootfs_install$ tree
.
├── bin
│ ├── ash -> busybox
│ ├── busybox
│ ├── cat -> busybox
│ ├── catv -> busybox
│ ├── chattr -> busybox
│ ├── chgrp -> busybox
│ ├── chmod -> busybox
│ ├── chown -> busybox
│ ├── cp -> busybox
│ ├── cpio -> busybox
│ ├── date -> busybox
│ ├── dd -> busybox
│ ├── df -> busybox
│ ├── dmesg -> busybox
│ ├── dnsdomainname -> busybox
│ ├── dumpkmap -> busybox
│ ├── echo -> busybox
│ ├── egrep -> busybox
│ ├── false -> busybox
│ ├── fdflush -> busybox
│ ├── fgrep -> busybox
│ ├── getopt -> busybox
│ ├── grep -> busybox
│ ├── gunzip -> busybox
│ ├── gzip -> busybox
│ ├── hostname -> busybox
│ ├── kill -> busybox
│ ├── linux32 -> busybox
│ ├── linux64 -> busybox
│ ├── ln -> busybox
│ ├── login -> busybox
│ ├── ls -> busybox
│ ├── lsattr -> busybox
│ ├── mkdir -> busybox
│ ├── mknod -> busybox
│ ├── mktemp -> busybox
│ ├── more -> busybox
│ ├── mount -> busybox.
├── bin
│ ├── ash -> busybox
│ ├── busybox
│ ├── cat -> busybox
│ ├── catv -> busybox
│ ├── chattr -> busybox
│ ├── chgrp -> busybox
│ ├── chmod -> busybox
│ ├── chown -> busybox
│ ├── cp -> busybox
│ ├── cpio -> busybox
│ ├── date -> busybox
│ ├── dd -> busybox
│ ├── df -> busybox
│ ├── dmesg -> busybox
│ ├── dnsdomainname -> busybox
│ ├── dumpkmap -> busybox
│ ├── echo -> busybox
│ ├── egrep -> busybox
│ ├── false -> busybox
│ ├── fdflush -> busybox
│ ├── fgrep -> busybox
│ ├── getopt -> busybox
│ ├── grep -> busybox
│ ├── gunzip -> busybox
│ ├── gzip -> busybox
│ ├── hostname -> busybox
│ ├── kill -> busybox
│ ├── linux32 -> busybox
│ ├── linux64 -> busybox
│ ├── ln -> busybox
│ ├── login -> busybox
│ ├── ls -> busybox
│ ├── lsattr -> busybox
│ ├── mkdir -> busybox
│ ├── mknod -> busybox
│ ├── mktemp -> busybox
│ ├── more -> busybox
│ ├── mount -> busybox
│ ├── mountpoint -> busybox
│ ├── mt -> busybox
│ ├── mv -> busybox
│ ├── netstat -> busybox
│ ├── nice -> busybox
│ ├── pidof -> busybox
│ ├── ping -> busybox
│ ├── pipe_progress -> busybox
│ ├── printenv -> busybox
│ ├── ps -> busybox
│ ├── pwd -> busybox
│ ├── rm -> busybox
│ ├── rmdir -> busybox
│ ├── run-parts -> busybox
│ ├── sed -> busybox
│ ├── setarch -> busybox
│ ├── setserial -> busybox
│ ├── sh -> busybox
│ ├── sleep -> busybox
│ ├── stty -> busybox
│ ├── su -> busybox
│ ├── sync -> busybox
│ ├── tar -> busybox
│ ├── touch -> busybox
│ ├── true -> busybox
│ ├── umount -> busybox
│ ├── uname -> busybox
│ ├── usleep -> busybox
│ ├── watch -> busybox
│ └── zcat -> busybox
├── dev
│ ├── console
│ └── null
├── etc
│ ├── dropbear -> /var/run/dropbear
│ ├── fstab
│ ├── group
│ ├── hostname
│ ├── hosts
│ ├── init.d
│ │ ├── rcK
│ │ ├── rcS
│ │ ├── S01logging
│ │ ├── S10mdev
│ │ ├── S20urandom
│ │ ├── S40network
│ │ └── S50dropbear
│ ├── inittab
│ ├── inittab_NoLogin
│ ├── issue
│ ├── mdev.conf
│ ├── mtab
│ ├── network
│ │ ├── if-down.d
│ │ ├── if-post-down.d
│ │ ├── if-pre-up.d
│ │ │ └── wait_iface
│ │ ├── if-up.d
│ │ ├── interfaces
│ │ └── nfs_check
│ ├── nsswitch.conf
│ ├── os-release
│ ├── passwd
│ ├── profile
│ ├── profile.d
│ │ └── umask.sh
│ ├── protocols
│ ├── services
│ └── shadow
├── init -> /bin/busybox
├── lib
│ ├── ld-2.26.so
│ ├── ld-linux-riscv64-lp64d.so.1 -> ld-2.26.so
│ ├── libatomic.so.1 -> libatomic.so.1.2.0
│ ├── libatomic.so.1.2.0
│ ├── libc-2.26.so
│ ├── libcrypt-2.26.so
│ ├── libcrypt.so.1 -> libcrypt-2.26.so
│ ├── libc.so.6 -> libc-2.26.so
│ ├── libdl-2.26.so
│ ├── libdl.so.2 -> libdl-2.26.so
│ ├── libgcc_s.so.1
│ ├── libm-2.26.so
│ ├── libm.so.6 -> libm-2.26.so
│ ├── libnsl-2.26.so
│ ├── libnsl.so.1 -> libnsl-2.26.so
│ ├── libnss_files-2.26.so
│ ├── libnss_files.so.2 -> libnss_files-2.26.so
│ ├── libpthread-2.26.so
│ ├── libpthread.so.0 -> libpthread-2.26.so
│ ├── libresolv-2.26.so
│ ├── libresolv.so.2 -> libresolv-2.26.so
│ ├── librt-2.26.so
│ ├── librt.so.1 -> librt-2.26.so
│ ├── libutil-2.26.so
│ └── libutil.so.1 -> libutil-2.26.so
├── lib64 -> lib
├── linuxrc -> bin/busybox
├── media
├── mnt
├── opt
├── proc
├── root
│ └── Miracle
│ └── test
│ ├── helloworld
│ ├── helloworld.c
│ ├── test
│ └── test.c
├── run
├── sbin
│ ├── arp -> ../bin/busybox
│ ├── blkid -> ../bin/busybox
│ ├── devmem -> ../bin/busybox
│ ├── fdisk -> ../bin/busybox
│ ├── freeramdisk -> ../bin/busybox
│ ├── fsck -> ../bin/busybox
│ ├── fstrim -> ../bin/busybox
│ ├── getty -> ../bin/busybox
│ ├── halt -> ../bin/busybox
│ ├── hdparm -> ../bin/busybox
│ ├── hwclock -> ../bin/busybox
│ ├── ifconfig -> ../bin/busybox
│ ├── ifdown -> ../bin/busybox
│ ├── ifup -> ../bin/busybox
│ ├── init -> ../bin/busybox
│ ├── ip -> ../bin/busybox
│ ├── ipaddr -> ../bin/busybox
│ ├── iplink -> ../bin/busybox
│ ├── iproute -> ../bin/busybox
│ ├── iprule -> ../bin/busybox
│ ├── iptunnel -> ../bin/busybox
│ ├── klogd -> ../bin/busybox
│ ├── loadkmap -> ../bin/busybox
│ ├── losetup -> ../bin/busybox
│ ├── makedevs -> ../bin/busybox
│ ├── mdev -> ../bin/busybox
│ ├── mkswap -> ../bin/busybox
│ ├── modprobe -> ../bin/busybox
│ ├── nameif -> ../bin/busybox
│ ├── pivot_root -> ../bin/busybox
│ ├── poweroff -> ../bin/busybox
│ ├── reboot -> ../bin/busybox
│ ├── route -> ../bin/busybox
│ ├── runlevel -> ../bin/busybox
│ ├── setconsole -> ../bin/busybox
│ ├── start-stop-daemon -> ../bin/busybox
│ ├── sulogin -> ../bin/busybox
│ ├── swapoff -> ../bin/busybox
│ ├── swapon -> ../bin/busybox
│ ├── switch_root -> ../bin/busybox
│ ├── sysctl -> ../bin/busybox
│ ├── syslogd -> ../bin/busybox
│ ├── udhcpc -> ../bin/busybox
│ ├── uevent -> ../bin/busybox
│ ├── vconfig -> ../bin/busybox
│ └── watchdog -> ../bin/busybox
├── sys
├── tmp
├── usr
└── var
├── cache
├── lib
│ └── misc
├── lock
├── log
├── run
├── spool
├── tmp
└── www
#总大小为2.9M,由于相关库文件占用比较大的原因导致
imaginemiracle@:rootfs_install$ du -h
614K ./bin
1.0K ./dev
18K ./etc/init.d
0 ./etc/network/if-down.d
0 ./etc/network/if-post-down.d
1.0K ./etc/network/if-pre-up.d
0 ./etc/network/if-up.d
9.5K ./etc/network
512 ./etc/profile.d
66K ./etc
2.2M ./lib
0 ./media
0 ./mnt
0 ./opt
0 ./proc
25K ./root/Miracle/test
25K ./root/Miracle
25K ./root
0 ./run
31K ./sbin
0 ./sys
0 ./tmp
0 ./usr
0 ./var/cache
0 ./var/lib/misc
0 ./var/lib
0 ./var/lock
0 ./var/log
0 ./var/run
0 ./var/spool
0 ./var/tmp
0 ./var/www
4.0K ./var
2.9M .
更多推荐
所有评论(0)