笔记第11课构建根文件系统

       第11课第1节 构建根文件系统之启动第1个程序
1、uboot:启动内核
2、内核:启动应用程序:首先要挂接根文件系统,然后再启动应用程序
3、构建根文件系统

内核怎样启动第一个应用程序
 1、"/dev/console"对应的是终端设备
    sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)   //代表标准输入
    (void) sys_dup(0);       //代表标准输出
    (void) sys_dup(0);       //代表标准错误
 2、run_init_process来启动命令行传入的"init=xxxx"或者"/sbin/init"。但是如果"/sbin/init"执行不成功,就往下执行"/etc/init"、"/bin/init"、"/bin/sh"
 
 
当我们启动内核用ps查看:
# ps
  PID  Uid        VSZ Stat Command
    1 0          3092 S   init
  771 0          3096 S   -sh  
 
 
       第11课第2节 构建根文件系统之init进程分析
启动开发板后用命令查看一下:       
# ls
bin         lib         mnt         root        tmp
dev         linuxrc     opt         sbin        usr
etc         lost+found  proc        sys

引出busybox:命令都是到busybox的链接
# ls -l /bin/ls
lrwxrwxrwx    1 0        0               7 Dec 24  2010 /bin/ls -> busybox
# ls -l /bin/cp
lrwxrwxrwx    1 0        0               7 Dec 24  2010 /bin/cp -> busybox
# ls
bin         lib         mnt         root        tmp
dev         linuxrc     opt         sbin        usr
etc         lost+found  proc        sys
# busybox ls
bin         lib         mnt         root        tmp
dev         linuxrc     opt         sbin        usr
etc         lost+found  proc        sys

我们可以发现我们的init进程也是到busybox的链接,所以我们要分析init进程就需要找busybox的源码来分析
# ls /sbin/init
/sbin/init
# ls /sbin/init -l
lrwxrwxrwx    1 0        0              14 Dec 24  2010 /sbin/init -> ../bin/busybox

回顾一下:
  uboot的目的是启动内核
  内核的目的是启动应用程序:先启动第一个进程init进程
  最终目的是启动客户的程序
 由于我们客户应用程序的不同,所以我们的init程序有如下几步:
  1、读取配置文件
  2、解析配置文件
  3、执行用户程序
  
busybox->init_main
 parse_inittab
     file = fopen(INITTAB, "r");//打开配置文件"/etc/inittab"
    
     new_init_action //①创建一个init_action结构,填充
    //②把这个结构放入init_action_list链表
 run_actions(SYSINIT);
     waitfor(a, 0);                          //执行应用程序,等待它执行完毕
         run(a);               //创建process子进程
         waitpid(runpid, &status, 0);     //等待它结束
     delete_init_action(a); //在init_action_list链表里删掉
 run_actions(WAIT);
      waitfor(a, 0);                          //执行应用程序,等待它执行完毕
         run(a);               //创建process子进程
         waitpid(runpid, &status, 0);     //等待它结束
     delete_init_action(a); //在init_action_list链表里删掉
 run_actions(ONCE);
     run(a);     //创建process子进程
     delete_init_action(a);      //在init_action_list链表里删掉
 while (1) {
     run_actions(RESPAWN);
         if (a->pid == 0) {
      a->pid = run(a);
      }
     run_actions(ASKFIRST);
         if (a->pid == 0) {
      a->pid = run(a);
        打印:"\nPlease press Enter to activate this console. "
        等待回车
        创建子进程
      }
     wpid = wait(NULL);//等待子进程退出
     while (wpid > 0) {
        a->pid = 0;     //退出后,就设置pid=0
     }
 }

 
/dev/console /dev/null
/etc/inittab
配置文件里指定的应用程序

init本身,即busybox 

最小根文件系统:
①/dev/console /dev/null
②init本身,即busybox
③/etc/inittab
④配置文件里指定的应用程序
⑤c库

 


从默认的new_init_action反推出默认的配置文件:

#inittab格式:
#<id>:<runlevels>:<action>:<process>

#runlevels:忽略
#action   :执行时机
# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
#                                  restart, ctrlaltdel, and shutdown.
#process  :应用程序或脚本

