linux cmdline学习笔记
来源:互联网 发布:it基础知识 编辑:程序博客网 时间:2024/06/06 07:17
内核启动的时候有这样一条打印信息:
[ 0.000000]Kernel command line: mem=524256K@0x20000000 console=ttyGS0…………
这条打印信息的源代码在init/main.c中的start_kernel()函数中:
printk(KERN_NOTICE"Kernel command line: %s\n", boot_command_line);
可见,cmdline字符串是保存在boot_command_line中的。
boot_command_line是在init/main.c中定义的一个字符数组:
char __initdata boot_command_line[COMMAND_LINE_SIZE];
并且在init.h中有对这个boot_command_line的声明:
extern char __initdataboot_command_line[];
解析cmdline的操作是由parse_early_param()函数执行的。
然而,setup_arch()在调用parse_early_param()前会调用setup_machine_tags()
setup_machine_tags()中有如下代码:
static struct machine_desc * __init setup_machine_tags(unsigned int nr){…………char *from = default_command_line;…………if (__atags_pointer)tags = phys_to_virt(__atags_pointer);else if (mdesc->boot_params) {…………}…………if (tags->hdr.tag == ATAG_CORE) {if (meminfo.nr_banks != 0)squash_mem_tags(tags);save_atags(tags);parse_tags(tags);}/* parse_early_param needs a boot_command_line */strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);return mdesc;}
在setup.c中有如下定义:
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;CONFIG_CMDLINE应该是在Makefile中定义的或在编译过程中生成的一个字符串。
但是,在setup_machine_tags中,复制cmdline字符串到boot_command_line中之前,会调用parse_tags函数,这个函数会解析所有的tag并对cmdline的tag调用下面这个函数。
static int __init parse_tag_cmdline(const struct tag *tag){#if defined(CONFIG_CMDLINE_EXTEND)strlcat(default_command_line, " ", COMMAND_LINE_SIZE);strlcat(default_command_line, tag->u.cmdline.cmdline,COMMAND_LINE_SIZE);#elif defined(CONFIG_CMDLINE_FORCE)pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");#elsestrlcpy(default_command_line, tag->u.cmdline.cmdline,COMMAND_LINE_SIZE);#endifreturn 0;}__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
其中CONFIG_CMDLINE_EXTEND和CONFIG_CMDLINE_FORCE都没有定义,那么default_command_line的初始值在这里被tag->u.cmdline.cmdline覆盖。
那么parse_tag_cmdline是怎么被调用的呢,这个就是一个叫做“自动数组”的机制的功劳了。其实就是利用__tagtable把这个函数信息放到了自动数组里面了。
__tagtable的定义在setup.h中:#define __tag __used __attribute__((__section__(".taglist.init")))#define __tagtable(tag, fn) \static struct tagtable __tagtable_##fn __tag = { tag, fn }
可见这种静态定义的结构体被放到了一个特定的段中。
现在再来看一看tags是怎么来的。
setup_machine_tags()中有如下一段代码:
if (__atags_pointer)tags = phys_to_virt(__atags_pointer);
__atags_pointer是什么?它实际就是bootloader中存储tags的地址,把这个地址转换为虚拟地址,内核就得到了bootloader创建的tags。
有网上资料说:内核(arch/arm/kernel/head-common.S中的__mmap_switched)将这个地址存入__atags_pointer(定义于arch/arm/kernel/setup.c)。下面分析一下这段代码:
__INIT__mmap_switched:adrr3, __mmap_switched_dataldmiar3!, {r4, r5, r6, r7}cmpr4, r5@ Copy data segment if needed1:cmpner5, r6ldrnefp, [r4], #4strnefp, [r5], #4bne1bmovfp, #0@ Clear BSS (and zero fp)1:cmpr6, r7strccfp, [r6],#4bcc1b ARM(ldmiar3, {r4, r5, r6, r7, sp}) /* 这样__atags_pointer的地址就保存在R6中了 */ THUMB(ldmiar3, {r4, r5, r6, r7}) THUMB(ldrsp, [r3, #16])strr9, [r4]@ Save processor IDstrr1, [r5]@ Save machine typestrr2, [r6]@ Save atags pointer /* 保存atags地址 */bicr4, r0, #CR_A@ Clear 'A' bitstmiar7, {r0, r4}@ Save control register valuesbstart_kernelENDPROC(__mmap_switched)//----------------------------------------.align2.type__mmap_switched_data, %object__mmap_switched_data:.long__data_loc@ r4.long_sdata@ r5.long__bss_start@ r6.long_end@ r7.longprocessor_id@ r4.long__machine_arch_type@ r5.long__atags_pointer@ r6 /* 声明一个long型数据,数据的内容是__atags_pointer的地址 */.longcr_alignment@ r7.longinit_thread_union + THREAD_START_SP @ sp.size__mmap_switched_data, . - __mmap_switched_data
bootloader中,通常是这样跳转到linux的:
static void boot_linux(unsigned kaddr){ void (*entry)(unsigned,unsigned,unsigned) = (void*) kaddr; entry(0, board_machtype(), linux_tags);}
可以看出tags的地址是放在r2寄存器中的。
- linux cmdline学习笔记
- linux cmdline参数解析
- linux cmdline解析过程说明
- Linux Kernel Boot CMDLINE Processing
- [笔记分享] [SCons] SCons工具之Cmdline
- Linux cmdline 解析(CMA 预留内存)
- Linux Kernel command line 内核输入参数/proc/cmdline
- 组播MAC地址 和 linux cmdline 详细解析
- linux kernel的cmdline参数解析原理分析
- linux驱动——cmdline原理及利用
- linux kernel的cmdline参数解析原理分析
- Linux内核强制使用自配置的cmdline
- linux kernel的cmdline参数解析原理分析
- linux kernel的cmdline参数解析原理分析
- Linux内核强制使用自配置的cmdline
- kernel cmdline
- cmdline传递
- cmdline值
- @JoinColumn
- [2012校赛新生组]稳定排序的题目
- 排序之插入排序
- Linux CURL的安装
- 认识org.apache.hadoop.io.compress解码器/编码器
- linux cmdline学习笔记
- 人脸识别facedetect的摄像头简化程序
- mysql sql语句大全
- eclipse括号风格改为独占一行风格
- JSTL 自定义标签
- java 重点分析泛型
- 哈哈哈哈哈哈和
- signal信号函数个人见解
- KMP模式匹配算法中next[]数组求法