1.内核怎样启动第一个应用程序
(1)打开一个设备
open("/dev/console");
sys_dup(0);
sys_dup(0);
注释:open函数打开一个文件(第一个文件标号为0),sys_dup(0)表示复制第一个文件,所以printf,scanf,err三个都指向终端/dev/console。
(2)通过run_init_process来启动程序,这个函数如果传入的命令死循环命令,这个函数将不会返回,系统中这个优先执行init=xxxx,也就是命令行传入的参数(是uboot传给内核的),如果没有传入参数,则还有几个默认的命令,依次往下执行,直到有一个成功。
2.通过secureCRT连接开发板之后,用户可以在电脑上输入命令和开发板进行交互,这是因为在开发板的linux系统上运行着一个shell程序,即终端程序。
3.busybox:是众多命令的集合,集合了linux系统中基本的命令,ls命令等其实是一个链接指向busybox,执行ls命令的时候其实就是执行busybox(等同于执行busybox ls)。在busybox的源代码中就包含了ls.c,copy.c等等。
4.init程序(也就是0号进程)应该去读取一个配置文件,然后解析配置文件,最后根据配置文件执行用户程序。这样可以达到不同的系统系统启动之后能够实现不同的功能。
5.调用关系
busybox-->init_main
parse_inittab(解析init)
file=fopen(INITTAB, "r");//打开配置文件/etc/inittab
new_init_action //(1)创建一个init_action结构,并填充
//(2)把这个结构放入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);
打印:Please press Enter to activate this console.
等待回车
创建子进程
}
wpid = wait(NULL); //等待子进程退出
while(wpid > 0){
a->pid = 0; //退出后,就设置pid=0
}
}
new_init_action(ASKFIRST,bb_default_login_shell,VC_2);
||
new_init_action(ASKFIRST,"-/bin/sh","/dev/tty2");
static void new_init_action(int action, const char*command, const char *cons)
默认的配置要执行的操作:
格式:<id>:<runlevels>:<action>:<process>
::ctrlaltdel:reboot
::shutdown:umount -a -r
::restart:init
::asdfirst:-/bin/sh
tty2::asdfirst:-/bin/sh
tty3::asdfirst:-/bin/sh
tty4::asdfirst:-/bin/sh
::sysinit:/etc/init.d/rCS
inittab配置文件的格式:
<id>:<runlevels>:<action>:<process>
id=>/dev/id,用做终端:stdin,stdout,stderr:printf,scanf,err
runlevels:忽略掉
action:指示何时执行:包括sysinit,respawn,askfirst,wait,once,restart,ctrlaledel,and shutdown.
process:应用程序或脚本
6.最小根文件系统
(1)/dev/console以及/dev/null
(2)init应用程序=>busybox
(3)/etc/inittab
(4)配置指定的应用程序
(5)C库
7.busybox文件夹中的install文件有如何编译的教程
编译器需要在makefile中指定
最后不能直接在PC上安装!需要使用:
make CONIFG_PREFIX=/usr/myfs install
这个命令执行之后,在myfs文件夹中就有了bin、usr之类的文件夹。
8.创建设备文件
# mkdir dev
# sudo mknod console c 5 1
# sudo mknod null 1 3
9.构造inittab
# mkdir etc
# vi etc/inittab
conosle::askfirst:-/bin/sh
解析:这是一个最简单的配置文件
10.C库安装
拷贝C库的时候加-d参数,是让系统将链接文件拷贝为链接文件,而不要拷贝为实际的文件。
# mkdir /lib
# cp *.so* /usr/lib -d
11.制作映像文件
yaffs1是针对小页的nand flash,每一页512字节,每页2KB的nand flash要使用yaffs2。
制作yaffs2文件系统可以使用工具:yaffs_source_util_larger_small_page_nand.tar.bz2
# mkyaffs2image myfs my_fs.yaffs2
将生成的文件系统烧写到nand flash中。
12.这样制作好的文件系统是不能使用ps命令的,修改方法
# mkdir proc
# mount -t proc none /proc
13.12点是针对手动加上的,可以在修改配置文件中
配置文件中加入
::sysinit:/etc/init.d/rcS
# mkdir etc/init.d
# vi etc/init.d/rcS
mount -t proc none /proc
chmod +x etc/init.d/rcS
14.在13中也可以将mount -t proc none /proc替换为mount -a,mount -a这个命令会依赖一个文件etc/fstab
fstab的格式:
device mount-point type options dump fsck order
所以在fstab中写入:
proc /proc proc defaults 0 0
vi编辑保存后,使用cat命令打印出来检查一下:
# cat etc/init.d/rcS
注释:mount -a会去读取fstab这个文件,根据文件的指示去挂载相应的文件系统。
15.# cat /proc/mounts
查看当前挂载了那些系统
16.dev目录下应该有很多设备的驱动,如果每一个驱动都手动去创建,将会非常麻烦,所以linux提供了udev机制来解决这个问题。udev用来自动创建/dev/设备节点,busybox里面有一个mdev,是udev的简化版本。
mdev -s:表示将已有的设备节点先创建出来
在linux中,很多程序都必须先配置,然后才能编译
# ./configure --shared --prefix=/usr
--shared:表示会编译出动态库
--prefix:表示安装在usr目录下
17.NFS文件系统
(1)服务器允许某个目录被挂接:/etc/exports中定义这个目录
# sudo vi etc/exports
加入:/usr/myfs *(rw_sync_no_root_squash)
# sudo /etc/init.d/nfs-kernel-server restart
# sudo mount -t nfs 192.168.1.4:
/usr/myfs /mnt
检查能否自己挂载(PC机)
(2)开发板去挂接
# mkdir /mnt
# mount -t nfs -o nolock 192.168.1.19:/usr/myfs /mnt
18.NFS挂载启动
(1)服务器IP、目录
(2)开发板的IP