Linux Kernel (v 0.11)源代码解读-main.c

本文详细解析了Linux内核的启动过程,包括内存管理、设备初始化、时间管理等关键步骤,并介绍了局部描述符表描述符的工作原理及任务状态段(TSS)的配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Study Linux Kernel Notes(v 0.11)       Shawn.Xie
                                       Shawshie@msn.com

 4   main.c

  4.1   function: main()
 
    4.1.1  Procedure Overview
   
        (1) 在全局变量中保存根设备号、磁盘驱动器的信息等。
        (2) 初始化内存空间的大致分配:
             内存末端 = 1M + 扩展内存大小,并进行页对齐(4096)
               内存末端 > 16M, 内存末端 = 16M
               内存末端 > 12M,         缓冲区末端 = 4M
               内存末端 > 6M && <= 12M,缓冲区末端 = 2M
               内存末端 < 6M,          缓冲区末端 = 1M
            
             RAM
             |              | 
             +--------------+  memory_end
             |              |
             +--------------+  main_memory_start (if RAMDISK = 0, main_memory_start = buffer_memory_end)
             |              |    RAMDISK * 1024
             +--------------+  buffer_memory_end
             |              |  
            
        (3) Call mem_init(),内存管理初始化
             mem_map[0...Start_mem/4K-1]      = USED;
             mem_map[Start_mem/4K...16M/4K-1] = 0;
            
        (4) Call trap_init(),陷阱门初始化        
             将相关ISR挂到陷阱门中(0-16,45 used. 17-44,46-47 reserved)
             允许主8259A 芯片的IRQ2 中断请求。
             允许从8259A 芯片的IRQ13 中断请求。
             将相关ISR挂到陷阱门中(39)
         
        (5) Call blk_dev_init(),块设备初始化
             request[0...31].dev  = -1; (设备没有请求)
             request[0...31].next = NULL;
            
        (6) Call chr_dev_init(),字符设备初始化
             NULL
            
        (7) Call tty_init(),tty初始化      
             初始化串口终端
             初始化控制台终端
            
        (8) Call time_init(),计算机时间初始化
             从BIOS中获取机器时间,将BCD码转换成二进制
             将时间转换成自1970年以来累计运行的秒数
       
        (9) Call sched_init(),调度初始化
       
            --------------------------------------------------------------------
             局部描述符表描述符详解:
             63          56 55 54 53 52 51   48 47 46 45 44 43 41 40 39             16 15               0
             +-------------+--+--+-----+-------+--+-----+--+----+--+------------------+-----------------+
             |Seg Base Addr|G |D | 0 0 |Seg Len|P | DPL |S | TYPE  | Seg Base Addr    |  Segment Length |
             +-------------+--+--+-----+-------+--+-----+--+----+--+------------------+-----------------+
            
             G ------   表示粒度:1=段长度为页粒度、 0=段长度为字节粒度
             D ------   缺省操作数的大小(仅在代码段描述符中识别) 1=32位段   ; 0=16位段                            
             P ------   该字节最高位(D7),占一位。用以确定此描述符是否有效。P=1,描述符有效;P=0,此描述符无效                                                                                    
             DPL ----   该字节D6, D5位,占两位。描述符所定义的段的特权级,其值为0 --- 3                                                                                                             
             S ------   该字节D4位,占一位。S=0                                                                                                                                                    
             TYPE----   该字节D3,D2 ,D1,D0位,占四位。用于规定该描述符的类型:是局部描述符表描述符、调用门、任务门、中断门、自陷门中的哪一个,而其它段长,段基地址,保留字节等的定义不变。具体如下:
              
               类型     描述             类型    描述
             -------------------------------------------------- 
               0        无用             8       无用
               1        有效的286TSS     9       有效的386TSS
               2        LDT             A       未定义
               3        286TSS忙        B       386TSS忙
               4        286调用门        C       386调用门
               5        任务门           D       未定义
               6        286中断门        E       386中断门
               7        286陷阱门        F       386陷阱门
             --------------------------------------------------
            --------------------------------------------------------------------
           
            (9.1) 创建初始化任务的TSS描述符,放在GDT[4]中
                      P=1,描述符有效
                      DPL=0,
                      TYPE=9,有效的386TSS
                      Seg Base Addr = &(init_task.task.tss)
                      Segment  Len  = 104

            (9.2) 创建初始化任务的LDT描述符,放在GDT[5]中
                      P=1,描述符有效
                      DPL=0,
                      TYPE=2,LDT
                      Seg Base Addr = &(init_task.task.ldt)
                      Segment  Len  = 104
            (9.3) task[1...63] = NULL
                  GDT[6..68] = 0
                 
            (9.4) clear NT,LTS(0),LLDT(0)
           
            (9.5) 初始化8253定时器
                  设定定时中断门
                  设定系统调用门
          
        (10) Call buffer_init(),缓冲区初始化
              在end - buffer_memory_end内,以1K大小进行分片,片头初始化
              free_list组成环形链表
              hash_table[0...306] = NULL
             
        (11) Call hd_init(),硬盘驱动初始化
              blk_dev[3].request_fn = DEVICE_REQUEST
              挂接中断46 - hd_interrupt
              复位接联的主8259A int2 的屏蔽位,允许从片发出中断请求信号。
              复位硬盘的中断请求屏蔽位(在从片上),允许硬盘控制器发送中断请求信号。
             
        (12) Call floppy_init(),软盘驱动初始话
              blk_dev[2].request_fn = DEVICE_REQUEST;                                                                                                                                                            
              挂接中断38 - floppy_interrupt       
              复位软盘的中断请求屏蔽位,允许软盘控制器发送中断请求信号。
             
        (13) Call sti(),开中断
       
        (14) Call move_to_user_mode(),进入用户模式
              保存 SS, ESP, eflags, CS.
              设置数据段选择子
             
        (15) Call init()
       
        (16) for(;;) pause();      
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值