0. 声明

kernel版本号3.10.53

1. 链接脚本

arch/arm/kernel/vmlinux.lds.S ==>vmlinux.lds

生成的链接脚本(vmlinux.lds)中的重点内容如下:

OUTPUT_ARCH(arm)
ENTRY(stext)
······

根据链接脚本可知kernel执行入口为stext,搜索stext即可得到入口函数的定义。

2. 入口函数(stext)实现

函数stext是一个汇编函数,其定义在arch/arm/kernel/head.S中,stext函数主要做了以下几件事:

(1) 关闭irq和fiq,设置svc管理模式
(2) 判断是或支持这个CPU
(3) 判断是否支持这个单板(通过uboot传入的机器ID判断)
(4) 创建页表,为后面的MMU做准备
(5) 使能MMU并跳到__switch_data处,复制数据段,清除bss段,设置栈,调用start_kernel第一个C函数

简化后的代码如下:

ENTRY(stext)
ldr     r13, =__mmap_switched     @将__mmap_switched函数地址存放到r13寄存器
1:      b       __enable_mmu
ENDPROC(stext)
--------------------------------------------------------------------------__enable_mmu:
b       __turn_mmu_onENDPROC(__enable_mmu)
--------------------------------------------------------------------------
ENTRY(__turn_mmu_on)
mov     r3, r13    @将r13寄存器中的值存放到r3寄存器
mov     pc, r3     @将PC指针指向r3寄存器中存放的地址
ENDPROC(__turn_mmu_on)
-------------------------------------------------------------------------__mmap_switched:          @ arch/arm/kernel/head-common.Sb       start_kernel
ENDPROC(__mmap_switched)//调用流程总结:stext--->__enable_mmu--->__turn_mmu_on--->__mmap_switched--->start_kernel

3.start_kernel函数

函数start_kernel是kernel启动过程中调用的第一个C函数,其定义在 init/main.c 中;在start_kernel函数中执行了大量的初始化工作,以下是挑选出来的一小部分常见和常用的初始化内容:

