免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 978 | 回复: 0
打印 上一主题 下一主题

入门备忘录三--内核初始化代码分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-02-12 11:04 |只看该作者 |倒序浏览
x86系列cpu的引导无非如下几个步骤:
1、cpu加电自检,初始化自身,在固定位置执行一条指令。
2、这条指令跳转到BIOS中。
3、BIOS找到启动设备并获取MBR,该MBR指向我们的lilo
4、BIOS装载并把控制权交给lilo
5、内核自解压,并把控制权转交给解压内核。
这时内核将跳转到start_kernel是/init/main.c,这里我简要介绍一下这个函数的初始化流程。
初始化内核:
从start_kernel函数(/init/main.c)开始系统初始化工作,好,我们首先分析这个函数:
函数开始首先:
#ifdef __SMP__
static int boot_cpu = 1;
/* "current" has been set up, we need to load it now *//*定义双处理器用*/
if (!boot_cpu)
initialize_secondary();
boot_cpu = 0;
#endif
定义双处理器。
printk(linux_banner); /*打印linux banner*/
打印内核标题信息。
开始初始化自身的部分组件(包括内存,硬件终端,调度等),我来逐个分析其中的函数:
setup_arch(&command_line, &memory_start, &memory_end);/*初始化内存*/
返回内核参数和内核可用的物理地址范围
函数原型如下:
setup_arch(char **, unsigned long *, unsigned long *);
返回内存起始地址:
memory_start = paging_init(memory_start,memory_end);
看看paging_init的定义,是初始化请求页:
paging_init(unsigned long start_mem, unsigned long end_mem)
{
     int i;
     struct memclust_struct * cluster;
     struct memdesc_struct * memdesc;
     /* initialize mem_map[] */
     start_mem = free_area_init(start_mem, end_mem);/*遍历查找内存的空闲页*/
     /* find free clusters, update mem_map[] accordingly */
     memdesc = (struct memdesc_struct *)
     (hwrpb->mddt_offset + (unsigned long) hwrpb);
     cluster = memdesc->cluster;
     for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
     unsigned long pfn, nr;
     /* Bit 0 is console/PALcode reserved. Bit 1 is
     non-volatile memory -- we might want to mark
     this for later */
     if (cluster->usage & 3)
        continue;
     pfn = cluster->start_pfn;
     if (pfn >= MAP_NR(end_mem)) /* if we overrode mem size */
        continue;
     nr = cluster->numpages;
     if ((pfn + nr) > MAP_NR(end_mem)) /* if override in cluster */
        nr = MAP_NR(end_mem) - pfn;
     while (nr--)
        clear_bit(PG_reserved, &mem_map[pfn++].flags);
     }
     memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
     return start_mem;
}
trap_init(); 初始化硬件中断
/arch/i386/kernel/traps.c文件里定义此函数
sched_init() 初始化调度
/kernel/sched.c文件里有详细的调度算法
parse_options(command_line) 分析传给内核的各种选项
memory_start = console_init(memory_start,memory_end) 初始化控制台
memory_start = kmem_cache_init(memory_start, memory_end) 初始化内核内存cache
sti();接受硬件中断
kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
current->need_resched = 1; need_resched标志增加,调用schedule
cpu_idle(NULL) 进入idle循环以消耗空闲的cpu时间片
已经基本完成内核初始化工作,把需要完成的少量工作传递给了init,所以剩余地工作不过是进入idle循环以消耗空闲的cpu时间片。所以在这里调用了cpu_idle(NULL),它从不返回,所以当有实际工作需要处理时,该函数就会被抢占。
parse_options函数:
static void __init parse_options(char *line)/*参数收集在一条长命令行中,内核被赋给指向该命令行头部的指针*/
{
     char *next;
     char *quote;
     int args, envs;
     if (!*line)
        return;
     args = 0;
     envs = 1;/* TERM is set to 'linux' by default */
     next = line;
     while ((line = next) != NULL) {
        quote = strchr(line,'"');
        next = strchr(line, ' ');
        while (next != NULL && quote != NULL && quote
      /*
       * check for kernel options first..
       */
      if (!strcmp(line,"ro")) {
        root_mountflags |= MS_RDONLY;
        continue;
      }
      if (!strcmp(line,"rw")) {
        root_mountflags &= ~MS_RDONLY;
        continue;
      }
      if (!strcmp(line,"debug")) {
        console_loglevel = 10;
        continue;
      }
      if (!strcmp(line,"quiet")) {
        console_loglevel = 4;
        continue;
      }
      if (!strncmp(line,"init=",5)) {
        line += 5;
        execute_command = line;
        args = 0;
        continue;
      }
      if (checksetup(line))
        continue;
      if (strchr(line,'=')) {
        if (envs >= MAX_INIT_ENVS)
           break;
        envp_init[++envs] = line;
      } else {
        if (args >= MAX_INIT_ARGS)
          break;
        argv_init[++args] = line;
      }
   }
    argv_init[args+1] = NULL;
    envp_init[envs+1] = NULL;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/61037/showart_477411.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP