1、获取 BusyBox 1.31.1 代码
从busybox.net下载最新版本的代码:
https://busybox.net/downloads/busybox-1.31.1.tar.bz2
解压:tar -jxvf busybox-1.31.1.tar.bz2
2、修改Makefile
CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-6.5.0-2018.12-x86_64/bin/arm-linux-gnueabihf-
ARCH ?= arm
注意:根据自己的实际情况修改交叉编译工具链路径
gcc-linaro:https://releases.linaro.org/components/toolchain/binaries/6.5-2018.12/arm-linux-gnueabihf/
3、编译根文件系统
1.配置根文件系统
make menuconfig
(1)指定安装路径
设置用于nfs启动的路径,根据自己实际情况设置,后面将在这个路径里添加库文件
Settings --->
--- Installation Options ("make install" behavior)
(/home/hanxiaohu/linux/netboot/nfs/s5pv210/rootfs) Destination path for 'make install'
(2)静态库编译busybox
Settings --->
[*] Build static binary (no shared libs)
(3)设置,命令行风格和网络配置
Settings --->
--- Library Tuning
[*] Support /etc/networks
[*] vi-style line editing commands
(4)去掉简要安装
Linux Module Utilities --->
[ ] Simplified modutils
[*] depmod (27 kb)
[*] insmod (22 kb)
[*] lsmod (1.9 kb)
[*] Pretty output (NEW)
[*] modinfo (24 kb)
[*] modprobe (28 kb)
[*] Blacklist support (NEW)
[*] rmmod (3.3 kb)
(5)mdev配置
Linux System Utilities --->
[*] mdev (17 kb)
[*] Support /etc/mdev.conf
[*] Support subdirs/symlinks
[*] Support regular expressions substitutions when renaming device
[*] Support command execution at device addition/removal
[*] Support loading of firmware
2.编译
编译根文件系统,报错的话百度解决一下。
make -j8
编译成功后
make install
4、向根文件系统添加 lib 库
1.添加常用目录
mkdir dev mnt proc var tmp sys root lib
2.向 rootfs 的“/lib”目录添加库文件
Linux 中的应用程序一般都是需要动态库的,当然你也可以编译成静态的,但是静态的可执行文件会很大。如果编译为动态的话就需要动态库,所以我们需要先根文件系统中添加动态库。进入上面安装的路径里,在 rootfs 目录中创建一个名为“lib”的文件夹,命令如下:
mkdir lib
进入到交叉编译器的安装路径里复制so文件,
cd /usr/local/arm/gcc-linaro-6.5.0-2018.12-x86_64/arm-linuxgnueabihf/libc/lib
cp *so* *.a /home/hanxiaohu/linux/netboot/nfs/s5pv210/rootfs/lib/ -d
注意:根据自己实际情况修改路径
3.向 rootfs 的“usr/lib”目录添加库文件
在 rootfs 的 usr 目录下创建一个名为 lib 的目录,将如下目录中的库文件拷贝到 rootfs/usr/lib目录下
cd /usr/local/arm/gcc-linaro-6.5.0-2018.12-x86_64/arm-linuxgnueabihf/libc/usr/lib
cp *so* *.a /home/hanxiaohu/linux/netboot/nfs/s5pv210/rootfs/usr/lib/ -d
5、完善根文件系统
1.创建/etc/init.d/rcS 文件
rcS 是个 shell 脚本, Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。在 rootfs 中创建/etc/init.d/rcS 文件(先创建目录),然后在 rcS 中输入如下所示内容:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
第 1 行:表示这是一个 shell 脚本。
第 3 行: PATH 环境变量保存着可执行文件可能存在的目录。
第 4 行: LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
第 5 行:使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
第 7 行:使用 mount 命令来挂载所有的文件系统,这些文件系统由文件/etc/fstab 来指定。
第 8 和 9 行:创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 10 和 11 行:使用 mdev 来管理热插拔设备,通过这两行, Linux 内核就可以在/dev 目录下自动创建设备节点。
创建好文件/etc/init.d/rcS 以后一定要给其可执行权限:
chmod 777 rcS
2.创建/etc/fstab 文件
在 rootfs 中创建/etc/fstab 文件, fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,格式如下:
<file system> <mount point> <type> <options> <dump> <pass>
<file system>:要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
<mount point>:挂载点。
<type>:文件系统类型,比如 ext2、 ext3、 proc、 romfs、 tmpfs 等等。
<options>:挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults
<dump>:为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。
<pass>:磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,因此这里一般设置为 0。
在 fstab 文件中输入如下内容保存:
# <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
3.创建/etc/inittab 文件
参考 busybox 的 examples/inittab 文件,创建一个/etc/inittab,在里面输入如下内容:
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
第 2 行:系统启动以后运行/etc/init.d/rcS 这个脚本文件。
第 3 行:将 console 作为控制台终端,也就是 ttymxc0。
第 4 行:重启的话运行/sbin/init。
第 5 行:按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重启系统。
第 6 行:关机的时候执行/bin/umount,也就是卸载各个文件系统。
第 7 行:关机的时候执行/sbin/swapoff,也就是关闭交换分区。
4.创建/etc/profile文件
# Ash profile
# vim: syntax=sh
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
PS1='[root@\h \W]\# '
PATH=$PATH
`hostname S5PV210`
HOSTNAME=`hostname`
export PS1 PATH
5.创建测试程序
在rootfs根目录下创建一个hello.c
#include <stdio.h>
int main(void)
{
while(1) {
printf("hello world!\r\n");
sleep(2);
}
return 0;
}
使用交叉编译器编译
arm-linux-gnueabihf-gcc hello.c -o hello
6、运行测试
1.配置NFS
安装NFS服务
sudo apt-get install nfs-kernel-server rpcbind
添加 nfs文件夹,打开/etc/exports
sudo gedit /etc/exports
添加一行 (修改成自己的路径)
/home/hanxiaohu/linux/netboot/nfs/s5pv210/rootfs *(rw,sync,no_root_squash,no_subtree_check)
重启 NFS 服务
sudo /etc/init.d/nfs-kernel-server restart
2.配置u-boot
设置u-boot参数
setenv ipaddr 192.168.0.50
setenv ethaddr 00:19:D3:FE:56:33
setenv gatewayip 192.168.0.1
setenv netmask 255.255.255.0
setenv serverip 192.168.0.200
setenv bootcmd 'tftp 30000000 s5pv210-tq-e8.dtb;tftpboot 20008000 zImage; bootz 20008000 - 30000000'
setenv bootargs 'console=ttySAC0,115200 root=/dev/nfs rw nfsroot=192.168.0.200:/home/hanxiaohu/linux/netboot/nfs/s5pv210/rootfs ip=192.168.0.41:192.168.0.200:192.168.0.1:255.255.255.0::eth0:off earlyprintk'
saveenv
自行修改ip地址
3.启动测试
U-Boot 2017.01-g499aa08-dirty (Mar 17 2020 - 08:28:38 +0800), Build: S5PV210 for TQ-E8
CPU: S5PC110 @ 1 GHz
Model: Samsung Goni based on S5PC110
Board: TQ-E8 S5PV210
DRAM: 512 MiB
MMC: SAMSUNG SDHCI: 0, SAMSUNG SDHCI: 1
In: serial
Out: serial
Err: serial
Net: dm9000
TQ-E8 # boot
dm9000 i/o: 0x88000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:19:d3:fe:56:33
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.0.200; our IP address is 192.168.0.50
Filename 's5pv210-tq-e8.dtb'.
Load address: 0x30000000
Loading: ##
1.5 MiB/s
done
Bytes transferred = 24979 (6193 hex)
dm9000 i/o: 0x88000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:19:d3:fe:56:33
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.0.200; our IP address is 192.168.0.50
Filename 'zImage'.
Load address: 0x20008000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
1.8 MiB/s
done
Bytes transferred = 3807360 (3a1880 hex)
Kernel image @ 0x20008000 [ 0x000000 - 0x3a1880 ]
## Flattened Device Tree blob at 30000000
Booting using the fdt blob at 0x30000000
Loading Device Tree to 3af5f000, end 3af68192 ... OK
Starting kernel ...
...........
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
dm9000 88000000.ethernet eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
Please press Enter to activate this console.
[root@S5PV210 ]# ls
bin etc hello.c linuxrc proc sbin tmp var
dev hello lib mnt root sys usr
[root@S5PV210 ]# ./hello
hello world!
hello world!
hello world!
hello world!
完成!
参考文章: