当前位置: 首页 > 图文教程 > 操作系统 > Unix/Linux > linux核心代码分析(系统初始化start_kernel函数)

Unix/Linux
FreeBSD 数据转移办法
Freebsd 下运行QQ For Linux 的方法
FreeBSD, Debian, CentOS一个网卡绑定多个IP
freebsd下切换到root下 su: Sorry 的解决办法
Freebsd挂载光驱和软驱
FREEBSD下运行调试asterisk
一些 freebsd 的常用命令
笔记本上安装freebsd的小知识
FreeBSD系统下添加中文字体
FreeBSD挂载DOS分区,正确显示中文
FreeBSD挂载DOS分区时显示中文的方法
freebsd7.0安装系统图解(最新版)
服务器的时间同步设置方法
FreeBSD FTP 的架设教程
FreeBSD mpd VPN服务器安装步骤
更新FreeBSD Port Tree的几种方法小结
portupgrade 中文手册(翻译)
freebsd 服务器 ARP绑定脚本
在Ubuntu系统中定制 Compiz Fusion 特效
Ubuntu 7.10 绑定IP及MAC地址

Unix/Linux 中的 linux核心代码分析(系统初始化start_kernel函数)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-01   浏览: 184 ::
收藏到网摘: n/a

 
至于x86的引导无非如下步骤:
1,cpu初始化自身,在固定位置执行一条指令。
2,这条指令条转到bios中。
3,bios找到启动设备并获取mbr,该mbr指向我们的lilo
4,bios装载并把控制权交给lilo
5,压缩内核自解压,并把控制权转交给解压内核。
简单点讲,就是cpu成为内核引导程序的引导程序的引导程序的引导程序,西西。
这时内核将跳转到start_kernel是/init/main.c的重点函数,main.c函数很多定义都是为此函数服务的,这里
我简要介绍一下这个函数的初始化流程。
初始化内核:
从start_kernel函数(/init/main.c)开始系统初始化工作,好,我们首先分析这个函数:
函数开始首先:
#ifdef __SMP__
 static int boot_cpu = 1;
 /* "current" has been set up, we need to load it now *//*定义双处理器用*/
 if (!boot_cpu)
 initialize_secondary();
 boot_cpu = 0;
#endif
定义双处理器。
printk(linux_banner);    /*打印linux banner*/
打印内核标题信息。
开始初始化自身的部分组件(包括内存,硬件终端,调度等),我来逐个分析其中的函数:
setup_arch(&command_line, &memory_start, &memory_end);/*初始化内存*/
返回内核参数和内核可用的物理地址范围
函数原型如下:
setup_arch(char **, unsigned long *, unsigned long *);
返回内存起始地址:
memory_start = paging_init(memory_start,memory_end);
看看paging_init的定义,是初始化请求页:
paging_init(unsigned long start_mem, unsigned long end_mem)(会在以后的内存管理子系统分析时详细介
绍)
{
 int i;
 struct memclust_struct * cluster;
 struct memdesc_struct * memdesc;
 /* initialize mem_map[] */
 start_mem = free_area_init(start_mem, end_mem);/*遍历查找内存的空闲页*/
 /* find free clusters, update mem_map[] accordingly */
 memdesc = (struct memdesc_struct *)
 (hwrpb->mddt_offset + (unsigned long) hwrpb);
 cluster = memdesc->cluster;
 for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
 unsigned long pfn, nr;
 /* Bit 0 is console/PALcode reserved. Bit 1 is
   non-volatile memory -- we might want to mark
   this for later */
 if (cluster->usage & 3)
  continue;
 pfn = cluster->start_pfn;
 if (pfn >= MAP_NR(end_mem)) /* if we overrode mem size */
  continue;
 nr = cluster->numpages;
 if ((pfn + nr) > MAP_NR(end_mem)) /* if override in cluster */
  nr = MAP_NR(end_mem) - pfn;
 while (nr--)
  clear_bit(PG_reserved, &mem_map[pfn++].flags);
 }
 memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
 return start_mem;
}
trap_init();   初始化硬件中断
/arch/i386/kernel/traps.c文件里定义此函数
sched_init()   初始化调度
/kernel/sched.c文件里有详细的调度算法(这些会在以后进程管理和调度的结构分析中详细介绍)
parse_options(command_line) 分析传给内核的各种选项(随后再详细介绍)
memory_start = console_init(memory_start,memory_end) 初始化控制台
memory_start = kmem_cache_init(memory_start, memory_end) 初始化内核内存cache(同样,在以后的内存
管理分析中介绍此函数)
sti();接受硬件中断
kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 current->need_resched