Linux 版 (精华区)

发信人: tcpip (俺的昵称改了), 信区: Linux
标  题: FreeBSD核心探讨(翻译)3(转寄)
发信站: 哈工大紫丁香 (Tue Aug 24 16:38:57 1999), 转信

发信人: reden (Offer 快快来啊 ~!), 信区: FreeBSD       

标  题: FreeBSD核心探讨(翻译)3

发信站: BBS 水木清华站 (Mon Mar 29 19:46:43 1999)

标 题: FreeBSD核心探讨(翻译)3 

  

  作 者: liangvy (桃花岛主) 1999.03.17

  

  (续上,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。 

  

  也就是说,如果没有它,用户就不能使用unix文件系统。还有就是,如果boot  

  

  progam参数指定-s的话,它就过渡到单一的用户模式。相对来说,普通的用户 

  

  模式也就是multi模式。为了使普通用户能够使用系统,/sbin/init的参考文件 

  

  主要在/etc目录里放着。主要就是运行/etc/rc文件对系统进行初始化。 

  

  /etc/rc文件的主要内容和作用如下: 

  

    。使系统能够使用swap区 

  

    。检查/etc/fstab,检查它的连贯性,如果有问题就转到单一的用户模式 

  

    。mount nfs以外的文件系统 

  

    。读入network 的设定和各种daemon进程的设定情况的记录文件 

  

      /etc/c.conf,这个内容作为shell script的变量设定,以下的就是 

  

      各个shell的动作调整 

  

    。serial的初始化(/etc/rc.serial) 

  

    。运行PCMCIA卡的插拔监控守护进程(/etc/rc.pccard) 

  

    。network的部分初始化(/etc/rc.network) 

  

    。如果有nfs的时候就进行mount操作 

  

    。network的最终初始化(/etc/rc.network:启动和entwork有关的daemon) 

  

    。共有库的有关信息的初始化 

  

    。intd,lpd,sendmail的启动 

  

    。依赖系统的一些初始化进程 

  

  /etc/rc的处理完了后,/sbin/init就对/etc/ttys等记述的一些终端的用户login进

行 

  

  监视。对于这个,/etc/ttys里指定的终端,fork()后的进程里: 

  

    。exec()指定的程序(普通的情况是/usr/libexec/getty) 

  

    。/usr/libexec/getty进行终端速度等的设定。提示login:,等待用户输入 

  

    。用户输入后,名字作为参数exec() /etc/bin/login 

  

    。/usr/bin/login就提示出passwd:,等待用户的输入 

  

    。准备user名和passwd,对输入的用户名进行确定,正确的话就exec()用户 

  

      shell 

  

             

  

  下图就是/sbin/init的监视进程图: 

  

  process #1 

  

             --------------------------------------------------------> 

  /sbin/init |                                         ^       \ 

             | fork()                                  |        | fork() 

             + exec()  exec()     exec()               |        | exec() 

  process #n |---------->+--------->+------------------*+-------- 

                getty   login      user的login shell       process #m 

  

  (第一章完,下一章介绍文件系统和驱动程序,liangvy) 

  

  -- 

  

  

--

在江湖中,只要拿起了刀,就是一场无涯的梦。

※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 159.226.21

.168]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: bin@mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.078毫秒