mini2440 root_qtopia 文件系统启动过程分析

转于:http://blog.csdn.net/wangrunmin/article/details/7583211

对于mini2440最新的root_qtopia文件系统启动过程,我在这里做了一些简单的分析,和大家分享一下经验,不足之处也请大家及时指出。 
      
其实,虽然root_qtopia这个文件系统的GUI是基于Qtopia的,但其初始化启动过程却是由大部分由busybox完成,Qtopiaqpe)只是在启动的最后阶段被开启。 
      
由于默认的内核命令行上有init=/linuxrc, 因此,在文件系统被挂载后,运行的第一个程序是根目录下的linuxrc。这是一个指向/bin/busybox的链接,也就是说,系统起来后运行的第一个程序也就是busybox本身。 
      
这种情况下,busybox首先将试图解析/etc/inittab来获取进一步的初始化配置信息(参考busybox源代码init/init.c中的parse_inittab()函数)。而事实上,root_qtopia中并没有/etc/inittab这个配置文件,根据busybox的逻辑,它将生成默认的配置。busyboxinit.c代码中的关于inittab的代码如下所示:

[cpp] view plaincopyprint?

static void parse_inittab(void)  

{  

#if ENABLE_FEATURE_USE_INITTAB   

    char *token[4];  

    parser_t *parser = config_open2("/etc/inittab", fopen_for_read);  

  

    if (parser == NULL)  

#endif   

    {  

        /* No inittab file - set up some default behavior */  

        /* 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 QUIT is received */  

        new_init_action(RESTART, "init", "");  

        /* Askfirst shell on tty1-4 */  

        new_init_action(ASKFIRST, bb_default_login_shell, "");  

//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users   

        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 */  

        <SPAN style="COLOR: #3333ff"><STRONG>new_init_action(SYSINIT, INIT_SCRIPT, "");</STRONG>  

</SPAN>     return;  

    }  

static void parse_inittab(void)

{

#if ENABLE_FEATURE_USE_INITTAB

char *token[4];

parser_t *parser = config_open2("/etc/inittab", fopen_for_read);

 

if (parser == NULL)

#endif

{

/* No inittab file - set up some default behavior */

/* 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 QUIT is received */

new_init_action(RESTART, "init", "");

/* Askfirst shell on tty1-4 */

new_init_action(ASKFIRST, bb_default_login_shell, "");

//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users

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, "");

return;

}

        其中,最重要的一个,就是new_init_action(SYSINIT, INIT_SCRIPT, ""),也就决定了接下去初始化的脚本是INIT_SCRIPT所定义的值。这个宏的默认值是"/etc/init.d/rcS".

下面是文件系统中/etc/init.d/rcS的内容, 也是我们要分析的重点

[cpp] view plaincopyprint?

#! /bin/sh    

  

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:   

runlevel=S   

prevlevel=N   

umask 022   

export PATH runlevel prevlevel   

  

#    

# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.    

#    

trap ":" INT QUIT TSTP   

/bin/hostname FriendlyARM   

  

/bin/mount -n -t proc none /proc   

/bin/mount -n -t sysfs none /sys   

/bin/mount -n -t usbfs none /proc/bus/usb   

/bin/mount -t ramfs none /dev   

  

echo /sbin/mdev > /proc/sys/kernel/hotplug   

/sbin/mdev -s   

/bin/hotplug   

# mounting file system specified in /etc/fstab    

mkdir -p /dev/pts   

mkdir -p /dev/shm   

/bin/mount -n -t devpts none /dev/pts -o mode=0622   

/bin/mount -n -t tmpfs tmpfs /dev/shm   

/bin/mount -n -t ramfs none /tmp   

/bin/mount -n -t ramfs none /var   

mkdir -p /var/empty   

mkdir -p /var/log   

mkdir -p /var/lock   

mkdir -p /var/run   

mkdir -p /var/tmp   

  

/sbin/hwclock -s   

  

syslogd   

/etc/rc.d/init.d/netd start   

echo " " > /dev/tty1   

echo "Starting networking..." > /dev/tty1   

sleep 1   

/etc/rc.d/init.d/httpd start   

echo " " > /dev/tty1   

echo "Starting web server..." > /dev/tty1   

sleep 1   

/etc/rc.d/init.d/leds start   

echo " " > /dev/tty1   

echo "Starting leds service..." > /dev/tty1   

echo " "   

sleep 1   

  

/sbin/ifconfig lo 127.0.0.1   

/etc/init.d/ifconfig-eth0   

  

/bin/qtopia &   

echo " " > /dev/tty1   

echo "Starting Qtopia, please waiting..." > /dev/tty1   

#! /bin/sh

 

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel

 

#

# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.

#

trap ":" INT QUIT TSTP

/bin/hostname FriendlyARM

 

/bin/mount -n -t proc none /proc

/bin/mount -n -t sysfs none /sys

/bin/mount -n -t usbfs none /proc/bus/usb

/bin/mount -t ramfs none /dev

 

echo /sbin/mdev > /proc/sys/kernel/hotplug

/sbin/mdev -s

/bin/hotplug

# mounting file system specified in /etc/fstab

mkdir -p /dev/pts

mkdir -p /dev/shm

/bin/mount -n -t devpts none /dev/pts -o mode=0622

/bin/mount -n -t tmpfs tmpfs /dev/shm

/bin/mount -n -t ramfs none /tmp

/bin/mount -n -t ramfs none /var

mkdir -p /var/empty

mkdir -p /var/log

mkdir -p /var/lock

mkdir -p /var/run

mkdir -p /var/tmp

 

/sbin/hwclock -s

 

syslogd

/etc/rc.d/init.d/netd start

echo " " > /dev/tty1

echo "Starting networking..." > /dev/tty1

sleep 1

/etc/rc.d/init.d/httpd start

echo " " > /dev/tty1

echo "Starting web server..." > /dev/tty1

sleep 1

/etc/rc.d/init.d/leds start

echo " " > /dev/tty1

echo "Starting leds service..." > /dev/tty1

echo " "

sleep 1

 

/sbin/ifconfig lo 127.0.0.1

/etc/init.d/ifconfig-eth0

 

/bin/qtopia &

echo " " > /dev/tty1

echo "Starting Qtopia, please waiting..." > /dev/tty1

下面就逐个来分析:

[cpp] view plaincopyprint?

//为启动环境设置必要的环境变量   

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:   

runlevel=S   

prevlevel=N   

umask 022   

export PATH runlevel prevlevel   

//为启动环境设置必要的环境变量

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel

1.PATH:指的是环境变量

2.runlevellinux操作系统自从开始启动至启动完毕需要经历几个不同的阶段,这几个阶段就叫做runlevel,同样,当linux操作系统关闭时也要经历另外几个不同的runlevelrunlevel可以认为是系统状态,形象一点,您可以认为runlevel有点象微软的windows操作系统中的Normalsafemode,和Command prompt only。进入每个runlevel都需要启动或关闭相应的一系列服务(services),这些服务(services)以初始化脚本的方式放置于目录/etc/rc.d/rc?.d/或者/etc/rc?.d下面(?代表runlevel的对应序号)。在大多数的linux发行版本中,通常有8runlevel

Runlevel System State

0 Halt the system

1 Single user mode

2 Basic multi user mode

3 Multi user mode

5 Multi user mode with GUI

6 Reboot the system

S, s Single user mode  单用户模式

多数的桌面的linux系统缺省的runlevel5,用户登陆时是图形界面,而多数的服务器版本的linux系统缺省的runlevel3,用户登陆时是字符界面,runlevel 12除了调试之外很少使用,runlevel sS并不是直接给用户使用,而是用来为Single user mode作准备。

linux的运行模式比起windows的启动模式的优势在于:你可以在系统空闲时使用.init工具切换你现在使用的runlevel,另外,当你关闭或者启动linux系统时你已经不知不觉中切换你的runlevel,系统关机进程需要调用runlevel(06)来关闭所有正在运行中的进程。

3.prelevel:未知,欢迎添加。

4.umask 022:在unix中文件权限是三类用户,三种权限。三类用户分别是文件所有者user(u),文件所有者所在主群组group(g)、其它用户others(o),三种权限分别是起读read(r)、写write(w)、执行execute(x)

umask 读写执行权限分别对应是

R -- 4

W -- 2

X -- 1

写是 2022表示group,other的写权限,umask=022掩码表示取消group , other用户的写权限。

设置umask022,是用以保证groupother有对安装的文件的读和执行许可,但无写权限。可以输入umask命令检查当前的设置。

功能说明:指定在建立文件时预设的权限掩码。

语  法:umask [-S][权限掩码]

补充说明:umask可用来设定[权限掩码]。[权限掩码]是由3个八进制的数字所组成,将现有的存取权限减掉权限掩码后,即可产生建立文件时预设的权限。

参  数:

-S  以文字的方式来表示权限掩码。

文件:用八进制基数666,即无x位(可执行位)rw- rw- rw-.执行位需由用户自行加入

5.export:这个比较简单,设置前边配置的环境变量。

[cpp] view plaincopyprint?

//设置机器的名字,就是进入终端后shell前边显示的名字   

/bin/hostname FriendlyARM   

//设置机器的名字,就是进入终端后shell前边显示的名字

/bin/hostname FriendlyARM

[cpp] view plaincopyprint?

//挂载各种文件系统及其他   

/bin/mount -n -t proc none /proc   

/bin/mount -n -t sysfs none /sys   

/bin/mount -n -t usbfs none /proc/bus/usb   

/bin/mount -t ramfs none /dev   

//挂载各种文件系统及其他

/bin/mount -n -t proc none /proc

/bin/mount -n -t sysfs none /sys

/bin/mount -n -t usbfs none /proc/bus/usb

/bin/mount -t ramfs none /dev

    挂载虚拟文件系统,/proc, /sys,并且在/dev目录上挂载一个ramfs,相当于把原本NAND Flash上的只读的/dev目录覆盖上一块可写的空的SDRAM。这里要注意的是/sys和挂载了ramfs/dev是正确创建设备节点的关键

    对于2.6.29内核来说,已经没有了devfs的支持,创建设备节点只有通过两种办法由文件系统完成:
    1) 制作文件系统镜像前用mknod手动创建好系统中所有的(包括可能有的)设备节点,并把这些节点文件一起做进文件系统镜像中;
    2)在文件系统初始化过程中,通过/sys目录所输出的信息,在/dev目录下动态的创建系统中当前实际有的设备节点。
    显然,方法1)有很大的局限性,仅限于没有设备动态增加或减少的情况,不适用于很多设备热插拔的情况,比如U盘,SD卡等等。方法2)是目前大多数PCLinux的做法(基于udev实现)。这种方法有两个前提:/sys目录挂载和一个可写的/dev目录。这也就是为什么我们在这里需要挂载/sysramfs/dev目录上。事实上,这种方法最早就是为热插拔设计的,你可以理解为当系统启动是,所有设备一下子全部插入了进来。
    这里有一点要说明的是,在文件系统初始化跑到这里之前,原本的/dev目录下必须有一个的设备节点:/dev/console

[cpp] view plaincopyprint?

<STRONG>echo /sbin/mdev > /proc/sys/kernel/hotplug  

/sbin/mdev -s  

/bin/hotplug</STRONG>  

echo /sbin/mdev > /proc/sys/kernel/hotplug

/sbin/mdev -s

/bin/hotplug

  echo /sbin/mdev > /proc/sys/kernel/hotplug:设置系统的hotplug程序为mdev,即当设备热插拔时,由mdev接收来自内核的消息并作出相应的回应, 比如挂载U盘。busybox的mdev是一个精简了的udev管理程序,它可以间接的以hotplug方式被内核调用,进而在arm平台上/dev目录下动态创建设备 节点,因为hotplug会被内核发送uevent之前调用,所以如果动态可插拔设备很多,很频繁,那么每次内核都会调用elf格式的用户空间的 hotplug,生成一个独立的hotplug程序来处理,所以hotplug是一个非常笨重的实现方法,但是在我们的arm开发板上,可插拔设备并没有想象中的频繁。所以完全可以在不复杂的嵌入式设备上使用mdev来管理动态节点,方法也很简单,就是 在rcS脚本中加入下面一句,将用户空间的应用程序路径传递给内核,"echo /sbin/mdev > /proc/sys/kernel/hotplug”,之后kernel会在每次设备出现变动时调用上面一句传递进去的用户空间应用程序/sbin/mdev来处理对应的信息,进而mdev应用程序操作/dev目录下的设备,进行添加或删除。

    /sbin/mdev -s:在/dev目录下建立必要的设备节点。以‘-s’为参数调用位于 /sbin目录写的mdev(其实是个链接,作用是传递参数给/bin目录下的busybox程序并调用它),mdev扫描 /sys/class /sys/block 中所有的类设备目录,如果在目录中含有名为“dev”的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev 下创建设备节点文件。一般只在启动时才执行一次 “mdev -s”

    mdev的另外一个很有用的地方是,他可以通过procsys文件系统来动态整理出注册的设备,进而到/dev/下生成他们对应的节点,使用该功能之前必须mountprocsys文件系统,然后简单的执行下面的一句就弯成了:mdev -s。这就是上一段代码做的工作。

    对于mdev,需要注意的是,文件系统里存在/etc/mdev.conf文件,它包含了mdev的配置信息。对于友善的文件系统/etc下的这个mdev.conf文件,如果自己制作的系统的/etc下没有这个文件,就不能进入qt程序,一直停在qt黄色界面不动,而且触摸屏也不好使,如果有这个文件,但是里面没有内容的话就能进入文件系统,但是触摸屏不好使,如果这个文件加上友善mdev.conf的内容后,既能进入qt程序,而且触摸屏也好使。通过这个文件,我们可以自定义一些设备节点的名称或链接来满足特定的需要。下面是root qtopiamdev.conf的内容:

[cpp] view plaincopyprint?

# system all-writable devices   

full        0:0    0666  

null        0:0    0666  

ptmx        0:0    0666  

random        0:0    0666  

tty        0:0    0666  

zero        0:0    0666  

  

# console devices   

tty[0-9]*    0:5    0660  

vc/[0-9]*    0:5    0660  

  

# serial port devices   

s3c2410_serial0    0:5    0666    =ttySAC0  

s3c2410_serial1    0:5    0666    =ttySAC1  

s3c2410_serial2    0:5    0666    =ttySAC2  

s3c2410_serial3    0:5    0666    =ttySAC3  

  

# loop devices    

loop[0-9]*    0:0    0660    =loop/  

  

# i2c devices   

i2c-0        0:0    0666    =i2c/0  

i2c-1        0:0    0666    =i2c/1  

  

# frame buffer devices   

fb[0-9]        0:0    0666  

  

# input devices   

mice        0:0    0660    =input/  

mouse.*        0:0    0660    =input/  

event.*        0:0    0660    =input/  

ts.*        0:0    0660    =input/  

  

# rtc devices   

rtc0        0:0    0644    >rtc  

rtc[1-9]    0:0    0644  

  

# misc devices   

mmcblk0p1    0:0    0600    =sdcard */bin/hotplug  

sda1        0:0    0600    =udisk * /bin/hotplug  

# system all-writable devices

full        0:0    0666

null        0:0    0666

ptmx        0:0    0666

random        0:0    0666

tty        0:0    0666

zero        0:0    0666

 

# console devices

tty[0-9]*    0:5    0660

vc/[0-9]*    0:5    0660

 

# serial port devices

s3c2410_serial0    0:5    0666    =ttySAC0

s3c2410_serial1    0:5    0666    =ttySAC1

s3c2410_serial2    0:5    0666    =ttySAC2

s3c2410_serial3    0:5    0666    =ttySAC3

 

# loop devices

loop[0-9]*    0:0    0660    =loop/

 

# i2c devices

i2c-0        0:0    0666    =i2c/0

i2c-1        0:0    0666    =i2c/1

 

# frame buffer devices

fb[0-9]        0:0    0666

 

# input devices

mice        0:0    0660    =input/

mouse.*        0:0    0660    =input/

event.*        0:0    0660    =input/

ts.*        0:0    0660    =input/

 

# rtc devices

rtc0        0:0    0644    >rtc

rtc[1-9]    0:0    0644

 

# misc devices

mmcblk0p1    0:0    0600    =sdcard */bin/hotplug

sda1        0:0    0600    =udisk * /bin/hotplug

      可以看到,原本串口驱动注册的设备名是s3c2410_serial0, s3c2410_serial1s3c2410_serial2,而mdev则会在/dev目录下对应生成ttySAC0, ttySAC1ttySAC2以符合应用程序对于串口设备名称的习惯。同样的,/dev/sdcard/dev/udisk永远分别指向SD卡和U盘的第一个分区。(所以,用那些没有分区表的SD卡或U盘的兄弟知道原因了吧...)。对于这一段最后两句:

