Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起

        根文件系统rootfs('/')是 Linux 系统中所有其他文件系统和目录的起源。在 Linux 中,所有文件、目录、设备和驱动都被组织为一个树型结构,根文件系统就是这个结构的根节点,也是引导过程中启动并加载内核所需的起点。

   根文件系统是嵌入式系统的关键组成部分,它包含了操作系统运行所需的所有基本文件和数据,能够使操作系统顺利地启动和运行,并且提供文件系统的访问和管理功能。它还包含了驱动程序、系统库文件以及其他与系统运行和管理有关的数据。所以可以简单的将他理解为一个文件夹或是一个目录

  一般来讲,嵌入式系统中根文件系统占用内存空间较小,通常采用压缩的文件系统(如 ext2、ext3 或 ext4 文件系统)来进行存储。

        嵌入式Linux开发中,常用到的目录如下:

rootfs常用子目录说明
/bin 可执行文件,例如ls、mv等命令。
/dev         设备 Linux下一切皆文件 例如:/dev/ttymxc0代表串口0
/etc 配置文件
/lib 库文件
/mnt 临时挂载目录 例如:/mnt/usb
/proc proc文件系统挂载点  系统运行信息文件
/usr 软件资源目录
/var 变量
/sbin 管理员可使用的可执行文件
/sys sysfs文件系统挂载点
/opt 可选的文件、软件

        以下从几个方面介绍根文件系统的构建:

        一、BusyBox构建根文件系统          

                1、编译BusyBox构建根文件系统

                2、添加lib库

                3、创建其他文件夹

        二、测试

        三、完善

        四、其他功能

        以下一一进行说明:

一、BusyBox构建根文件系统          

1、编译BusyBox构建根文件系统

1)修改Makefile,添加编译器

        打开busybox的顶层Makefile,添加ARCH和CROSS_COMPILE,如下:

CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-20170.1-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-//使用绝对路径防止编译出错
......
ARCH ?= arm

2)busybox中文字符支持

        因为busybox中的shell命令对中文进行了限制,无法正确的显示中文。需要对源码中的printable_string函数进行修改,如下:

12 const char* FAST_FUNC printable_string(uni_stat_t *stats, const char
*str)
13 {
14 char *dst;
15 const char *s;
16
17 s = str;
18 while (1) {
......
30 if (c < ' ')
31 break;
32 /* 注释掉下面这个两行代码 */
33 /* if (c >= 0x7f)
34 break; */
35 s++;
36 }
37
38 #if ENABLE_UNICODE_SUPPORT
39 dst = unicode_conv_to_printable(stats, str);
40 #else
41 {
42 char *d = dst = xstrdup(str);
43 while (1) {
44 unsigned char c = *d;
45 if (c == '\0')
46 break;
47 /* 修改下面代码 */
48 /* if (c < ' ' || c >= 0x7f) */
49 if( c < ' ')
50 *d = '?';
51 d++;
52 }
......
59 #endif
60 return auto_string(dst);
61 }

        将代码中字符大于0X7F以后就跳出的相关程序注释掉即可。

        接着打开unnicode.c文件,进行如下的修改:

1003 static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t
*stats, const char *src, unsigned width, int flags)
1004 {
1005 char *dst;
1006 unsigned dst_len;
1007 unsigned uni_count;
1008 unsigned uni_width;
1009
1010 if (unicode_status != UNICODE_ON) {
1011 char *d;
1012 if (flags & UNI_FLAG_PAD) {
1013 d = dst = xmalloc(width + 1);
......
1022 /* 修改下面一行代码 */
1023 /* *d++ = (c >= ' ' && c < 0x7f) ? c : '?'; */
1024 *d++ = (c >= ' ') ? c : '?';
1025 src++;
1026 }
1027 *d = '\0';
1028 } else {
1029 d = dst = xstrndup(src, width);
1030 while (*d) {
1031 unsigned char c = *d;
1032 /* 修改下面一行代码 */
1033 /* if (c < ' ' || c >= 0x7f) */
1034 if(c < ' ')
1035 *d = '?';
1036 d++;
1037 }
1038 }
......
1044 return dst;
1045 }
......
1047
1048 return dst;
1049 }

        在该段代码中,也是对字符大于0X7F的相关程序进行注释掉。               

3)配置busybox

        配置路径如下所示:

        Location:

                Settings

                        Build static binary(no shared libs) 不要选中

        继续如下路径的配置:

        Location:

                Settings

                        vi-style line editing commands

        继续如下配置:

        Location:

                Linux Modle Utilities

                        Simplifed modutils 不要选中

        继续配置如下:

        Location:

                Linux System Utilities

                        mdev(16k) //确保下面的全部选中

        最后配置使能Unicode支持中文,路径如下:

        Location:

                Settings

                        Support Unicode

                                Check $LC_ALL,$LC_CTYPE and $LANG environment varabies

 4)编译busybox

        输入如下指令编译busybox,并制定编译结果的存放路径:

make
make install CONFIG_PREFIX=/home/jia/linux/nfs/rootfs

2、添加lib库

1)向rootfs的/lib目录添加库文件

        将交叉编译器下所有的*so*和.a文件都拷贝到rootfs/lib目录中,如下:

cp *so* *.a /home/jia/linux/nfs/rootfs/lib/ -d

  删掉rootfs/lib中的ld-linux-armhf.so.3(因为它只是一个快捷方式,是一个影子而已),然后将本尊移植到相应文件中,如下:

rm ld-linux-armhf.so.3
cp ld-linux-armhf.so.3 /home/jia/linux/nfs/rootfs/lib/

        继续进行如下操作:

cp *so* *.a /home/jia/linux/nfs/rootfs/lib/ -d

        完成以后的目录如下:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第1张图片

2)向rootfs的usr/lib目录添加库文件

        进行如下操作

cp *so* *.a /home/linux/nfs/rootfs/usr/lib/ -d

        完成以后的rootfs/usr/lib目录如下:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第2张图片

 3、创建其他文件夹

        进行指令操作,创建dev、proc、mnt、sys、tmp、root等需要的文件夹。

二、测试

        要测试创建好的根文件系统rootfs,只需要将root的值改为NFS挂载即可。 

         bootarg环境变量boot的值如下:

root=/dev/nfs/ nfsroot=192.168.1.250:/home/jia/linux/nfs/rootfs,proto=tcp rw

ip=192.169.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off

        所以,需要重启开发板,进入uboot命令行模式,重新设置bootargs环境变量,命令如下:

setenv bootargs 'console=ttymxc0,115200 root=dev/nfs nfsroot=192.168.1.250:/home/jia/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::etho:off'//设置bootargs环境变量
saveenv//保存环境变量

使用boot命令启动Linux内核,如下:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第3张图片

        在上图中出现了文件缺失的错误提示。需要进一步对根文件系统进行完善。

三、完善根文件系统

1.创建/etc/init.d/rcS文件

rcS是规定启动哪些文件的shell脚本文件。在rootfs中创建/etc/init.d/rcS文件,内容如下:

1 #!/bin/sh//这是一个shell脚本
2 
3PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH//PATH环境变量保存着可执行文件可能存在的目录
4 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib//LD_LIBRARY_PATH保存着库文件所在的目录
5 export PATH LD_LIBRARY_PATH//导出上述环境变量,相当于声明一些全局变量
6
7mount -a//使用mount命令挂载所有的文件系统
8 mkdir /dev/pts//创建目录
9 mount -t devpts devpts /dev/pts//将devpts挂载到/dev/pts目录中
10
11 echo /sbin/mdev > /proc/sys/kernel/hotplug//使用mdev管理热拔插设备
12 mdev -s

使用 chmod 777 rcS命令给与/etc/init.d/rcS可执行权限。

        设置好以后,重新启动系统,得到如下界面:

        提示缺少/etc/fstab文件。

2.创建/etc/fstab文件

fstab文件会在开机以后自动配置哪些需要自动挂载的分区。在fstab文件中输入如下内容:

1 #     
2 proc /proc proc defaults 0 0
3 tmpfs /tmp tmpfs defaults 0 0
4 sysfs /sys sysfs defaults 0 0

重新启动系统,会得到如下提示:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第4张图片

上图虽然没有提示错误,但是还是要创建/etc/inittab文件

3.创建 /etc/inittab文件

创建 /etc/inittab文件,在里面输入如下内容:

1 #etc/inittab
2 ::sysinit:/etc/init.d/rcS
3 console::askfirst:-/bin/sh
4 ::restart:/sbin/init
5 ::ctrlaltdel:/sbin/reboot
6 ::shutdown:/bin/umount -a -r
7 ::shutdown:/sbin/swapoff -a

至此,根文件系统创建的文件全部完成。

四、根文件系统其它功能测试

1.软件运行测试

        使用vim编辑器新建hello.c文件,内容如下:

1 #include 
2 3
int main(void)
4 {
5 while(1) {
6 printf("hello world!\r\n");
7 sleep(2);
8 }
9 return 0;
10 }

使用如下命令进行编译:

arm-linux-gnueabihf-gcc hello.c -o hello

使用file命令查看文件类型及编码格式:

file hello

将其拷贝到rootfs/dervers目录下,在开发板中输入如下指令执行这个可执行文件:

cd /drivers
./hello

结果如下:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第5张图片

后台关闭软件的方法:

软件后面加&,使用ps查看要关闭软件的PID,使用kill -9 pid关闭指定软件。

2.中文字符测试

按照下图对SecureCRT进行设置:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第6张图片

在rootfs目录新建一个“中文测试”文件夹,新建一个名为“测试文档.txt”的文件,使用vim编辑器输入“这是一个中文测试文档”,使用cat命令查看“测试文档.txt”内容,如下:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第7张图片

3.开机自启测试

在rcS文件添加自启动相关内容,如下:

cd /drivers
./hello &
cd /

重启开发板,会得到如下界面:

Linux学习第9天:关于Linux移植之根文件系统构建:万丈高楼平地起_第8张图片

说明自启动成功。

4.外网连接测试

输入ping命令测试外网网址能否成功,出现“bad address”提示,则在/etc/resolv.conf中输入一下内容:

nameserver 114.114.114.114
nameserver 192.168.1.1

之后再使用ping命令测试外网网址成功。


本文内容为学习Linux参考正点原子开发板配套文档整理所得,仅用于学习交流,不得用于商业用途。

你可能感兴趣的:(嵌入式Linux驱动开发学习,linux,运维,学习,嵌入式硬件,服务器)