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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Wu.Country@侠缘

与我相关的一些链接 - Wu.Country@侠缘 [Linux]OpenSuse12图形和文字界面转换 haneWIN NFS Server An Introduction to the Linux-based Assignments Booting Linux with U-Boot on QEMU ARM Using The mkimage Tool To Create U-Boot Images SUSE安全大揭秘之“十诫” [Copy]如何使用qemu执行交叉环境下的内核镜像文件 CT-NG编译错误以及解决办法 无法忍受在SUSE10上安装开发环境了 Windows的路由命令 【CLFS】记录: [读书笔记]Binary Hancks(2) livepatch在X86下的实践 [读书笔记]Binary Hancks(1) ARM Stack Unwinding Physical Address Extension - PAE Memory and Windows 如何制作grub启动光盘 [译]Kernel Memory Layout on ARM Linux [转]ucLinux下sqlite数据库移植全攻略
Linux内核代码学习笔记(2.6.21.7 ARM) -- 内核启动函数start_kernel
Wu.Country@侠 · 2010-11-15 · via 博客园 - Wu.Country@侠缘

其实对内核的代码已经分析很久了,早就想自己写些什么,从今天开始,从新继续我的博客!

这几年都在与Linux打交道了,而且我觉得我也真正的爱上了Linux,所以就写些Linux的东西吧!

Linux的东西很多,就内核而言,已经无法一个人去了解所有的机制和细节了。但好在源码是可以随时取到的,只要你熟悉和了解内核的一些基本特性,还是可以很容易上手的!

下面,我就把我自己的一些学习经历写出来和大家分享一下!

首选,内核代码里有大小写重名的文件,所以,从网上下载了内核源码包以后,不能直接在Windows下解压,否则会有些文件被大小写重复的文件名复盖掉!主要是网络相关的。我暂时先不想了解网络相关的内容,所以,就先在Windows下,使用SourceInsight来看代码!如果要看到全部的代码,还是要在Linux系统下解压代码!

另外,我对X86体系结构的代码也暂时不感兴趣,先从ARM入手,不过不同的体系结构,关系并不太大,明白一些机制以后,大部份是一样的!

先从第一个函数入手:

E:\Projects\kernel\linux-2.6.21.1.src\init\main.c (501/825)

asmlinkage void __init start_kernel(void);

这个函数是内核由引导程序引导以后,由自解压程序解压以后执行的第一个函数,可以认为是整个内核的入口函数,以后我分析的代码全部从这个函数开始!

这个函数做的事情相对比较简单,就是线性的初始化一些内核的基础机制,如中断,内存管理,进程管理,信号,文件系统,KO等!最后就启动一个init线程,init线程再读取文件系统里的init程序,做为系统的第一个进程而存在!

其实,start_kernel函数是0是做为0号进程存在的,它在最后就是空转CPU:

代码

/*
 * The idle thread.  We try to conserve power, while trying to keep
 * overall latency low.  The architecture specific idle is passed
 * a value to indicate the level of "idleness" of the system.
 
*/
void cpu_idle(void)
{
    local_fiq_enable();
/* endless idle loop with no priority at all */
    
while (1) {
        
void (*idle)(void= pm_idle;

#ifdef CONFIG_HOTPLUG_CPU

if (cpu_is_offline(smp_processor_id())) {
            leds_event(led_idle_start);
            cpu_die();
        }
#endifif (!idle)
            idle 
= default_idle;
        leds_event(led_idle_start);
        
while (!need_resched())
            idle();
        leds_event(led_idle_end);
        preempt_enable_no_resched();
        schedule();
        preempt_disable();
    }
}

而在它之前,启动的init线程,则是运行文件系统里的init程序:

代码

/* This is a non __init function. Force it to be noinline otherwise gcc
 * makes it inline to init() and it becomes part of init.text section
 
*/
static int noinline init_post(void)
{
    free_initmem();
    unlock_kernel();
    mark_rodata_ro();
    system_state 
= SYSTEM_RUNNING;
    numa_default_policy();
if (sys_open((const char __user *"/dev/console", O_RDWR, 0< 0)
        printk(KERN_WARNING 
"Warning: unable to open an initial console.\n");

    (

void) sys_dup(0);
    (
void) sys_dup(0);if (ramdisk_execute_command) {
        run_init_process(ramdisk_execute_command);
        printk(KERN_WARNING 
"Failed to execute %s\n",
                ramdisk_execute_command);
    }
/*
     * We try each of these until one succeeds.
     *
     * The Bourne shell can be used instead of init if we are
     * trying to recover a really broken machine.
     
*/
    
if (execute_command) {

  /* 如果有启动参数做为执行命令,就执行 */
        run_init_process(execute_command);
        printk(KERN_WARNING 
"Failed to execute %s.  Attempting "
                    
"defaults...\n", execute_command);
    }

  /* 依次查询文件系统里的init程序,这里的run_init_process函数不能返回,否则启动失败 */
    run_init_process(
"/sbin/init");
    run_init_process(
"/etc/init");
    run_init_process(
"/bin/init");
    run_init_process(
"/bin/sh");

    panic(

"No init found.  Try passing init= option to kernel.");
}

 因为内核为很多体系结构的CPU实现具体的函数,所以一个函数可能在很多目录里的同名文件所实现。在查询是具体的哪个函数时,要对应的具体的体系结构。如果对应的具体体系结构里没有相关函数,就可在使用通用的函数或者通用的体系结构里的函数!

================================
  /\_/\                        
 (=^o^=)  Wu.Country@侠缘      
 (~)@(~)  一辈子,用心做一件事!
--------------------------------
  学而不思则罔,思而不学则怠!  
================================