`
vfh615gc
  • 浏览: 14384 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

start_kernel()注解2

 
阅读更多

start_kernel()注解2
2010年06月17日
         /*   
  Setup_arch()这个函数根据你的处理器,还有你的硬件平台设置你的系统,并解析Linux系统的命令行,设置0号进程,即Swapper进程的内在描述结构INIt_MM,系统内存管理初始化,统计并注册系统各种资源,还有其它一些相关的初始化
  */
  setup_arch(&command_line)
  {
  void __init setup_arch(char **cmdline_p)
  {
  struct tag *tags = (struct tag *)&init_tags;
  struct machine_desc *mdesc;
  char *from = default_command_line;
  setup_processor()
  {
  static void __init setup_processor(void)
  {
  extern struct proc_info_list __proc_info_begin, __proc_info_end;
  struct proc_info_list *list;
  /*
  * locate processor in the list of supported processor
  * types.  The linker builds this table for us from the
  * entries in arch/arm/mm/proc-*.S
  */
  /*
  从所支持的处理器类型表中找出所需要的处理器,利用Proc-*.S里面的函数,链接器会为我们创建这个表格,根据汇编代码中获取的ARM处理器的主ID寄存器的值processor_id,从Proc.info中找到该处理器对应的处理器信息结构proc_info_list变量,
  */
  for (list = &__proc_info_begin; list cpu_mask) == list->cpu_val)//
  break;
  /*
  * If processor type is unrecognised, then we
  * can do nothing...
  */
  /*
  *如果处理器类型没有被认可,那么我们不做任何事情,
  */
  if (list >= &__proc_info_end) {
  printk("CPU configuration botched (ID %08x), unable "
  "to continue.\n", processor_id);
  while (1);
  }
  //如果被认可,我们保存CPU的名字到全局变量cpu_name中
  cpu_name = list->cpu_name;
  #ifdef MULTI_CPU
  //把该处理器的处理函数结构指针保存
  processor = *list->proc;
  #endif
  #ifdef MULTI_TLB
  //保存快表操作函数组指针
  cpu_tlb = *list->tlb;
  #endif
  #ifdef MULTI_USER
  //保存处理器用户空间操作函数组结构指针
  cpu_user = *list->user;
  #endif
  #ifdef MULTI_CACHE
  //保存Cache操作函数组结构指针
  cpu_cache = *list->cache;
  #endif
  //打印处理器名,ID,处理器的修正版本,体系结构信息
  printk("CPU: %s [%08x] revision %d (ARMv%s)\n",
  cpu_name, processor_id, (int)processor_id & 15,
  proc_arch[cpu_architecture()]);
  dump_cpu_info()
  {
  static void __init dump_cpu_info(void)
  {
  //读出处理器的ID
  unsigned int info = read_cpuid(CPUID_CACHETYPE);
  //打印处理器catche信息
  if (info != processor_id) {
  //以下是打印catche相关信息,如类型,组织形式,容量,块大小,相连性,
  printk("CPU: D %s %s cache\n", cache_is_vivt() ? "VIVT" : "VIPT",
  cache_types[CACHE_TYPE(info)]);
  if (CACHE_S(info)) {
  dump_cache("CPU: I cache", CACHE_ISIZE(info));
  dump_cache("CPU: D cache", CACHE_DSIZE(info));
  } else {
  dump_cache("CPU: cache", CACHE_ISIZE(info));
  }
  }
  }
  };
  //把它的处理器架构名字字符串arch_name + “L”传给system_utsname.machine,L是小端,B是大端 ENDIANNESS是小端
  sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
  //把体系架构版本字符串Elf_name + “L”传给elf_platform
  sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
  elf_hwcap = list->elf_hwcap;//硬件性能标志字传到全局变量中
  //刚才保存过的processor是该处理器的函数组结构变量,调用_proc_init()初始化函数
  cpu_proc_init()
  {
  processor._proc_init()
  };
  };
  // machine_arch_type:系统体系结构类型,定义了当前系统硬件平台编号,从.arch.info(体系结构信息表)中找到该平台的结构描述结构变量machine_desc,之后传给局部变量Mdesc
  mdesc = setup_machine(machine_arch_type)
  {
  static struct machine_desc * __init setup_machine(unsigned int nr)
  {
  extern struct machine_desc __arch_info_begin, __arch_info_end;
  struct machine_desc *list;
  /*
  * locate architecture in the list of supported architectures.
  从所支持的体系结构表中找出本体系结构
  */
  for (list = &__arch_info_begin; list nr == nr)//平台编号相同说明找到
  break;
  /*
  * If the architecture type is not recognised, then we
  * can co nothing...
  如果体系结构未被认可,啥也不做,
  */
  if (list >= &__arch_info_end) {
  printk("Architecture configuration botched (nr %d), unable "
  "to continue.\n", nr);
  while (1);
  }
  printk("Machine: %s\n", list->name);//打印体系结构 名字
  return list;
  }
  };
  machine_name = mdesc->name; //保存体系结构到全局变量中
  if (mdesc->soft_reboot) //如果soft_reboot不为0,将reboot_mode设为“S”说明是软件重启动,硬件重启动reboot_mode为“H”[/b]
  reboot_setup("s")
  {
  int __init reboot_setup(char *str)
  {
  reboot_mode = str[0];
  return 1;
  }
  };
  //如果param_offset 不为0,说明在系统内在基址+ param_offset处保存了[b]Bootloader
中设置并传过来的系统参数,保存在这里的可以是老参数Param_stuct,也可以是新参数Tag
  if (mdesc->param_offset)
  tags = phys_to_virt(mdesc->param_offset)
  {
  #define __phys_to_virt(x)     ((x) - PHYS_OFFSET + PAGE_OFFSET)
  #define PHYS_OFFSET (0x30000000UL)
  #define PAGE_OFFSET        (0xc0000000UL)
  };
  2.6.10是老参数,我们会将它转成新的Tag 参数
  /*
  * If we have the old style parameters, convert them to
  * a tag list. //如果我们用的是旧格式参数,将他们转化成新格式的
  */
  if (tags->hdr.tag != ATAG_CORE)
  convert_to_tag_list(tags);// 将他们转化成新格式的,这里会将其转成连续存放 的新格式参数,
  if (tags->hdr.tag != ATAG_CORE)
  tags = (struct tag *)&init_tags;//如果param_offset是0,那么就用默认参数
  if (mdesc->fixup) //成员函数有定义,调用之,做一些前期补充初始化并设置系统参数,这个函数很少定义而已, 
  mdesc->fixup(mdesc, tags, &from, &meminfo);
  if (tags->hdr.tag == ATAG_CORE) {//查看系统是否设置了核心参数(根文件系统是否是只读,内存页大小,根文件系统设备号)
  if (meminfo.nr_banks != 0)// 检查内存信息,不=0,说明前面调用过Fixup(),
  squash_mem_tags(tags)
  {
  void __init squash_mem_tags(struct tag *tag)
  {  //将内存参数的结构(标签为ATAG_MEM)清除,其它参数不变
  for (; tag->hdr.size; tag = tag_next(tag))
  if (tag->hdr.tag == ATAG_MEM)
  tag->hdr.tag = ATAG_NONE;
  }
  };
  //分析连续排放在struct tag 结构变量 的地址Tags处所有有效参数设置标签,从。Taglist区根据参数标签字找出每个有效参数标签对应的Struct tagtable结构变量,执行Struct tagtable结构变量中的标签,解析相应参数设置标签的内容,这个版本的内核中有11个这样的结构,
  parse_tags(tags);
  }
  //设置Init_mm的成员变量,将Linux内核编译出来的代码段起始,结束地址,数据段结束地址,和整个内核结束地址分别保存到Start_code,end_code,end_data,Brk成员变量 中
  init_mm.start_code = (unsigned long) &_text;
  init_mm.end_code   = (unsigned long) &_etext;
  init_mm.end_data   = (unsigned long) &_edata;
  init_mm.brk       = (unsigned long) &_end;
  //将1024字节的系统默认命令行字符串全局变量default_command_line复制到系统备份命令行字符全局变量saved_command_line中,[b][/b]
  memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
  saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
  //然后解析default_command_line中的每个命令,系统认识的系统参数设置命令,都有一个对应的 对应的 Struct early_params全局结构变量,变量中定义了命令参数名以及对应的命令解析函数,所有这些Struct early_params全局结构变量都是通过,Early_param()宏定义的,它们被连续放置在Early_param区,一条命令行可以设置多个参数命令,两个参数命令之间只能用空格隔开,参数命令内部不能用空格隔开,同一参数的不同属性用逗号隔开
  parse_cmdline(cmdline_p, from)
  {
  /*
  * Initial parsing of the command line.
  */
  static void __init parse_cmdline(char **cmdline_p, char *from)
  {
  char c = ' ', *to = command_line;
  int len = 0;
  for (;;) {
  if (c == ' ') {
  extern struct early_params __early_begin, __early_end;
  struct early_params *p;
  for (p = &__early_begin; p arg);
  if (memcmp(from, p->arg, len) == 0) {
  if (to != command_line)
  to -= 1;
  from += len;
  p->fn(&from);
  while (*from != ' ' && *from != '\0')
  from++;
  break;
  }
  }
  }
  c = *from++;
  if (!c)
  break;
  if (COMMAND_LINE_SIZE <= ++len)
  break;
  *to++ = c;
  }
  *to = '\0';
  *cmdline_p = command_line;
  }
  };
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics