嵌入式Linux根文件系统制作 (BusyBox+Initramfs)

8 篇文章 0 订阅

在这里插入图片描述

利用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、编译成功后会在刚才所创建的目录里生成这样的目录结构,正常会生成三个目录和一个文件,分别是binsbinusr目录和一个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)使用BusyBoxadderuser工具生成。

  • (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	.
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Imagine Miracle

爱你哟 =^ v ^=

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值