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

Unix/Linux
linux查看内存的大小
在linux下写的代码,用的是utf-8,结果拿到XP下运行的时候,所有的中文都成乱码
linux su和sudo命令的区别
linux cron 下的定时执行工具使用技巧
linux 查找进程及终止进程操作的相关命令
redhat linux 安装 gcc编译器
Linux Mplayer播放各种格式的电影
一起回顾一下linux常用命令
Linux 网站项目发布要做哪些配置
linux SSH配合SecureCRT的密匙完美使用方法
GD 编译出错解决方法
Facebook Open Platform编译FAQ
Linux 系统硬盘 优化
linux 挂载详解
linux crontab定时命令
Linux 系统中确保访问三级域名畅通的方法
Linux 特权帐号VS普通帐号
确保Linux系统安全的前提条件 漏洞防护
Linux 监视系统资源使用率
Red Hat Linux上使用BIND建立DNS服务器

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


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