|
FreeBSD 核心 (1)
|
|
--------
disk no used
label
-------------------------------------------------------------
<-boot->|<---------boot2-------------->| |<--unix file system--
FreeBSD用的block#0--#14的15个block里面,含有读入freebsd的程序,bootease
只在block#0里面,在15个block中并没有。它的作用
。读入mbr,找freebsd的分区
。读入最初的15个block,到物理内存中0x0001000
。跳转到相当于block#2的内存位置
然后,屏幕表示为:
。。。
。。。
boot:
(参数说明略)
它的source是/usr/src/sys/i386/boot/biosboot,make之后,生成两个文件:
boot1,boot2分别写入block#1,block#2--#14中。
一般,一个物理的unix分区理论上可以有8个,比如swap,unix system等。
boot2部分是boot program,它读入kernel的文件名和option。然后
。找boot label指定的分区。
。构造unix filesystem,找指定的kernel
。从开始执行文件,text,data的顺序向物理内存读入。对bss清零。
。以option的选择,向开始位置跳转。
1.3.2 kernel的初始化动作
boot program执行之后,转向kernel的text段开始进行初始化,即先执行
locore.s的text段。因此是虚拟内存还没有发生作用,locore.s的开始部分必
须对offset进行补正。locore.s的作用是
。保存从boot program过来的option
。设定虚拟的stacker
。检测cpu的module
。对自己的bss空间进行0初始化
。为使虚拟内存工作,要保证最少的管理信息。然后是虚拟空间动作。
也就是,调用cpu有强的依赖关系的过程init386()(@i386/i386/machdep.c),
然后进行kernel内的管理信息初始化,i/o设备的登记,生成4个kernel process
,再调用main()(@kern/init_main.c)。当main()返回locore.s时,应该有如下
5个进程:
PID TT STAT TIME COMMAND
0 ?? DLs 0:00.17 (swapper)
1 ?? Is 0:00.19 /sbin/init --
2 ?? DL 0:56.60 (pagedaemon)
3 ?? DL 0:00.06 (vmdaemon)
4 ?? DL 6:07.65 (updata)
从locore.s返回到process #1,/sbin/init开始动作,然后转向freebsd的普通
动作。
init386()和main()的处理大致如下:
。init386()
GDT和LDT,IDT,task stages处理的初始化,例外处理等locore.s没做的
事情,虚拟内存初始化。然后,根据boot program的参数,增加物理内
存page数。然后,作成process #0的雏形。
。main()
逐步调用构成kernel模块的的初始化部分。
FreeBSD核心探讨(翻译)3
(续上,liangvy.icewolf.leon翻译)
但是,kernel构成的各个模块的初始化子程序一个个的列举出来运行很显然是
不行的。通常是利用时间连表的技能来运行它(ld command)。也就是,程序
是以很多个source分开编译和联结。相同的模块名字就对应于相同的地址来进
行调用。它在时间链表里面自动调节执行。
初始化时候,main()函数要call的模块利用在sys/kernel.h里面定义的宏
SYSINIT()和SYSINIT_KT()进行登记。这样,kernel在link的时候,ld命令就
能够得到那些信息和进行配置列表。这个列表就是kernel的组成模块的初始化
routine的登记。检查source,
就可以找到初始化routine的部分。
如表:
print_caddr_t(copyright) kern/init_main.c
vm_men_init(NULL) vm/vm_init.c
syctl_order(&sysctl_) kern/kern_sysctl.c
kmemnit(NULL) kern/kern_malloc.c
fpu_init(NULL) i386/i386/math_emulate.c
cpu_startup(NULL) i386/i386/machdep.c
gnufpu_init(NULL) miscfs/devfs/devfs_tree.c
...
各个device的major号与处理routine的登记 (major循序号)
...
configure(NULL) i386/i386/autoconf.c
proc0_init(NULL) kern/init_main.c
rqinit(NULL) kern/kern_synch.c
vm_init_limits(&proc0) vm/vm_glue.c
vfsinit(NULL) kern/vfs_init.c
elf_insert_brand_entry(&linux_brand) i386/linux/linux_sysvec.c
initclocks(NULL) kern/kern_clock.c
mbinit(NULL) kern/uipc_mbuf.c
clst_init(NULL) kern/tty_subr.c
shmnit(NULL) kern/sysv_shm.c
seminit(NULL) kern/sysv_sem.c
msginit(NULL) kern/sysc_msg.c
kludge_splimp(&x_save_spl) kern/uipc_domain.c
ifinit(NULL) net/if.c
domaininit(NULL) kern/uipc_domain.c
kludge_splx(&x_save_spl) kern/uipc_domain.c
kmstartup(NULL) kern/subr_prof.c
sched_setup(NULL) kern/init_main.c
xxx_vfs_mountroot(NULL) kern/init_main.c
xxx_vfs_root_fdtab(NULL) kern/init_main.c
swapinit(NULL) kern/init_main.c
proc0_post(NULL) kern/init_main.c
kthread_init(NULL) kern/init_main.c||
kproc_start(&page_kp) vm/vm_pageout.c||
kproc_start(&vm_kp) vm/vm_pageout.c||
kproc_start(&up_kp) kern/vfs_bio.c||
scheduler(NULL) vm/vm_glue.c
(||表示有多个程序)
proc-post()被呼叫后,main()就是在对应process 0 的kernel的虚拟
内存里动作。kthread_init(),kproc_start(&page_kp),kproc_start(&vm_kp)
,kproc_start(&up_kp)等这几个进程,在fork()后相继被调用。它就是相
应的进程1,2,3,4等。
除process 1 以外,其他的进程调用并不返回调用的地址。(也就是,main()
的跟随执行后,并不返回locore.s)。对于process #1的kernel的虚拟内存,
在kthread_init()返回后,main()的跟随就完了,回到locore.s后,process #1
的进程空间的配置文件/sbin/init就被执行。
main()在process #0对应的kernel虚拟内存运行后,进入时间链表scheduler()。
这个并不返回。那现在就有五个进程了。
然后,fork() 的调用在下面说明。
1,分配process ID,保证struct proc()用的空间。
2,复制父亲的process的虚拟内存空间,作成物理内存的变换表。对
应两个进程,采用相对应的物理内存表。
3,给回父亲的struct proc和struct user,然后对子进程的struct和
struct user进行初始化。
4,kernel的stacker也进行复制。
5,返回父进程后,标记生成的子进程。完成处理。
但是,process #0 -- 4 这五个进程的虚拟内存里面什么都没有。这些是核心
进程的特殊部分。进程0,2,3是调节系统存在的进程的执行优先级,监视物理
内存的不足,如果不够就使用swap区进行交换。进程4的作用就是定期调查核心
的unix文件系统的管理信息与驱动程序的管理信息的一致性,使它的信息一直
是最新的。
1.3.3 /sbin/init
从kernel里面看,/sbin/init就是单一的进程空间里动作,与一般的
user program一样,提供user使用的unix文件系统的环境的服务。
核心启动后最初的动作就是/sbin/init。作用如下:
。确保file system的一致性,进行mount。
。之后,network的设定和各种daemon的启动。
。监视终端的login的配置和动作状态。这个动作完了后(logout),
修改和配置 login。
也就是
上一页 [1] [2] [3] [4] 下一页
|
| 上一篇:文件特殊权限的解释 下一篇:FreeBSD 核心 (2) |