最近在写专利,中期答辩前的必备材料还差一篇论文......抽一个周五的晚上来完善一下之前留下的坑,慢慢来吧,先把这些弄完,希望可以在下月中旬之前把论文弄好,然后专心学习...好运
1、Linux根文件系统基本目录
- /bin : 该目录存放所有用户都可以使用的、基本的命令,这些命令可以在挂接其他文件系统之前就可以使用,所以/bin目录必须跟文件系统在同一个分区中
- /sbin : 该目录存放基本系统命令(shutdown、reboot等),即只有管理员才能使用的命令,他们用于启动系统、修复系统等。可以在挂接其他文件系统之前就可以使用这些命令,所以/sbin目录必须跟文件系统在同一个分区中。
- /dev : 该目录存放的是设备文件。设备文件是Linux独有的文件类型,在Linux系统下,以文件的方式访问各种外设,即通过读写某个设备文件操作某个具体硬件。如通过"/dev/ttySAC0"文件可以操作串口0。设备文件有两种:字符设备(c)和块设备(b)
- /etc : 该目录存放各种配置文件。对于PC的Linux系统,/etc目录下目录、文件非常多。这些目录、文件都是可选的,他们依赖于系统中所拥有的应用程序,依赖与这些程序是否需要配置文件。在嵌入式系统中,这些内容可以大为精减。
- /lib : 该目录下存放共享库和可加载模块(即驱动程序),共享库用于启动程序、运行根文件系统的可执行程序,比如/bin、/sbin目录下的程序。
- /home : 用户目录,对于每个用户,在/home下都有一个以用户名命名的子目录,里面存放用户相关的配置文件
- /root : 根用户目录(用户名为root)
- /usr : 该目录的内容可以存在另一个分区中,在系统启动后再挂接到根文件系统中的/usr目录下。里面存放的是共享、制度的程序和数据。
- /var : 与/usr目录相反,/var目录中存放可变的数据,比如spool目录(mail、news、打印机等),log文件、临时文件
- /proc : 这是一个空目录,常作为proc文件系统的挂接点。proc文件系统是个虚拟的文件系统,他没有实际的存储设备,里面的目录、文件都是由内核临时生成的,用来表示系统的运行状态,也可以操作其中的文件控制系统。
- /mnt : 用于挂接某个文件系统的挂接点,通常是空目录;也可以在里面创建一个空目录的字目录,比如/mnt/cdram、/mnt/hdal等,用来临时挂接光盘、硬盘。
- /tmp : 用来存放临时文件,通常是空目录。
对于最小busybox根文件系统至少包含下面文件夹:
- /etc/:存储重要的配置文件。
- /bin/:存储经常使用且开机时必须用到的运行文件。
- /sbin/:存储着开机过程中所需的系统运行文件。
- /lib/:存储/bin/及/sbin/的运行文件所需的链接库,以及Linux的内核模块。
- /dev/:存储设备文件。
2、移植busybox文件系统
2.1 什么是busybox
busybox是一个遵循GPL v2协议的开源项目(busybox官网)。busybox将众多的UNIX命令集合进一个很小的可执行程序中,可以用来替换GNU fileutils、shellutils等工具集。
busybox中各种命令与相应的GNU工具相比,所提供的选项较少,但能够满足一般应用。busybox为各种小型或者嵌入式系统提供了一个较完全的工具集。
busybox在编写过程中对文件大小进行优化,并考虑到资源有限的情况。与一般GNU工具集动辄几MB的体积相比,动态链接的busybox只有几百KB,即使静态链接也只有1MB左右。
busybox按照模块进行设计,可以很容易的加入、去除某些命令,或者增减命令的某些选项。
在创建最小的根文件系统时,使用busybox的话,只需要在/dev目录下创建必要的设备节点、在/etc目录下创建一些配置文件就可以啦,如果busybox使用动态链接,还要再/lib目录下包含库文件。
busybox支持uClibc和glibc库,对Linux2.2.x之后的内核支持良好。
2.2 init进程介绍和用户程序启动过程
2.2.1 内核如何启动init进程
init进程是内核启动的第一个(也是唯一一个)用户进程(进程号为1),他根据配置文件决定启动哪些程序,比如执行某些脚本、启动shell、运行用户指定的程序等。init进程是后续所有进程的发起者,比如init进行启动/sbin/init程序后,才能够在控制台上输入各种命令。
/* linux/init/目录下init.c文件 */
static noinline int init_post(void)
{
/* 1.
* 启动标准输入、输出、错误
*/
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
current->signal->flags |= SIGNAL_UNKILLABLE;
/* 2.
* ramdisk_execute_command指定了要运行的程序,运行它
* 如果命令行参数指定了rdinit=...,则ramdisk_execute_command等于这个参数指定的程序
* 否则如果/init存在,则ramdisk_execute_command就等于“/init”
* 否则ramdisk_execute_command为空
*/
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
/* 3.
* execute_command指定了要运行的程序,运行它
* 如果命令行参数指定了init=...,则execute_command等于这个参数指定的程序
* 否则execute_command为空
*/
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
/* 4.
* run_init_process()使用它参数所指定的程序来创建一个用户进程
* 一旦创建成功,它将不会返回
* 4.1
* 首先执行/sbin/init,根文件系统中存在,将跳转过去执行,不在返回init_post函数
* 4.2
* 如果根文件系统/sbin/init为空,则执行/etc/init,这个在我们制作的根文件系统是有的,所以跳
* 转过去执行了
* 4.3
* 在执行/sbin/init时,需要确保根文件系统已经被正确的挂载
*/
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
2.2.2 busybox init进程启动过程
2.3 移植busybox(提取密码:eje6)
2.3.1 编译安装busybox
1、解压
tar jxvf busybox-1.22.1.tar.bz2
2、配置
make menuconfig
Busybox Settings ->
general configuration ->
[*] don't use /usr //选中它 否则会破坏虚拟机
build options->
cross comliler prefix = arm-linux- //选择交叉编译工具
3、编译&安装
mkdir -p ~/work/my_rootfs //安装路径
make
make install CONFIG_PREFIX=~/work/my_rootfs
cd /work/my_rootfs
ls //查看是否安装成功
编译安装完毕之后,我们的文件系统就生成在 ~/work/my_roofs 目录下了
2.3.2 配置启动相关
1、创建 /etc/inittab(必须的,如果想简单测试,只需要保留console::askfirst:-/bin/sh,同时下面只要按照红色标题步骤即可创建一个简单的busybox文件系统)
mkdir -p ~/work/my_rootfs/etc
vi ~/work/my_rootfs/etc/inittab
# /etc/inittab
# 启动脚本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 启动 shell
console::askfirst:-/bin/sh
# 重启关机前 卸载文件系统
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
2、创建 /etc/init.d/rcS
mkdir -p ~/work/my_rootfs/etc/init.d
vi ~/work/my_rootfs/etc/init.d/rcS
# 这是一个脚本文件,用/bin/sh解析
#!/bin/sh
#开启DM9000网卡 down是关闭
ifconfig eth0 up
# 挂载文件系统
mount -a
# 使用内存文件系统
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# 设置IP
ifconfig eth0 192.168.0.100 #nfs不需要
# 挂载 /etc/fstab 中的文件系统
mount -a
exec /etc/rc.local
3、创建rc.local
vi /work/my_rootfs/etc/rc.local
#!/bin/sh
#加载环境变量,如果要设置某个应用程序自启动(需要环境变量),环境变量加加载应该放在程序启动前头
. /etc/profile //注意.后边有个空格!
4、创建/etc/fstab
vi ~/work/my_rootfs/etc/fstab
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
5、构建 /dev 目录(必须的)
mkdir -p ~/work/my_rootfs/dev
cd ~/work/my_rootfs/dev
sudo mknod console c 5 1
sudo mknod null c 1 3
6、创建其它目录
mkdir proc mnt tmp sys root usr
7、拷贝Lib(必须的)
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib
cp *.so* ~/work/my_rootfs/lib -d
cd /opt/FriendlyARM/toolschain/4.4.3/lib
cp *.so* ~/work/my_rootfs/lib -d