::CTRLALTDEL:reboot
::SHUTDOWN:umount -a -r
::RESTART:init
tty2::askfirst:-/bin/sh
tty3::askfirst:-/bin/sh
tty4::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS
  /* Reboot on Ctrl-Alt-Del */
  new_init_action(CTRLALTDEL, "reboot", "");
  /* Umount all filesystems on halt/reboot */
  new_init_action(SHUTDOWN, "umount -a -r", "");
  /* Swapoff on halt/reboot */
  if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
  /* Prepare to restart init when a HUP is received */
  new_init_action(RESTART, "init", "");
  /* Askfirst shell on tty1-4 */
  new_init_action(ASKFIRST, bb_default_login_shell, "");
  new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
  new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
  new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
  /* sysinit */
  new_init_action(SYSINIT, INIT_SCRIPT, "");
    
new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2"); 
static void new_init_action(int action, const char *command, const char *cons)
1、创建一个init_action结构,填充
2、把这个结构放入init_action_list链表  
  
在busybox目录下面搜索inittab,打开一个inittab文件例子
inittab格式:
<id>:<runlevels>:<action>:<process>

runlevels:忽略
action   :执行时机
process  :应用程序或脚本

id => /dev/id,用作终端:stdin,stdout,stderr:printf,scanf,err


猜测:既然我们配置文件的目的是启动不同的用户程序,那么:
      配置文件:1、指定应用程序
        2、何时执行

 

int main()
{
    printf("hello,world!\n"); //c库
    fopen();   //c库
    fwrite();
}

 

       第11课第3节 构建根文件系统之busybox.WMV
最小根文件系统:
①/dev/console /dev/null
②init本身,即busybox
③/etc/inittab
④配置文件里指定的应用程序
⑤c库

book@book-desktop:/work/system$ tar xjf busybox-1.7.0.tar.bz2 

注意首先要设置交叉编译工具链:改两个地方。
ARCH          ?= arm
CROSS_COMPILE ?= arm-linux-

查看E:\colin weidongshan\colin_kernel\official\busybox-1.7.0\INSTALL里面教你怎么编译busybox
  make menuconfig     # This creates a file called ".config"
    make                # This creates the "busybox" executable
    make install        # or make CONFIG_PREFIX=/path/from/root install 
    
book@book-desktop:/work/system/busybox-1.7.0$ make menuconfig
book@book-desktop:/work/system/busybox-1.7.0$ make
book@book-desktop:/work/system/busybox-1.7.0$ mkdir -p /work/nfs_root/first_fs
book@book-desktop:/work/system/busybox-1.7.0$ make CONFIG_PREFIX=/work/nfs_root/first_fs install

      
        

       第11课第4节 构建根文件系统之构建根文件系统.WMV 
一:
最小根文件系统:
 ①/dev/console /dev/null
 ②init本身,即busybox
 ③/etc/inittab
 ④配置文件里指定的应用程序
 ⑤c库
查看pc机上面的,做上面的①/dev/console /dev/null
book@book-desktop:/work/nfs_root/first_fs$ ls /dev/console  /dev/null -l
crw------- 1 root root 5, 1 2013-07-07 07:53 /dev/console
crw-rw-rw- 1 root root 1, 3 2013-07-06 19:18 /dev/null

book@book-desktop:/work/nfs_root/first_fs$ mkdir dev
book@book-desktop:/work/nfs_root/first_fs$ cd dev/
book@book-desktop:/work/nfs_root/first_fs/dev$ sudo mknod console c 5 1
book@book-desktop:/work/nfs_root/first_fs/dev$ sudo mknod null c 1 3

做③/etc/inittab:
book@book-desktop:/work/nfs_root/first_fs/dev$ cd ..
book@book-desktop:/work/nfs_root/first_fs$ ls
bin  dev  linuxrc  sbin  usr
book@book-desktop:/work/nfs_root/first_fs$ mkdir etc
book@book-desktop:/work/nfs_root/first_fs$ vi etc/inittab
里面加一句:console::askfirst:-/bin/sh

做⑤c库:
book@book-desktop:/work/nfs_root/first_fs$ mkdir lib
book@book-desktop:/work/nfs_root/first_fs$ cd /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib
book@book-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp *.so* /work/nfs_root/first_fs/lib -d
book@book-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cd /work/nfs_root/first_fs
book@book-desktop:/work/nfs_root/first_fs$ ls
bin  dev  etc  lib  linuxrc  sbin  usr
最小根文件系统已经做好了

二:制作yaffs映像文件,完善最小根文件系统
1、制作工具
book@book-desktop:/work/nfs_root/first_fs$ cd /work/system/
book@book-desktop:/work/system$ tar xjf yaffs_source_util_larger_small_page_nand.tar.bz2
book@book-desktop:/work/system$ cd Development_util_ok/
book@book-desktop:/work/system/Development_util_ok$ cd yaffs2
book@book-desktop:/work/system/Development_util_ok/yaffs2$ cd utils/
book@book-desktop:/work/system/Development_util_ok/yaffs2/utils$ pwd
/work/system/Development_util_ok/yaffs2/utils
book@book-desktop:/work/system/Development_util_ok/yaffs2/utils$ make
book@book-desktop:/work/system/Development_util_ok/yaffs2/utils$ sudo cp mkyaffs2image /usr/local/bin/
book@book-desktop:/work/system/Development_util_ok/yaffs2/utils$ sudo chmod +x /usr/local/bin/mkyaffs2image

book@book-desktop:/work/system/Development_util_ok/yaffs2/utils$ cd /work/nfs_root/
book@book-desktop:/work/nfs_root$ mkyaffs2image first_fs first_fs.yaffs2


遇到一个问题,不能启动提示:kernel panic - not syncing: No init found.  Try passing init= option to kernel.
问题解决:主要原因是编译器的问题,我用的是高版本的编译器,但是库加载的是低版本的编译器。换成低版本的编译器后,改一下环境变量如下
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/tools/gcc-3.4.5-glibc-2.3.6/bin"

至此第一个根文件系统初步已经做好了:启动内核之后,按回车
# cat /etc/inittab
console::askfirst:-/bin/sh
# ls
bin         etc         linuxrc     sbin
dev         lib         lost+found  usr

2、完善最小根文件系统:
当我想用PS命令:
# ps
  PID  Uid        VSZ Stat Command
ps: can't open '/proc': No such file or directory

即使我们创建了proc目录还是不行如下;
# ps
  PID  Uid        VSZ Stat Command
ps: can't open '/proc': No such file or directory
# mkdir proc
# ps
  PID  Uid        VSZ Stat Command
# mount -t proc none /proc
# ps
  PID  Uid        VSZ Stat Command
    1 0          3092 S   init    
    2 0               SW< [kthreadd]
    3 0               SWN [ksoftirqd/0]
    4 0               SW< [watchdog/0]
    5 0               SW< [events/0]
    6 0               SW< [khelper]
   55 0               SW< [kblockd/0]
   56 0               SW< [ksuspend_usbd]
   59 0               SW< [khubd]
   61 0               SW< [kseriod]
   73 0               SW  [pdflush]
   74 0               SW  [pdflush]
   75 0               SW< [kswapd0]
   76 0               SW< [aio/0]
  709 0               SW< [mtdblockd]
  744 0               SW< [kmmcd]
  762 0          3096 S   -sh
  777 0          3096 R   ps
# cd /proc/
# ls
1              744            diskstats      locks          sys
2              75             driver         meminfo        sysrq-trigger
3              76             execdomains    misc           sysvipc
4              762            fb             modules        timer_list
5              778            filesystems    mounts         tty
55             asound         fs             mtd            uptime
56             buddyinfo      interrupts     net            version
59             bus            iomem          partitions     vmstat
6              cmdline        ioports        scsi           yaffs
61             cpu            irq            self           zoneinfo
709            cpuinfo        kallsyms       slabinfo
73             crypto         kmsg           stat
74             devices        loadavg        swaps
# cd 1
# ls -l fd
lrwx------    1 0        0              64 Jan  1 02:00 0 -> /dev/console
lrwx------    1 0        0              64 Jan  1 02:00 1 -> /dev/console
lrwx------    1 0        0              64 Jan  1 02:00 2 -> /dev/console
# pwd
/proc/1


注;proc是我们内核提供的虚拟的文件系统
我们要首先就要把proc放到我们做好的文件系统里面:
book@book-desktop:/work/nfs_root/first_fs$ mkdir proc
book@book-desktop:/work/nfs_root/first_fs$ ls
bin  dev  etc  lib  linuxrc  proc  sbin  usr

如果不想手工挂载,要加一个配置文件:
book@book-desktop:/work/nfs_root/first_fs$ vi etc/inittab
 console::askfirst:-/bin/sh
 ::sysinit:/etc/init.d/rcS
那么我们还得创建脚本文件:/etc/init.d/rcS
book@book-desktop:/work/nfs_root/first_fs$ mkdir etc/init.d
book@book-desktop:/work/nfs_root/first_fs$ vi etc/init.d/rcS
 mount -t proc none /proc
book@book-desktop:/work/nfs_root/first_fs$ chmod +x etc/init.d/rcS
book@book-desktop:/work/nfs_root/first_fs$ cat etc/init.d/rcS
mount -t proc none /proc
当然我们可以通过etc/init.d/rcS来mount -t proc none /proc挂载根文件系统,我们还有另外一种办法通过mount -a
mount -a 就是读出etc/inittab,根据这个里面的内容来挂载系统.mount -a 命令依赖于文件etc/init.d/rcS
book@book-desktop:/work/nfs_root/first_fs$ vi etc/init.d/rcS
 #mount -t proc none /proc
 mount -a
book@book-desktop:/work/nfs_root/first_fs$ vi etc/fstab
book@book-desktop:/work/nfs_root/first_fs$ cat etc/fstab
#device    mount-point    type    options     dump   fsck    order
proc          /proc       proc    defaults      0     0
book@book-desktop:/work/nfs_root/first_fs$ cat etc/init.d/rcS
#mount -t proc none /proc
mount -a
实验一下:
book@book-desktop:/work/nfs_root/first_fs$ cd ..
book@book-desktop:/work/nfs_root$ mkyaffs2image first_fs first_fs.yaffs2
下载到开发板
# ps
  PID  Uid        VSZ Stat Command
    1 0          3092 S   init    
    2 0               SW< [kthreadd]
    3 0               SWN [ksoftirqd/0]
    4 0               SW< [watchdog/0]
    5 0               SW< [events/0]
    6 0               SW< [khelper]
   55 0               SW< [kblockd/0]
   56 0               SW< [ksuspend_usbd]
   59 0               SW< [khubd]
   61 0               SW< [kseriod]
   73 0               SW  [pdflush]
   74 0               SW  [pdflush]
   75 0               SW< [kswapd0]
   76 0               SW< [aio/0]
  709 0               SW< [mtdblockd]
  744 0               SW< [kmmcd]
  765 0          3096 S   -sh
  766 0          3096 R   ps
# cat /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / yaffs rw 0 0
proc /proc proc rw 0 0
但是
# ls /dev
console  null

在这里引入了udev,mdev概念:自动创建挂载设备
在busybox下面的mdev.txt里面有:
Here's a typical code snippet from the init script:
[1] mount -t sysfs sysfs /sys
[2] echo /bin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s

Of course, a more "full" setup would entail executing this before the previous
code snippet:
[4] mount -t tmpfs mdev /dev
[5] mkdir /dev/pts
[6] mount -t devpts devpts /dev/pts

book@book-desktop:/work/nfs_root$ cd first_fs/
book@book-desktop:/work/nfs_root/first_fs$ mkdir sys
book@book-desktop:/work/nfs_root/first_fs$ vi etc/fstab
book@book-desktop:/work/nfs_root/first_fs$ cat etc/fstab
#device    mount-point    type    options     dump   fsck    order
proc          /proc       proc    defaults      0     0
sysfs         /sys        sysfs   defaults      0     0
tmpfs         /dev        tmpfs   defaults      0     0

book@book-desktop:/work/nfs_root/first_fs$ vi etc/init.d/rcS
book@book-desktop:/work/nfs_root/first_fs$ cat etc/init.d/rcS
#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
实验一下:
book@book-desktop:/work/nfs_root/first_fs$ cd ..
book@book-desktop:/work/nfs_root$ mkyaffs2image first_fs first_fs.yaffs2
下载到开发板

到这里最小根文件系统已经很完善了


三:制作jffs2映像文件,完善最小根文件系统
1、制作工具
先删掉重新做:
book@book-desktop:/work/GUI/xwindow$ cd /work/GUI/xwindow/X/deps
book@book-desktop:/work/GUI/xwindow/X/deps$ ls
expat-2.0.1.tar.gz       libdrm-2.3.0.tar.bz2   openssl-0.9.8g.tar.gz
fontconfig-2.5.0.tar.gz  libpng-1.2.23.tar.bz2  zlib-1.2.3
freetype-2.3.5.tar.bz2   libxml2-2.6.30.tar.gz  zlib-1.2.3.tar.gz
book@book-desktop:/work/GUI/xwindow/X/deps$ cd zlib-1.2.3/
book@book-desktop:/work/GUI/xwindow/X/deps/zlib-1.2.3$ cd ..
book@book-desktop:/work/GUI/xwindow/X/deps$ rm -rf zlib-1.2.3

book@book-desktop:/work/GUI/xwindow/X/deps$ tar xzf zlib-1.2.3.tar.gz
book@book-desktop:/work/GUI/xwindow/X/deps$ cd zlib-1.2.3/
book@book-desktop:/work/GUI/xwindow/X/deps/zlib-1.2.3$ ./configure --shared --prefix=/usr
book@book-desktop:/work/GUI/xwindow/X/deps/zlib-1.2.3$ make
book@book-desktop:/work/GUI/xwindow/X/deps/zlib-1.2.3$ sudo make install

book@book-desktop:/work/GUI/xwindow/X/deps/zlib-1.2.3$ cd ..
book@book-desktop:/work/GUI/xwindow/X/deps$ cd /work/tools/
book@book-desktop:/work/tools$ tar xjf mtd-utils-05.07.23.tar.bz2
book@book-desktop:/work/tools$ cd mtd-utils-05.07.23/util/
book@book-desktop:/work/tools/mtd-utils-05.07.23/util$ make
book@book-desktop:/work/tools/mtd-utils-05.07.23/util$ sudo make install

book@book-desktop:/work/tools/mtd-utils-05.07.23/util$ cd /work/nfs_root/
book@book-desktop:/work/nfs_root$ mkfs.jffs2 -n -s 2048 -e 128KiB -d first_fs -o first_fs.jffs2

下载实验:
下载后我们还是以yaffs文件系统启动,显然是不行的,我们要设置一下参数:
原来的参数:bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
OpenJTAG> set bootargs noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0
OpenJTAG> save
OpenJTAG> boot
VFS: Mounted root (jffs2 filesystem).


四、NFS
1、配置开发板IP
# ifconfig eth0 up
# ifconfig
# ifconfig eth0 192.168.1.11
# ping 192.168.1.51
PING 192.168.1.51 (192.168.1.51): 56 data bytes
64 bytes from 192.168.1.51: seq=0 ttl=64 time=5.073 ms

2、手工挂接
a、从flash上启动根文件系统,再用命令挂接NFS
   挂接NFS条件:①服务器“允许”那个目录可被挂接
     ②单板去挂接
book@book-desktop:/work/nfs_root/first_fs$ sudo vi /etc/exports
/work/nfs_root/first_fs   *(rw,sync,no_root_squash)
重启
book@book-desktop:/work/nfs_root/first_fs$ sudo /etc/init.d/nfs-kernel-server restart
实验自己挂接自己:
book@book-desktop:/work/nfs_root/first_fs$ sudo mount -t nfs 192.168.1.51:/work/nfs_root/first_fs /mnt

单板挂接:
# mkdir /mnt
# mount -t nfs -o nolock 192.168.1.51:/work/nfs_root/first_fs /mnt
# ls /mnt
bin      etc      linuxrc  sbin     usr
dev      lib      proc     sys

比如我们在/work/nfs_root/first_fs下创建一个文件,在单板上能够立刻看到这个文件:
book@book-desktop:/work/nfs_root/first_fs$ echo hello > test.txt
book@book-desktop:/work/nfs_root/first_fs$ ls
bin  dev  etc  lib  linuxrc  proc  sbin  sys  test.txt  usr

# ls /mnt
bin       etc       linuxrc   sbin      test.txt
dev       lib       proc      sys       usr
# cat /mnt/test.txt
hello


b、直接从NFS启动:
NFS启动参数:①服务器IP,目录。 ②
重启可以看到启动参数:
bootargs=noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0
修改启动参数:在linux-2.6.22.6\Documentation的nfsroot.txt里面有参数的说明
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>

bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.51:/work/nfs_root/first_fs ip=192.168.1.11:192.168.1.51:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0

OpenJTAG> set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.51:/work/nfs_root/first_fs ip=192.168.1.11:192.168.1.51:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
OpenJTAG> save
OpenJTAG> boot
到这里网络文件系统已经搭建好了,这样你可以在服务器上面编辑代码,编译,然后在单板上面运行了。

 

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值