[cpp] view plaincopyprint?

# misc devices   

mmcblk0p1    0:0    0600    =sdcard */bin/hotplug  

sda1        0:0    0600    =udisk * /bin/hotplug  

# misc devices

mmcblk0p1    0:0    0600    =sdcard */bin/hotplug

sda1        0:0    0600    =udisk * /bin/hotplug

     这两句配置的意思是当SD卡或者U盘插入/拔出时,将这个消息传递给自定义的热插拔handler, /bin/hotplug. 这个程序是友善之臂开发的用于自动挂载可移动设备的,目前是SD卡和U盘。它的逻辑很简单,将SD卡或者U盘的第一个分区作为FAT/FAT32挂载到/sdcard或者/udisk.但这也同时带来一个问题,当SD卡或者U盘上没有分区表或者第一个分区不是FAT/FAT32格式的时候,它就玩不转了,兄弟们要小心了:)
    
这是/bin/hotplug里的二进制数据片段,可以看到我上面说的逻辑:
000010d0h: 52 00 00 00 4D 00 00 00 00 00 00 00 41 00 00 00 ; R...M.......A...
000010e0h: 43 00 00 00 54 00 00 00 49 00 00 00 4F 00 00 00 ; C...T...I...O...
000010f0h: 4E 00 00 00 00 00 00 00 44 00 00 00 45 00 00 00 ; N.......D...E...
00001100h: 56 00 00 00 4E 00 00 00 41 00 00 00 4D 00 00 00 ; V...N...A...M...
00001110h: 45 00 00 00 00 00 00 00 61 00 00 00 64 00 00 00 ; E.......a...d...
00001120h: 64 00 00 00 00 00 00 00 72 00 00 00 65 00 00 00 ; d.......r...e...
00001130h: 6D 00 00 00 6F 00 00 00 76 00 00 00 65 00 00 00 ; m...o...v...e...
00001140h: 00 00 00 00 2F 00 00 00 64 00 00 00 65 00 00 00 ; ..../...d...e...
00001150h: 76 00 00 00 2F 00 00 00 75 00 00 00 64 00 00 00 ; v.../...u...d...
00001160h: 69 00 00 00 73 00 00 00 6B 00 00 00 00 00 00 00 ; i...s...k.......
00001170h: 2F 00 00 00 64 00 00 00 65 00 00 00 76 00 00 00 ; /...d...e...v...
00001180h: 2F 00 00 00 73 00 00 00 64 00 00 00 63 00 00 00 ; /...s...d...c...
00001190h: 61 00 00 00 72 00 00 00 64 00 00 00 00 00 00 00 ; a...r...d.......
000011a0h: 4D 00 00 00 44 00 00 00 45 00 00 00 56 00 00 00 ; M...D...E...V...
000011b0h: 00 00 00 00 6D 00 00 00 6D 00 00 00 63 00 00 00 ; ....m...m...c...
000011c0h: 62 00 00 00 6C 00 00 00 6B 00 00 00 30 00 00 00 ; b...l...k...0...
000011d0h: 70 00 00 00 31 00 00 00 00 00 00 00 73 00 00 00 ; p...1.......s...
000011e0h: 64 00 00 00 61 00 00 00 31 00 00 00 00 00 00 00 ; d...a...1.......
000011f0h: 76 00 00 00 66 00 00 00 61 00 00 00 74 00 00 00 ; v...f...a...t...
00001200h: 00 00 00 00 2F 00 00 00 64 00 00 00 65 00 00 00 ; ..../...d...e...
00001210h: 76 00 00 00 2F 00 00 00 77 00 00 00 61 00 00 00 ; v.../...w...a...
00001220h: 74 00 00 00 63 00 00 00 68 00 00 00 64 00 00 00 ; t...c...h...d...
00001230h: 6F 00 00 00 67 00 00 00 00 00 00 00 9A B2 01 81 ; o...g.......
.?
00001240h: B0                                              ; ?

[cpp] view plaincopyprint?

# mounting file system specified in /etc/fstab   

mkdir -p /dev/pts  

mkdir -p /dev/shm  

/bin/mount -n -t devpts none /dev/pts -o mode=0622  

/bin/mount -n -t tmpfs tmpfs /dev/shm  

/bin/mount -n -t ramfs none /tmp  

/bin/mount -n -t ramfs none /var  

mkdir -p /var/empty  

mkdir -p /var/log  

mkdir -p /var/lock  

mkdir -p /var/run  

mkdir -p /var/tmp  

# mounting file system specified in /etc/fstab

mkdir -p /dev/pts

mkdir -p /dev/shm

/bin/mount -n -t devpts none /dev/pts -o mode=0622

/bin/mount -n -t tmpfs tmpfs /dev/shm

/bin/mount -n -t ramfs none /tmp

/bin/mount -n -t ramfs none /var

mkdir -p /var/empty

mkdir -p /var/log

mkdir -p /var/lock

mkdir -p /var/run

mkdir -p /var/tmp

就像注释中所说的,这是用来挂载其他一些常用的文件系统,并在/var目录下(同样是ramfs,可写的)新建必要的目录。

[cpp] view plaincopyprint?

/sbin/hwclock -s  

/sbin/hwclock -s

用来设定系统时间的,从硬件RTC中获取,不过似乎有问题

接下来就是启动系统服务了,包括log记录,网络, http server和自定义的"跑马灯服务"

[cpp] view plaincopyprint?

syslogd  

/etc/rc.d/init.d/netd start  

echo "                        " > /dev/tty1  

echo "Starting networking..." > /dev/tty1  

sleep 1  

/etc/rc.d/init.d/httpd start  

echo "                        " > /dev/tty1  

echo "Starting web server..." > /dev/tty1  

sleep 1  

/etc/rc.d/init.d/leds start  

echo "                        " > /dev/tty1  

echo "Starting leds service..." > /dev/tty1  

echo "                        "  

sleep 1  

syslogd

/etc/rc.d/init.d/netd start

echo "                        " > /dev/tty1

echo "Starting networking..." > /dev/tty1

sleep 1

/etc/rc.d/init.d/httpd start

echo "                        " > /dev/tty1

echo "Starting web server..." > /dev/tty1

sleep 1

/etc/rc.d/init.d/leds start

echo "                        " > /dev/tty1

echo "Starting leds service..." > /dev/tty1

echo "                        "

sleep 1

启动一系列服务:
syslogd -
用于记录内核和应用程序debug信息
netd -     inetd, 一个挂载启动各种网络相关服务的看守进程
httpd -    http server看守进程
leds  -   跑马灯看守进程

其中,inetd的配置文件为/etc/inetd.conf,这是文件内容:

[cpp] view plaincopyprint?

# /etc/inetd.conf:  see inetd(8) for further informations.   

echo     stream  tcp    nowait    root    internal  

echo     dgram   udp    wait    root    internal  

daytime  stream  tcp    nowait    root    internal  

daytime  dgram   udp    wait    root    internal  

time     stream  tcp    nowait    root    internal  

time     dgram   udp    wait    root    internal  

  

# These are standard services.   

#   

ftp    stream    tcp    nowait    root    /usr/sbin/ftpd        /usr/sbin/ftpd  

telnet    stream    tcp    nowait    root    /usr/sbin/telnetd    /usr/sbin/telnetd -i  

# /etc/inetd.conf:  see inetd(8) for further informations.

echo     stream  tcp    nowait    root    internal

echo     dgram   udp    wait    root    internal

daytime  stream  tcp    nowait    root    internal

daytime  dgram   udp    wait    root    internal

time     stream  tcp    nowait    root    internal

time     dgram   udp    wait    root    internal

 

# These are standard services.

#

ftp    stream    tcp    nowait    root    /usr/sbin/ftpd        /usr/sbin/ftpd

telnet    stream    tcp    nowait    root    /usr/sbin/telnetd    /usr/sbin/telnetd -i

可以看到,这里启动的网络服务有两个: 1ftp server 2)telnet server。有关网络服务的端口和协议等具体信息,可以参考/etc/services, /etc/protocols
再接下来

[cpp] view plaincopyprint?

/sbin/ifconfig lo 127.0.0.1  

/etc/init.d/ifconfig-eth0  

/sbin/ifconfig lo 127.0.0.1

/etc/init.d/ifconfig-eth0

配置网络设备(网卡)
1)设定本机回环地址为127.0.0.1
2
)运行网卡设置脚本/etc/init.d/ifconfig-eth0
下面是/etc/init.d/ifconfig-eth0的内容, 加入了我的一些注释:

[cpp] view plaincopyprint?

#!/bin/sh   

  

echo -n Try to bring eth0 interface up......>/dev/ttySAC0  

  

//判断/etc/eth0-setting文件是否存在   

if [ -f /etc/eth0-setting ] ; then  

                     //读取配置文件信息   

    source /etc/eth0-setting  

  

                      //如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了   

    if grep -q "^/dev/root / nfs " /etc/mtab ; then  

        echo -n NFS root ... > /dev/ttySAC0  

                     //否则,根据配置文件中的MAC, IP, Mask和Gateway通过ifconfig命令相应地配置网卡    

    else  

        ifconfig eth0 down  

        ifconfig eth0 hw ether $MAC  

        ifconfig eth0 $IP netmask $Mask up  

        route add default gw $Gateway  

    fi  

  

                     //将配置文件中的DNS设置写入/etc/resolv.conf使之生效   

    echo nameserver $DNS > /etc/resolv.conf  

#配置文件不存在,使用默认配置   

else  

                         

                      //如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了   

    if grep -q "^/dev/root / nfs " /etc/mtab ; then  

        echo -n NFS root ... > /dev/ttySAC0  

    else  

                     //将网卡的IP地址设定为192.168.1.230   

    /sbin/ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up  

    fi  

fi  

  

echo Done > /dev/ttySAC0  

#!/bin/sh

 

echo -n Try to bring eth0 interface up......>/dev/ttySAC0

 

//判断/etc/eth0-setting文件是否存在

if [ -f /etc/eth0-setting ] ; then

                     //读取配置文件信息

    source /etc/eth0-setting

 

                      //如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了

    if grep -q "^/dev/root / nfs " /etc/mtab ; then

        echo -n NFS root ... > /dev/ttySAC0

                     //否则,根据配置文件中的MAC, IP, Mask和Gateway通过ifconfig命令相应地配置网卡

    else

        ifconfig eth0 down

        ifconfig eth0 hw ether $MAC

        ifconfig eth0 $IP netmask $Mask up

        route add default gw $Gateway

    fi

 

                     //将配置文件中的DNS设置写入/etc/resolv.conf使之生效

    echo nameserver $DNS > /etc/resolv.conf

#配置文件不存在,使用默认配置

else

                      

                      //如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了

    if grep -q "^/dev/root / nfs " /etc/mtab ; then

        echo -n NFS root ... > /dev/ttySAC0

    else

                     //将网卡的IP地址设定为192.168.1.230

    /sbin/ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up

    fi

fi

 

echo Done > /dev/ttySAC0

可以看到,NFS自动识别就是靠判断/etc/mtab中是否有nfs的挂载记录实现的。
下面是root qtopia文件系统中/etc/eth0-settings文件:

[cpp] view plaincopyprint?

IP=192.168.1.230  

Mask=255.255.255.0  

Gateway=192.168.1.1  

DNS=192.168.1.1  

MAC=08:90:90:90:90:90  

IP=192.168.1.230

Mask=255.255.255.0

Gateway=192.168.1.1

