当前位置: 首页 > news >正文

Linux内核代码学习笔记(2.6.21.7 ARM) -- 内核启动函数start_kernel

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

这几年都在与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:

ExpandedBlockStart.gif 代码
/*
 * 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();
        }
#endif

        
if  ( ! 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程序:

ExpandedBlockStart.gif 代码

/*  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实现具体的函数,所以一个函数可能在很多目录里的同名文件所实现。在查询是具体的哪个函数时,要对应的具体的体系结构。如果对应的具体体系结构里没有相关函数,就可在使用通用的函数或者通用的体系结构里的函数!

 

 

 

转载于:https://www.cnblogs.com/WuCountry/archive/2010/11/15/1878050.html

相关文章:

  • 将DataTable转换成类的方法
  • NOKIA C5-00怎么连接电脑??
  • 2010 支付宝DevDiv移动开发者大会[上海]
  • Java王者归来 6月Tiobe编程语言排行榜公布
  • 关于 在JQuery dialog里的服务器控件 事件失效问题
  • jquery的uploadify在 firefox 上传出问题,怎么解决啊
  • 从客户端(TexContent=rty内容)中检测到有潜在危险的Request.Form 值 解决方案
  • Linux--打包压缩 tar,gzip,bzip2
  • DataRow的RowState属性
  • HTML a 标签的 target 属性说明
  • 冬季谨防胃病复发 放松精神吃温热食物
  • 最经典的权限设计同样也是最糟糕的权限设计,权限设计理念最关键第一步之间的PK...
  • 回到达姆喽
  • 2011年通信运营的十大悬念
  • 改造面向过程式设计
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • ComponentOne 2017 V2版本正式发布
  • ECMAScript入门(七)--Module语法
  • Flex布局到底解决了什么问题
  • go语言学习初探(一)
  • Gradle 5.0 正式版发布
  • iOS | NSProxy
  • java多线程
  • Laravel 中的一个后期静态绑定
  • Mysql5.6主从复制
  • Promise面试题2实现异步串行执行
  • 从零开始学习部署
  • 马上搞懂 GeoJSON
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 物联网链路协议
  • 新版博客前端前瞻
  • 怎么将电脑中的声音录制成WAV格式
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (C++)八皇后问题
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (五)MySQL的备份及恢复
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .form文件_SSM框架文件上传篇
  • .Net 6.0 处理跨域的方式
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .net Stream篇(六)
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .net6 webapi log4net完整配置使用流程