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

Unix/Linux
Linux 备份 恢复方法
Linux玩CS反恐精英的方法
在一个ISO镜像中集成多个不同的linux发行版,可刻盘,可引导
Linux 快捷键使用
Linux DHCP 服务器配置方法介绍
Linux 22端口的修改方法
Linux 记录会话过程的命令
Linux 后台执行程序如何操作?
linux Wget命令来浏览网页的方法
Linux tail命令的巧妙应用
Wine 中文存在很多的乱码怎么解决方法
linux 新手教程之创建锁文件的方法
配置Linux 保证其系统的安全
Linux DHCP协议实现过程
Linux系统下破解SAM密码
linux/unix vi 编辑器用法详解
Linux 误删文件的解决方法
Linux系统下的历史记录删除方法
Red Hat Linux 安全设置指南
Linux基本命令-注销、关机、重启

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-01   浏览: 51 ::
收藏到网摘: 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