您的位置:首页 > 其它

通过bootloader向内核传输启动参数

2013-09-05 22:40 411 查看
作者:YoungerLiu,本作品采用知识共享署名-非商业性使用-相同方式共享3.0未本地化版本许可协议进行许可。

Linux提供了一种通过bootloader向其传输启动参数的功能,内核开发者可以通过这种方式来向内核传输数据,从而控制内核启动行为。

通常的使用方式是,定义一个分析参数的函数,而后使用内核提供的宏__setup把它注册到内核中,该宏定义在
linux/init.h中,因此要使用它必须包含该头文件:

__setup("para_name=",parse_func)

其中:@para_name为参数名;@parse_func为分析参数值的函数,它负责把该参数的值转换成相应的内核变量的值并设置那个内核变量。

内核为整数参数值的分析提供了函数get_option和
get_options,前者用于分析参数值为一个整数的情况,而后者用于分析参数值为逗号分割的一系列整数的情况,对于参数值为字符串的情况,需要开发者自定义相应的分析函数。

1setup使用案例

在文件./mm/slub.c

staticint__initsetup_slub_min_order(char*str) { get_option(&str,&slub_min_order); return1; } __setup("slub_min_order=",setup_slub_min_order); staticint__initsetup_slub_max_order(char*str) { get_option(&str,&slub_max_order); slub_max_order=min(slub_max_order,MAX_ORDER-1); return1; } __setup("slub_max_order=",setup_slub_max_order);

2内核程序kern-boot-params测试

在源代码包中的内核程序kern-boot-params.c说明了三种情况的使用。该程序列举了参数为一个整数、逗号分割的整数串以及字符串三种情况,读者要想测试该程序,需要把该程序拷贝到要使用的内核的源码目录树的一个目录下,为了避免与内核其他部分混淆,作者建议在内核源码树的根目录下创建一个新目录,如examples,然后把该程序拷贝到
examples目录下并重新命名为setup_example.c,并且为该目录创建一个Makefile文件:

obj-y=setup_example.o

Makefile仅需这一行就足够了,然后需要修改源码树的根目录下的Makefile文件的一行,把下面行

core-y:=usr/

修改为

core-y:=usr/examples/

注意:如果读者创建的新目录和重新命名的文件名与上面不同,需要修改上面所说Makefile文件相应的位置。做完以上工作就可以按照内核构建步骤去构建新的内核。

//filename:kern-boot-params.c #include<linux/kernel.h> #include<linux/init.h> #include<linux/string.h> #defineMAX_SIZE5 staticintsetup_example_int; staticintsetup_example_int_array[MAX_SIZE]; staticcharsetup_example_string[16]; staticint__initparse_int(char*s) { intret; ret=get_option(&s,&setup_example_int); if(ret==1){ printk("setup_example_int=%d\n",setup_example_int); } return1; } staticint__initparse_int_string(char*s) { char*ret_str; inti; ret_str=get_options(s,MAX_SIZE,setup_example_int_array); if(*ret_str!='\0'){ printk("incorrectsetup_example_int_arrayparamters:%s\n",ret_str); } else{ printk("setup_example_int_array="); for(i=1;i<MAX_SIZE;i++){ printk("%d",setup_example_int_array[i]); if(i<(MAX_SIZE-1)){ printk(","); } } printk("\n"); printk("setup_example_int_arrayincludes%dintergers\n",setup_example_int_array[0]); } return1; } staticint__initparse_string(char*s) { if(strlen(s)>15){ printk("Toolongsetup_example_stringparameter,\n"); printk("maximumlengthislessthanorequalto15\n"); } else{ memcpy(setup_example_string,s,strlen(s)+1); printk("setup_example_string=%s\n",setup_example_string); } return1; } __setup("setup_example_int=",parse_int); __setup("setup_example_int_array=",parse_int_string); __setup("setup_example_string=",parse_string);

3变量配置方法

在构建好内核并设置好lilo或grub为该内核的启动条目后,就可以启动该内核,然后使用lilo或grub的编辑功能为该内核的启动参数行增加如下参数串:

setup_example_int=1234setup_example_int_array=100,200,300,400setup_example_string=Thisisatest

当然,该参数串也可以直接写入到lilo或grub的配置文件中对应于该新内核的内核命令行参数串中。读者可以使用其它参数值来测试该功能.

[root@RedHat~]#cat/boot/grub/menu.lst #grub.confgeneratedbyanaconda # #Notethatyoudonothavetorerungrubaftermakingchangestothisfile #NOTICE:Youhavea/bootpartition.Thismeansthat #allkernelandinitrdpathsarerelativeto/boot/,eg. #root(hd0,0) #kernel/vmlinuz-versionroroot=/dev/mapper/VolGroup-lv_root #initrd/initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=3 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu titleRedHatEnterpriseLinuxServer(3.2.0trace) root(hd0,0) kernel/vmlinuz-3.2.0traceroroot=/dev/mapper/VolGroup-lv_rootrd_LVM_LV=VolGroup/lv_rootrd_LVM_LV=VolGroup/lv_swaprd_NO_LUKSrd_NO_MDrd_NO_DMLANG=en_US.UTF-8SYSFONT=latarcyrheb-sun16KEYBOARDTYPE=pcKEYTABLE=uscrashkernel=autorhgbquietsetup_example_int=1234setup_example_int_array=10,20,30,40setup_example_string=lewiyon initrd/initramfs-3.2.0trace.img titleRedHatEnterpriseLinux(2.6.32-71.el6.i686) root(hd0,0) kernel/vmlinuz-2.6.32-71.el6.i686roroot=/dev/mapper/VolGroup-lv_rootrd_LVM_LV=VolGroup/lv_rootrd_LVM_LV=VolGroup/lv_swaprd_NO_LUKSrd_NO_MDrd_NO_DMLANG=en_US.UTF-8SYSFONT=latarcyrheb-sun16KEYBOARDTYPE=pcKEYTABLE=uscrashkernel=autorhgbquiet initrd/initramfs-2.6.32-71.el6.i686.img [root@RedHat~]#

使用dmesg|grepsetup来查看该程序的输出。

[root@RedHat~]#dmesg|grepsetup setup_percpu:NR_CPUS:32nr_cpumask_bits:32nr_cpu_ids:1nr_node_ids:1 Kernelcommandline:roroot=/dev/mapper/VolGroup-lv_rootrd_LVM_LV=VolGroup/lv_rootrd_LVM_LV=VolGroup/lv_swaprd_NO_LUKSrd_NO_MDrd_NO_DMLANG=en_US.UTF-8SYSFONT=latarcyrheb-sun16KEYBOARDTYPE=pcKEYTABLE=uscrashkernel=autorhgbquietsetup_example_int=1234setup_example_int_array=10,20,30,40setup_example_string=lewiyon setup_example_int=1234 setup_example_int_array=10,20,30,40, setup_example_int_arrayincludes4intergers setup_example_string=lewiyon [root@RedHat~]#

4参考文献

http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs/

作者:YoungerLiu,本作品采用知识共享署名-非商业性使用-相同方式共享3.0未本地化版本许可协议进行许可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: