1、制作分区
(1)分析
在上节实验中出现以下问题:无法挂载根文件系统
在以前u-boot烧写文件系统时是烧写到某个地方,以前的分区是下面那样划分的,划分为4个分区,但是上面有8个分区
分区修改参考(分区是在代码里面写死的,u-boot怎么设置不会影响内核)
http://blog.csdn.net/qingkongyeyue/article/details/52201150
(2)实验
下载并启动内核,分区已改变,是不是分区上灭有烧写文件系统。
(3)烧写文件系统
下载
擦除
烧写
下载内核并启动
还是出现错误,因为不支持yaffs文件系统
(4)看内核支持的文件系统
查看vi .config
搜索不出yaffs,但是有jffs2
(5)烧写jffs2文件系统
实际上下载文件的时候,会把大小存在一个所谓的环境变量里面,可以通过$filesize或$(filesize)这样引用。
下载
擦除、烧写
(6)设置启动参数(在启动参数中指明内核在哪里挂载根文件系统)
并下载内核
用bootm 3200,0000启动
挂载上去了,但还是发现找不着init文件
2、FHS(Filesystem Hierarchy Standard)标准介绍
当我们在linux下输入ls / 的时候,见到的目录结构以及这些目录下的内容都大同小异,这是因为所有的linux发行版在对根文件系统布局上都遵循FHS标准的建议规定。
该标准规定了根目录下各个子目录的名称及其存放的内容:
目录名 | 存放的内容 |
/bin | 必备的用户命令,例如ls、cp等 |
/sbin | 必备的系统管理员命令,例如ifconfig、reboot等 |
/dev | 设备文件,例如mtdblock0、tty1等 |
/etc | 系统配置文件,包括启动文件,例如inittab等 |
/lib | 必要的链接库,例如C链接库、内核模块 |
/home | 普通用户主目录 |
/root | root用户主目录 |
/usr/bin | 非必备的用户程序,例如find、du等 |
/usr/sbin | 非必备的管理员程序,例如chroot、inetd等 |
/usr/lib | 库文件 |
/var | 守护程序和工具程序所存放的可变,例如日志文件 |
/proc | 用来提供内核与进程信息的虚拟文件系统,由内核自动生成目录下的内容 |
/sys | 用来提供内核与设备信息的虚拟文件系统,由内核自动生成目录下的内容 |
/mnt | 文件系统挂接点,用于临时安装文件系统 |
/tmp | 临时性的文件,重启后将自动清除 |
3、制作根文件系统
构造文件系统
内核启动后,挂载根文件系统,最终启动应用程序。有那么多的应用程序,到底启动哪一个,内核只会启动第一个应用程序,第一个应用程序就会根据配置文件去决定启动哪一家的公司的哪一个应用程序。
制作根文件系统就是要建立以上的目录,并在其中建立完整目录内容。其过程大体包括:
- 编译/安装busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目录
- 利用交叉编译工具链,构建/lib目录
- 手工构建/etc目录
- 手工构建最简化的/dev目录
- 创建其它空目录
- 配置系统自动生成/proc目录
- 利用udev构建完整的/dev目录
- 制作根文件系统的jffs2映像文件
(1)编译/安装busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目录
(编译内核用哪一个编译器,就用这个编译器去编译应用程序)
这些目录下存储的主要是常用命令的二进制文件。
1、从http://www.busybox.net/ 下载busybox-1.20.0.tar.bz2
2、tar xjvf busybox-1.20.0.tar.bz2解包
3、修改Makefile文件
175 ARCH ?= arm
176 CROSS_COMPILE ?= arm-linux-
4、make menuconfig配置busybox
我们要交叉编译,需要指定编译器
编译选项交叉编译前缀
5、编译busybox
make
6、安装busybox
在nfs_root中创建目录:mkdir fs_mini_mdev_new
(2)安装glibc库
看环境变量,我们的交叉编译工具链在哪里
进工具链中查找相关的库,thumb2是thumb指令集用到的库,我们用到的是
这两个库。
在根文件系统下建立一个lib目录
把交叉编译工具链下的动态链接库文件拷贝到跟文件系统下的lib目录,-d是链接文件在拷贝后仍是链接文件,否则是拷贝实际的文件。
在根文件系统下建立一个usr\lib目录,不加-p要先创建目录usr,后创建目录lib.-p可以一次性创建。把交叉编译工具链下的动态链接库文件拷贝到跟文件系统下的usr\lib目录
(3)构造etc目录
把之前的根文件系统的etc目录下的内容拷贝过来并修改
我们内核启动的第一个进程就会打开inittab,根据文件指示去做某些事情
会执行脚本/etc/init.d/rcS,执行完脚本后,启动shell,这个shell从串口0的设备名,console中得到输入
看脚本/etc/init.d/rcS,mount -a是根据fstab文件的内容来挂接各种根文件系统
fstab文件的内容
###############################################
###############################################
第一列:设备名或者设备卷标名,(/dev/sda10 或者 LABEL=/)
第二列:设备挂载目录 (例如上面的“/”或者“/mnt/D/”)
第三列:设备文件系统 (例如上面的“ext3”或者“vfat”)
第四列:挂载参数 (看帮助man mount)
对于已经挂载好的设备,例如上面的/dev/sda2,现在要改变挂载参数,这时可以不用卸载该设备,而可以使用下面的命令(没有挂载的设备,remount 这个参数无效)
#mount /mnt/D/ -o remount,ro (改defaults为ro)
为了安全起见,可以指明其他挂载参数,例如:
noexec(不允许可执行文件可执行,但千万不要把根分区挂为noexec,那就无法使用系统了,连mount 命令都无法使用了,这时只有重新做系统了!
nodev(不允许挂载设备文件)
nosuid,nosgid(不允许有suid和sgid属性)
nouser(不允许普通用户挂载)
第五列:指明是否要备份,(0为不备份,1为要备份,一般根分区要备份)
第六列:指明自检顺序。 (0为不自检,1或者2为要自检,如果是根分区要设为1,其他分区只能是2)如果想开机就自动挂载(mount)上,可以在/etc/fstab上添加如下几行:
/dev/hda5 /mnt/d vfat exec,dev,suid,rw,umask=0,iocharset=gb2312,codepage=936 0 0
同时也解决了中文文件名的乱码问题,我的fstab文件如下,仅供参考:
###############################################
###############################################
(4)构造dev目录
我们上电后执行,里面会根据inittab这个文件来决定执行脚本/etc/init.d/rcS,这个脚本会执行mdev -s创建dev目录下的内容,但是在mdev -s执行前,dev目录下需要有东西。创建两个设备节点。下面的目录需要修改一下,在fs_mini_mdev_new目录下的dev目录下创建两个设备节点。
(5)创建其他目录(挂载虚拟的文件系统)
(6)制作映像文件
-s 是扇区的大小,我们的nand flash的一个扇区是2048,-e是可擦除块是128K,-d指明目录是fs_mini_mdev_new,后面-o跟输出文件fs_mini_mdev_new.jffs2
4、验证制作的跟文件系统
(1)重启开发板、下载跟文件系统,擦除nand flash,然后烧写
(3)设置启动参数、下载新内核、用bootm 32000000启动
(4)看启动信息,挂接上去了,并找到了init程序,但是这个程序有点问题
(5)在内核中搜索exitcode,看exitcode=0x00000004是什么意思。
在Exit.c的find_new_reaper函数中
看参数是什么意思
find_new_reaper函数被forget_original_parent函数调用
forget_original_parent函数被exit_notify函数调用
exit_notify函数被do_exit函数调用
后面的code就是退出代码,搜索do_exit函数,看有哪些退出代码
看宏SIGKILL,这里4代表非法指令的意思,可以在网上搜索宏SIGKILL
(5)怎么会有非法指令
看看我们编译应用程序的时候用的是所谓的eabi接口,我们内核也要支持eabi接口才行,eabi是可执行层应用程序的二进制接口,应用程序支持这个接口,是用编译器arm-none-linux-gnueabi编译出来的符合eabi接口的应用程序,那么内核应该支持这种接口。
(6)配置内核(以支持eabi)
make menuconfig
搜索eabi
重新编译内核,下载、烧写,启动