惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
N
News and Events Feed by Topic
D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Engineering at Meta
Engineering at Meta
T
Tailwind CSS Blog
博客园_首页
Microsoft Azure Blog
Microsoft Azure Blog
Y
Y Combinator Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
月光博客
月光博客
A
About on SuperTechFans
I
InfoQ
S
Securelist
Last Week in AI
Last Week in AI
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Hacker News: Ask HN
Hacker News: Ask HN
Schneier on Security
Schneier on Security
Know Your Adversary
Know Your Adversary
腾讯CDC
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs
博客园 - 三生石上(FineUI控件)
Simon Willison's Weblog
Simon Willison's Weblog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
美团技术团队
aimingoo的专栏
aimingoo的专栏
G
Google Developers Blog
罗磊的独立博客
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
S
Secure Thoughts
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Latest news
Latest news
Recent Announcements
Recent Announcements
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
L
LINUX DO - 热门话题
Security Latest
Security Latest
TaoSecurity Blog
TaoSecurity Blog
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队

博客园 - Edison.Feng

Objective-读Xml [转]iPhone Mapkit 之在地图加入坐标点 使用MKAnnotation和MKAnnotationView [转]Android:使用URL和URLConnection(多线程下载) 【转】httpModules 与 httpHandlers 【转】挣脱浏览器的束缚(2) - 别让脚本引入坏了事 [转]asp.net中利用ashx实现图片防盗链 求任何一个正数的组合,组合的规则是这个数等于1或2的整数幂之和,请列出组合的情况。 C#利用反射获取对象属性的修改情况 C#利用反射获取对象属性值 Clone:Xml序列化反序列克隆对象 [转]Linux slab 分配器剖析 [转]Linux对I/O端口资源的管理 start_kernel paging_init [转]Linux TCP/IP 协议栈的关键数据结构Socket Buffer(sk_buff ) [转]Linux系统内核接收以太帧的处理程序 母牛生小牛(递归) MS SQL:Funcation拆分行 我使用WebService:Function.asmx的惊叹!!!
[转]linux内核分析-初始化分析
Edison.Feng · 2009-04-27 · via 博客园 - Edison.Feng

参考我提供的三个文件:bootsect.txt,head.txt,setup.txt
至于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 = 1; need_resched标志增加,调用schedule(调度里面会详细说明)
cpu_idle(NULL) 进入idle循环以消耗空闲的cpu时间片

已经基本完成内核初始化工作,已经把需要完成的少量责任传递给了init,所身于地工作不过是进入idle循环以消耗空闲的cpu时间片。所以在这里调用了cpu_idle(NULL),它从不返回,所以当有实际工作好处理时,该函数就会被抢占。

parse_options函数:
static void __init parse_options(char *line)/*参数收集在一条长命令行中,内核被赋给指向该命令行头部的指针*/

{

char *next;

char *quote;

int args, envs;

if (!*line) return;

args = 0;

envs = 1;/* TERM is set to 'linux' by default */

next = line;

while ((line = next) != NULL)

{

quote = strchr(line,'"');

next = strchr(line, ' ');

while (next != NULL && quote != NULL && quote < next)

{

next = strchr(quote+1, '"');

if (next != NULL) {

quote = strchr(next+1, '"');

next = strchr(next+1, ' ');

}

}

if (next != NULL)

*next++ = 0;

/*

* check for kernel options first..

*/

if (!strcmp(line,"ro"))

{

root_mountflags |= MS_RDONLY;

continue;

}

if (!strcmp(line,"rw"))

{

root_mountflags &= ~MS_RDONLY;

continue;

}

if (!strcmp(line,"debug"))

{

console_loglevel = 10;

continue;

}

if (!strcmp(line,"quiet"))

{

console_loglevel = 4;

continue;

}

if (!strncmp(line,"init=",5))

{

line += 5;

execute_command = line;

args = 0;

continue;

}

if (checksetup(line))

continue;

if (strchr(line,'='))

{

if (envs >= MAX_INIT_ENVS)

break;

envp_init[++envs] = line;

}

else

{

if (args >= MAX_INIT_ARGS)

break;

argv_init[++args] = line;

}

argv_init[args+1] = NULL;

envp_init[envs+1] = NULL;

}