- 浏览: 14384 次
最新评论
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;
}
};
发表评论
-
深入了解GPU--学习教材 (摘自opengpu)
2012-01-20 01:14 880深入了解GPU--学习教材 ( ... -
S3C2450自动升级
2012-01-20 01:14 1260S3C2450自动升级 2010年06 ... -
Papervision3D Essentials 要点整理
2012-01-20 01:14 752Papervision3D Essentials 要点 ... -
papervision3d学习笔记:图片墙(4)
2012-01-20 01:13 660papervision3d学习笔记:图片墙(4) 2010年 ... -
papervision3d学习笔记:图片墙(1)
2012-01-20 01:13 674papervision3d学习笔记:图片墙(1) 2010年 ... -
第一章第一节计算机语言C语言基础教程
2012-01-17 01:33 786第一章第一节计算机语言C语言基础教程 2012年01月02日 ... -
2011-1-8
2012-01-17 01:33 8262011-1-8 2011年01月08日 ... -
2001-6-1
2012-01-17 01:32 6852001-6-1 2011年09月17日 1.假设某台式 ... -
大文件上传解决办法
2012-01-15 20:13 892大文件上传解决办法 20 ... -
jQuery插件之jquery的form插件使用示例
2012-01-15 20:13 884jQuery插件之jquery的form插件使用示例 201 ... -
asp无组件上传
2012-01-15 20:13 715asp无组件上传 2009年10月14日 文件上传组件 ... -
ASP.NET 2.0使用FileUpload控件上传文件示例
2012-01-15 20:13 741ASP.NET 2.0使用FileUpload控件上传文件示例 ... -
经典的串口调试助手源代码(一)
2012-01-15 20:13 742经典的串口调试助手源代码(一) 2011年05月26日 ... -
这是一个广为流传的关于项目管理的通俗讲解 (转)
2012-01-11 12:21 571这是一个广为流传的关于项目管理的通俗讲解 (转) 2011年 ... -
struct2数字格式化
2012-01-11 12:21 735struct2数字格式化 2011年03月01日 st ... -
window.showModalDialog使用手册
2012-01-11 12:21 618window.showModalDialog使用手 ... -
3300_java
2012-01-11 12:21 5683300_java 2011年03月01日 impor ... -
Rails之格式化价格方法【转载】
2012-01-11 12:21 733Rails之格式化价格方法【转载】 2011年03月01日 ...
相关推荐
Linux内核函数Start_kernel()中调用了一系列初始化函数,以完成kernel本身的设置。这些动作有的是公共的,有的则是需要配置的才会执行的。本文介绍了在start_kernel()函数中的一些功能。
很好的linux启动代码分析 LINUX , start_kernel , 启动代码 linux kernel 从入口到start_kernel 的代码分析.rar 104.59 KB, 下载次数: 31 , 下载积分: 资产 -2 信元, 下载支出 2 信元
arm linux 从入口到start_kernel 代码分析
arm linux 从入口到start_kernel 代码分析 第四部分
arm linux 从入口到start_kernel 代码详细分析.doc
Daniel Jslin教授分析linux kernel 中的start_kernel详细过程。by the way.可以关注我在csdn上关于linux kernel的课程https://edu.csdn.net/course/detail/9089
该文档描述了linux 内核内存管理部分的相关分析,从start_kernel入手,注重代码分析。
linux内核从start_kernel到init.pdf
start_kernel流程图 linux2.6 内核支持两种格式的 initrd,一种是 image-initrd,其核心文件就是 /linuxrc。另外一种是cpio-initrd,使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init。尽管 linux2.6...
arm linux 从入口到start_kernel 代码分析 第六部分
arm linux 从入口到start_kernel 代码分析 第5部分
arm linux 从入口到start_kernel 代码分析 第7部分
arm linux 从入口到start_kernel 代码分析第三部分
打印机驱动 START_PLQ6_OKI5_Drvsky打印机驱动 START_PLQ6_OKI5_Drvsky打印机驱动 START_PLQ6_OKI5_Drvsky打印机驱动 START_PLQ6_OKI5_Drvsky打印机驱动 START_PLQ6_OKI5_Drvsky打印机驱动 START_PLQ6_OKI5_Drvsky...
分析明确内核中断向量表的初始化; 分析明确内核的根文件系统挂载过程; 分析明确内核页表的建立过程; 分析明确init进程创建和执行过程;