arm Linux系统启动之start_kernel函数
核锁,如果有,它将被释放,以致于其它的进程能够获得该锁,
//而当轮到该进程运行时,再让它重新获得大内核锁。注意在保持自旋锁期间是不运行发生调度的。
//需要特别指出,整个内核只有一个大内核锁,其实不难理解,内核只有一个,而大内核锁是保护整个内核的,当然有且只有一个就足够了。
//还需要特别指出的是,大内核锁是历史遗留,内核中用的非常少,一般保持该锁的时间较长,因此不提倡使用它。
//从2.6.11内核起,大内核锁可以通过配置内核使其变得可抢占(自旋锁是不可抢占的),这时它实质上是一个互斥锁,使用信号量实现。
//大内核锁的API包括:
//
//void lock_kernel(void);
//
//该函数用于得到大内核锁。它可以递归调用而不会导致死锁。
//
//void unlock_kernel(void);
//
//该函数用于释放大内核锁。当然必须与lock_kernel配对使用,调用了多少次lock_kernel,就需要调用多少次unlock_kernel。
//大内核锁的API使用非常简单,按照以下方式使用就可以了:
//lock_kernel(); //对被保护的共享资源的访问 … unlock_kernel();
//http://blog.csdn.net/universus/archive/2010/05/25/5623971.aspx
lock_kernel();
//初始化time ticket,时钟
tick_init();
//函数 tick_init() 很简单,调用 clockevents_register_notifier 函数向 clockevents_chain 通知链注册元素:
// tick_notifier。这个元素的回调函数指明了当时钟事件设备信息发生变化(例如新加入一个时钟事件设备等等)时,
//应该执行的操作,该回调函数为 tick_notify
//http://blogold.chinaunix.net/u3/97642/showart_2050200.html
boot_cpu_init();
//初始化页地址,当然对于arm这里是个空函数
//http://book.chinaunix.net/special/ebook/PrenticeHall/PrenticeHallPTRTheLinuxKernelPrimer/0131181637/ch08lev1sec5.html
page_address_init();
printk(KERN_NOTICE "%s", linux_banner);
//系结构相关的内核初始化过程
//http://www.cublog.cn/u3/94690/showart_2238008.html
setup_arch(&command_line);
//初始化内存管理
mm_init_owner(&init_mm, &init_task);
//处理启动命令,这里就是设置的cmd_line
setup_command_line(command_line);
//这个在定义了SMP的时候有作用,现在这里为空函数;对于smp的使用,后面在看。。。
setup_nr_cpu_ids();
//如果没有定义CONFIG_SMP宏,则这个函数为空函数。
//如果定义了CONFIG_SMP宏,则这个setup_per_cpu_areas()函数给每个CPU分配内存,
//并拷贝.data.percpu段的数据。为系统中的每个CPU的per_cpu变量申请空间。
setup_per_cpu_areas();
//定义在include/asm-x86/smp.h。
//如果是SMP环境,则设置boot CPU的一些数据。在引导过程中使用的CPU称为boot CPU
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
//设置node 和 zone 数据结构
//内存管理的讲解:http://blog.chinaunix.net/space.php?uid=361890&do=blog&cuid=2146541
build_all_zonelists(NULL);
//初始化page allocation相关结构
page_alloc_init();
printk(KERN_NOTICE "Kernel command line: %s/n", boot_command_line);
//解析内核参数
//对内核参数的解析:http://hi.baidu.com/yuhuntero/blog/item/654a7411e45ce519b8127ba9.html
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
/*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
//初始化hash表,以便于从进程的PID获得对应的进程描述指针,按照实际的物理内存初始化pid hash表
//这里涉及到进程管理http://blog.csdn.net/satanwxd/archive/2010/03/27/5422053.aspx
pidhash_init();
//初始化VFS的两个重要数据结构dcache和inode的缓存。
//http://blog.csdn.net/yunsongice/archive/2011/02/01/6171324.aspx
vfs_caches_init_early();
//把编译期间,kbuild设置的异常表,也就是__start___ex_table和__stop___ex_table之中的所有元素进行排序
sort_main_extable();
//初始化中断向量表
//http://blog.csdn.net/yunsongice/archive/2011/02/01/6171325.aspx
trap_init();
//memory map初始化
//http://blog.csdn.net/huyugv_830913/archive/2010/09/15/5886970.aspx
mm_init();
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhi
armLinux系统start_kernel函 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)