? ? ? ? 根文件系统rootfs('/')是 Linux 系统中所有其他文件系统和目录的起源。在 Linux 中,所有文件、目录、设备和驱动都被组织为一个树型结构,根文件系统就是这个结构的根节点,也是引导过程中启动并加载内核所需的起点。
根文件系统是嵌入式系统的关键组成部分,它包含了操作系统运行所需的所有基本文件和数据,能够使操作系统顺利地启动和运行,并且提供文件系统的访问和管理功能。它还包含了驱动程序、系统库文件以及其他与系统运行和管理有关的数据。所以可以简单的将他理解为一个文件夹或是一个目录。
一般来讲,嵌入式系统中根文件系统占用内存空间较小,通常采用压缩的文件系统(如 ext2、ext3 或 ext4 文件系统)来进行存储。
? ? ? ? 嵌入式Linux开发中,常用到的目录如下:
/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的顶层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
? ? ? ? 因为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的相关程序进行注释掉。? ? ? ? ? ? ? ?
? ? ? ? 配置路径如下所示:
? ? ? ? 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
? ? ? ? 输入如下指令编译busybox,并制定编译结果的存放路径:
make
make install CONFIG_PREFIX=/home/jia/linux/nfs/rootfs
? ? ? ? 将交叉编译器下所有的*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
????????完成以后的目录如下:
? ? ? ? 进行如下操作
cp *so* *.a /home/linux/nfs/rootfs/usr/lib/ -d
? ? ? ? 完成以后的rootfs/usr/lib目录如下:
????????进行指令操作,创建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内核,如下:
? ? ? ? 在上图中出现了文件缺失的错误提示。需要进一步对根文件系统进行完善。
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文件。
fstab文件会在开机以后自动配置哪些需要自动挂载的分区。在fstab文件中输入如下内容:
1 #<file system> <mount point> <type> <options> <dump> <pass>
2 proc /proc proc defaults 0 0
3 tmpfs /tmp tmpfs defaults 0 0
4 sysfs /sys sysfs defaults 0 0
重新启动系统,会得到如下提示:
上图虽然没有提示错误,但是还是要创建/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
至此,根文件系统创建的文件全部完成。
? ? ? ? 使用vim编辑器新建hello.c文件,内容如下:
1 #include <stdio.h>
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
结果如下:
后台关闭软件的方法:
软件后面加&,使用ps查看要关闭软件的PID,使用kill -9 pid关闭指定软件。
按照下图对SecureCRT进行设置:
在rootfs目录新建一个“中文测试”文件夹,新建一个名为“测试文档.txt”的文件,使用vim编辑器输入“这是一个中文测试文档”,使用cat命令查看“测试文档.txt”内容,如下:
在rcS文件添加自启动相关内容,如下:
cd /drivers
./hello &
cd /
重启开发板,会得到如下界面:
说明自启动成功。
输入ping命令测试外网网址能否成功,出现“bad address”提示,则在/etc/resolv.conf中输入一下内容:
nameserver 114.114.114.114
nameserver 192.168.1.1
之后再使用ping命令测试外网网址成功。
本文内容为学习Linux参考正点原子开发板配套文档整理所得,仅用于学习交流,不得用于商业用途。