asmlinkage void __init start_kernel(void)
{/*打印以下linux版本信息:       “Linux version 2.6.22.6(gcc version 3.4.5) #1 Fri Jun 16 00:55:53 CST 2017” */printk(linux_banner);//系结构相关的内核初始化过程,处理uboot传递进来的atag参数 setup_arch(&command_line);/* 进程调度器初始化 */sched_init(); /* 禁止内核抢占 */  preempt_disable();/* 打印Linux启动命令行参数 */   printk(KERN_NOTICE "Kernel command line: %s/n", boot_command_line);//初始化定时器Timer相关的数据结构  init_timers();  //软中断初始化    softirq_init(); //初始化时钟源  timekeeping_init()//初始化控制台以显示printk的内容,在此之前调用的printk,只是把数据存到缓冲区里,  //只有在这个函数调用后,才会在控制台打印出内容  //该函数执行后可调用printk()函数将log_buf中符合打印级别要求的系统信息打印到控制台上。  console_init(); /* 虚拟文件系统的初始化 */vfs_caches_init_early();  //测试CPU的各种缺陷,记录检测到的缺陷,以便于内核的其他部分以后可以使用他们工作。  check_bugs();  //电源相关的初始化  //http://blogold.chinaunix.net/u/548/showart.php?id=377952  acpi_early_init(); /* before LAPIC and SMP init */ //接着进入rest_init()创建init进程,创建根文件系统,启动应用程序rest_init();
}static noinline void __init_refok rest_init(void)
{//启动init进程,然后进入kernel_init中启动应用程序kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
}static int __ref kernel_init(void *unused)
{if (execute_command) {   //解析并挂载根文件系统if (!run_init_process(execute_command))return 0;pr_err("Failed to execute %s.  Attempting defaults...\n",execute_command);}if (!run_init_process("/sbin/init") ||  //执行应用程序!run_init_process("/etc/init") ||   //执行应用程序!run_init_process("/bin/init") ||   //执行应用程序!run_init_process("/bin/sh"))       //执行应用程序return 0
}

4. 小发现

在分析第二步的时候调用了head-common.S文件中的__mmap_switched函数,但是head-common.S却并没有被编译为.o文件???

验证步骤:

4.1 执行命令 grep -nr "head-common" *,发现head.S文件末尾有如下包含语句

#include "head-common.S"

4.2 执行反汇编命令将head.o反汇编

arm-linux-androideabi-objdump -d head.o > head.txt

4.3 打开反汇编文件head.txt可以发现其中有__mmap_switched函数的定义

0000005c <__mmap_switched>:5c:   e28f3044        add     r3, pc, #68     ; 0x4460:   e8b300f0        ldm     r3!, {r4, r5, r6, r7}64:   e1540005        cmp     r4, r568:   11550006        cmpne   r5, r66c:   1494b004        ldrne   fp, [r4], #470:   1485b004        strne   fp, [r5], #474:   1afffffb        bne     68 <__mmap_switched+0xc>78:   e3a0b000        mov     fp, #07c:   e1560007        cmp     r6, r780:   3486b004        strcc   fp, [r6], #484:   3afffffc        bcc     7c <__mmap_switched+0x20>88:   e89320f0        ldm     r3, {r4, r5, r6, r7, sp}8c:   e5849000        str     r9, [r4]90:   e5851000        str     r1, [r5]94:   e5862000        str     r2, [r6]98:   e3570000        cmp     r7, #09c:   13c04002        bicne   r4, r0, #2a0:   18870011        stmne   r7, {r0, r4}a4:   eafffffe        b       0 <start_kernel>
000000a8 <__mmap_switched_data>:

4.4 总结:head.o 中好像只包含了head-common.S文件中的部分函数

Linux kernel启动过程相关推荐

  1. arm linux内核启动过程,ARM64的启动过程之(一):内核第一个脚印

    ARM64的启动过程之(一):内核第一个脚印 作者:linuxer 发布于:2015-10-10 15:06 分类:ARMv8A Arch 一.前言 kernel的整个启动过程涉及的内容很多,不可能每 ...

  2. Linux开启动过程详解

    Linux开启动过程详解 Linux启动过程 前言: Linux是一种自由和开放源代码的类UNIX操作系统.该操作系统的内核由林纳斯·托瓦兹在1991年10月5日首次发布.在加上用户空间的应用程序之后 ...

  3. linux文件系统启动流程,linux 内核启动过程以及挂载android 根文件系统的过程

    转载 作者:汕头大学-黄珠唐 时间:2009 年10 月29 日 主要介绍linux 内核启动过程以及挂载android 根文件系统的过程,以及介绍android 源代码中文件系统部分的浅析. 主要源 ...

  4. Linux内核启动过程概述

    Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创造出自己的内核^_^ Linux的启动代码真的挺大,从汇 ...

  5. linux 打开上一级目录,linux开机启动过程、PATH、过滤一级目录、cd的参数、ls -lrt、命令切割日志...

    第二波命令正向我方来袭 :开机启动过程.PATH.过滤一级目录.cd的参数.ls -lrt.命令切割日志 1.1 linux开机启动过程 1.1.1 开机自检(BIOS)-- MBR引导-- GRUB ...

  6. 简述arm linux内核启动流程,Linux内核启动过程和Bootloader(总述)

    1.Linux内核启动过程概述 一个嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(Bootloader),Linux 内核,文件系统,应用程序.其中 Bootloader是系统启 ...

  7. linux内核启动过程5:启动用户空间

    上一篇<<linux内核启动过程4:内核运行时>>分析到了内核进入运行时状态(不退出),本篇分析用户空间(用户层)的加载过程. 启动应用空间 进入kernel_init函数,在 ...

  8. linux内核启动过程4:内核运行时

    上一篇<<linux内核启动过程3:内核初始化阶段>>分析到了start_kernel执行流程,本篇继续内核切换到运行时状态. 内核运行时状态 内核初始化流程已经分析完成,如何 ...

  9. Linux内核启动过程和Bootloader(总述)

    1.Linux内核启动过程概述     一个嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(Bootloader),Linux 内核,文件系统,应用程序.其中 Bootloader ...

最新文章

  1. 学会Python后能找到什么工作,待遇如何?
  2. PHP的抽象类的一段简单代码示例
  3. Linux自动备份文件(linux计划任务)
  4. python数值型转换字符型_2.6 字符型常量
  5. MathType公式保存后为什么字体会变化
  6. 我爱的人,你知道我一直在
  7. 用php打出前一天的时间格式,[php]用PHP打印出前一天的时间格式
  8. 第一次使用 Blog
  9. Linux SElinux
  10. C语言变量声明问题——变量定义一定要放在所有执行语句/语句块的最前面吗?
  11. 2-7 hash(2)
  12. matlab如何仿真递推型dft算法,并联型有源滤波器的设计与仿真
  13. IDEA 思维导图 ,类UML 图工具插件 plantUML integration
  14. 运算放大器分析----虚短和虚断简单计算
  15. 电商一定是一元化结构
  16. 【解决方案】“博物馆热”背后,如何建设安防视频监控体系保障文物安全?
  17. 你一定要这么多功能么?——献给希望创业的兄弟们
  18. Linux 磁盘管理-配额管理-配置用户对磁盘进行指定大小或者文件数量的使用权限
  19. PLM,是一个英文缩写,有2个含义,一是表示产品生命周期管理(product lifecycle management,PLM),...
  20. vue封装上拉菜单组件_Vue的灵活的lil上下文菜单组件

热门文章

  1. PX4算法:L1制导律(二)
  2. Excel冻结窗口设置,可以让表头固定不动
  3. Python文本文件内容修改实例(支持正则表达式)
  4. 日暮·第二章·烽烟传讯
  5. 【机械】圆锥轴半圆键失效分析(DLE-120cc发动机)
  6. 汇编语言-- 实验三 子程序应用(数制转换)程序设计
  7. KMeans秘籍之如何选取初始质心
  8. Linux系统编程之API(fputc、fget和feof)
  9. git删除本地分支和删除远程分支
  10. 北京市第二批国家专精特新小巨人企业高质量发展项目申报要求,补贴1500万