DNS=192.168.1.1

MAC=08:90:90:90:90:90


最后,启动Qtopia GUI环境:

[cpp] view plaincopyprint?

/bin/qtopia &  

echo "                                  " > /dev/tty1  

echo "Starting Qtopia, please waiting..." > /dev/tty1  

/bin/qtopia &

echo "                                  " > /dev/tty1

echo "Starting Qtopia, please waiting..." > /dev/tty1

可以看到,这里Qtopia是通过运行/bin/qtopia来启动的。事实上,/bin/qtopia也是一个脚本,它的任务是设定Qtopia运行必要的环境, 最后通过调用qpe可执行文件真正启动Qtopia。这是它的全部内容,我加入了一些注释:

[cpp] view plaincopyprint?

#!/bin/sh   

  

#tslib环境变量设置,包括了touchscreen设备文件,tslib配置文件,tslib plug-in位置和touchscreen校准数据文件   

export TSLIB_TSDEVICE=/dev/input/event0   

export TSLIB_CONFFILE=/usr/local/etc/ts.conf  

export TSLIB_PLUGINDIR=/usr/local/lib/ts  

export TSLIB_CALIBFILE=/etc/pointercal  

#Qtopia环境变量设置,设定了Qtopia主要文件位置   

export QTDIR=/opt/Qtopia  

export QPEDIR=/opt/Qtopia  

#设定PATH和LD_LIBRARY_PATH以包含Qtopia的可执行文件和共享库文件,方便Qtopia正确运行   

export PATH=$QTDIR/bin:$PATH  

export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH  

  

#通过判断/sys/devices/virtual/input/input0/uevent中是否包含touchscreen信息使Qtopia自动识别touchscreen和USB鼠标   

TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent  

if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen < $TS_INFO_FILE" ]; then  

    export QWS_MOUSE_PROTO="TPanel:/dev/input/event0 USB:/dev/input/mice"  

    if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then  

        rm /etc/pointercal  

    fi  

else  

    export QWS_MOUSE_PROTO="USB:/dev/input/mice"  

    >/etc/pointercal  

fi  

unset TS_INFO_FILE  

  

export QWS_KEYBOARD=TTY:/dev/tty1  

export KDEDIR=/opt/kde  

  

export HOME=/root  

  

#通过调用/opt/Qtopia/bin/qpe真正启动Qtopia   

exec $QPEDIR/bin/qpe 1>/dev/null 2>/dev/null  

#!/bin/sh

 

#tslib环境变量设置,包括了touchscreen设备文件,tslib配置文件,tslib plug-in位置和touchscreen校准数据文件

export TSLIB_TSDEVICE=/dev/input/event0

export TSLIB_CONFFILE=/usr/local/etc/ts.conf

export TSLIB_PLUGINDIR=/usr/local/lib/ts

export TSLIB_CALIBFILE=/etc/pointercal

#Qtopia环境变量设置,设定了Qtopia主要文件位置

export QTDIR=/opt/Qtopia

export QPEDIR=/opt/Qtopia

#设定PATH和LD_LIBRARY_PATH以包含Qtopia的可执行文件和共享库文件,方便Qtopia正确运行

export PATH=$QTDIR/bin:$PATH

export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH

 

#通过判断/sys/devices/virtual/input/input0/uevent中是否包含touchscreen信息使Qtopia自动识别touchscreen和USB鼠标

TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent

if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen < $TS_INFO_FILE" ]; then

    export QWS_MOUSE_PROTO="TPanel:/dev/input/event0 USB:/dev/input/mice"

    if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then

        rm /etc/pointercal

    fi

else

    export QWS_MOUSE_PROTO="USB:/dev/input/mice"

    >/etc/pointercal

fi

unset TS_INFO_FILE

 

export QWS_KEYBOARD=TTY:/dev/tty1

export KDEDIR=/opt/kde

 

export HOME=/root

 

#通过调用/opt/Qtopia/bin/qpe真正启动Qtopia

exec $QPEDIR/bin/qpe 1>/dev/null 2>/dev/null

到此为止,文件系统从初始化到最终启动Qtopia GUI环境的全部过程就结束了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值