Chinaunix首页 | 论坛 | 博客
  • 博客访问: 462283
  • 博文数量: 49
  • 博客积分: 345
  • 博客等级: 民兵
  • 技术积分: 509
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-21 12:02
个人简介

文章分类

全部博文(49)

文章存档

2022年(1)

2021年(7)

2020年(10)

2019年(2)

2016年(20)

2015年(5)

2014年(1)

2011年(3)

我的朋友

分类: LINUX

2015-09-15 15:34:39

内核在start_kernel()开始启动:
start_kernel
     -->setup_arch(&command_line);     //arch/arm/kernel/setup.c
          -->setup_machine_fdt(__atags_pointer);    //存储了配置参数的物理地址
               -->of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);     //调用early_init_dt_scan_chosen来查找入参,并保存在boot_command_line字符串中;           
int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
                         int depth, void *data)
     /* Retrieve command line */
     p = of_get_flat_dt_prop(node, "bootargs", &l);
     if (p != NULL && l > 0)
          strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
可以看出来这个查找的是bootargs字符,并将其值拷贝到boot_command_line中;
再来看一下,boot下参数列表里是否有bootargs项,如下可以找到对应的参数
Marvell>> pri
CASset=max
MALLOC_len=5
MPmode=SMP
activeimage=imagea
amp_enable=no
autoload=no
baudrate=115200
boot_order=hd_scr hd_img pxe net_img net_scr
bootargs=console=ttyS0,115200 root=/dev/mtdblock4 mtdparts=armada-nand:1m(boota),1m@1m(bootb),2m@2m(configa),2m@4m(configb),28m@6m(imagea),14m@34m(imagec0),28m@48m(imageb),14m@76m(imagec1),1m@90m(misca),1m@91m(miscb),-(reserved) rootfstype=cramfs mv_net_config=0  5srst=0 major=0xa5 minor=0x1 hwver=0x1 longrst=0
bootargs_dflt=$console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel
bootargs_end=:10.4.50.254:255.255.255.0:AvantaLP:eth0:none
bootargs_root=root=/dev/nfs rw
bootcmd=fsload;bootm
bootdelay=3
cacheShare=no
......
这样bootargs的参数就拷贝到boot_command_line中,
在setup_arch中,又将boot_command_line拷贝到入参command_line中;
     /* populate cmd_line too for later use, preserving boot_command_line */
     strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
     *cmdline_p = cmd_line;

__atags_pointer值如何获取???
在head-common.s中,也没看懂汇编,可以参考下面链接;

配置启动参数
启动参数存入后command_line后,会在setup_command_line中,再次将启动参数拷贝到static_command_line中;
static void __init setup_command_line(char *command_line)
{
     saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
     static_command_line = alloc_bootmem(strlen (command_line)+1);
     strcpy (saved_command_line, boot_command_line);
     strcpy (static_command_line, command_line);
}

参数配置:
     printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
     parse_early_param();
     parse_args("Booting kernel", static_command_line, __start___param,
             __stop___param - __start___param,
             -1, -1, &unknown_bootoption);

有些选项需要在其他选项之前被处理就会调用parse_early_param
void __init parse_early_options(char *cmdline)
{
     parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
}

/* Arch code calls this early on, or if not, just before other parsing. */
void __init parse_early_param(void)
{
     static __initdata int done = 0;
     static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];

     if (done)
          return;

     /* All fall through to do_early_param. */
     strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
     parse_early_options(tmp_cmdline);
     done = 1;
}
最终调用do_early_param,与__setup宏有关;可参考之前的博客;

非特殊的选项在parse_args-->parse_one中被处理;
可以看到最初处理函数是在__start___param/__stop___param区域内查找的,该区域存储的列表是build-in类型module的配置参数,
可参考

但是__setup设置的参数在__setup_start  __setup_end表示的段内,所有大部分调用unknown_bootoption函数处理;

与__setup宏有关;可参考之前的博客

阅读(2069) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~