上一篇推文讲了怎么移植根文件系统,并在i.MX6ULL开发板中运行起来,但是会出现一些提示,现在来进行根文件的完善;
| 完善根文件系统
创建/etc/init.d/rcS 文件 在 rootfs 中创建/etc/init.d/rcS 文件(前两级的目录都不存在,需要先创建目录再创建文件),rcS 是个 shell 脚本,Linux 内核启动以后需要启动一些服务,而 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 来指定,所以我们一会还要创建/etc/fstab 文件。
第 8 和 9 行,创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 11 和 12 行,使用 mdev 来管理热插拔设备,通过这两行,Linux 内核就可以在/dev 目录下自动创建设备节点。关于 mdev 的详细内容可以参考 busybox 中的 docs/mdev.txt 文档。
给予可执行权限
chmod 777 rcS创建/etc/fstab 文件 在 rootfs 中创建/etc/fstab 文件,fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,格式如下:
格式含义解析:
按照上述格式,在 fstab 文件中输入如下内容::要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。 :挂载点。 :文件系统类型,比如 ext2、ext3、proc、romfs、tmpfs 等等。 :挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项,defaults 包含了 rw、suid、 dev、 exec、 auto、 nouser 和 async。 :为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。 :磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,因此这里一般设置为 0。
#创建/etc/inittab 文件 inittab 的详细内容可以参考 busybox 下的文件 examples/inittab。init 程序会读取/etc/inittab这个文件,inittab 由若干条指令组成。每条指令的结构都是一样的,由以“:”分隔的 4 个段组成,格式如下:proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0
格式含义解析:: : :
busybox 支持的动作::每个指令的标识符,不能重复。但是对于 busybox 的 init 来说, 有着特殊意义。对于 busybox 而言 用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控制 tty。 :对 busybox 来说此项完全没用,所以空着。 :动作,用于指定 可能用到的动作。busybox 支持的动作如下表; :具体的动作,比如程序、脚本或命令等。
参考 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,也就是关闭交换分区。
/etc/inittab 文件创建好以后就可以重启开发板即可,至此!根文件系统要创建的文件就已经全部完成了。 | 根文件系统其他功能测试 软件运行测试 使用 Linux 的目的就是运行自己的软件,编译的应用软件一般都使用动态库,使用动态库的话应用软件体积就很小,但是得提供库文件,库文件已经添加到了根文件系统中,通过编写一个测试软件测试一下库文件是否工作正常; 在根文件系统下创建一个名为“drivers”的文件夹,以后我们 Linux 驱动的时候就把所有的实验文件放到这个文件夹里面。
在drivers中新建一个hello.c文件,在 hello.c 里面输入如下内容:
#include用交叉编译器去编译,命令如下:int main(void) { while(1) { printf("hello world! "); //打印 sleep(2); //休眠2秒 } }
arm-linux-gnueabihf-gcc hello.c -o hello
使用“file”命令查看文件类型以及编码格式:
file hello //查看 hello 的文件类型以及编码格式
hello 是个 32 位的 LSB 可执行文件,ARM 架构的,并且是动态链接的,所以编译出来的 hello 文件没有问题,在串口软件中输入命令运行编译出来的可执行文件hello:
./hello
运行正常,说明根文件系统中的动态库没有问题,按下“ctrl+c”组合键即可中止该程序。 hello 执行的时候终端是没法用的,除非使用“ctrl+c”来关闭 hello,如果想要hello正常运行并且不影响控制台使用,那么就可以让hello进入后台运行,运行软件的时候加上“&”即可命令如下:
./hello &注意:hello进入后台运行,控制台也能使用,但是hello输出会打断输入; 在后台运行的软件可以使用,使用“ps”命令查看要关闭的软件 PID,再通过“kill”命令关闭后台软件,操作如下:
// 查看所有当前正在运行的进程 ps // 关闭进程 kill -9 104
开机自启动测试 一般做好产品以后都是需要开机自动启动相应的软件,并不会每次启动后再手动输入相关命令;进入根文件系统的时候会运行/etc/init.d/rcS 这个 shell 脚本,因此可以在这个脚本里面添加自启动相关内容:
#!/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 #开机自启动 cd /drivers ./hello & cd /
外网连接测试 这里的外网是相对于局域网而言的,主要测试开发板能不能ping通百度来判断开发板能否正常联网,命令如下:
ping www.baidu.com
访问外网是需要域名解析的,需要配置域名解析服务器的 IP 地址,一般域名解析地址可以设置为所处网络的网关地址,比如 192.168.2.1。也可以设置为 114.114.114.114,这个是运营商的域名解析服务器地址。 在 rootfs 中新建文件/etc/resolv.conf,然后在里面输入如下内容:
nameserver 114.114.114.11 nameserver 192.168.1.1nameserver 表示这是个域名服务器,设置了两个域名服务器地址;
至此!我们的根文件系统就彻底的制作完成,这个根文件系统最好打包保存一下,防止以后做实验不小心破坏了根文件系统而功亏一篑,又得从头制作根文件系统。uboot、Linux kernel、rootfs 这三个共同构成了一个完整的Linux 系统,现在的系统至少是一个可以正常运行的系统,后面我们就可以在这个系统上完成Linux 驱动开发的学习。
审核编辑:汤梓红
评论
查看更多