前置:这里使用的linux版本是4.8,x86体系。

这篇是 http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html 的学习笔记。

linux的启动过程有点像是小鱼吃大鱼,最后吃成一个胖子。

计算机中的PC寄存器是用来指示下个执行程序。最开始的时候,pc寄存器都是指向0xfffffff0。这个程序是指向BIOS的POST程序的。POST全称是Power On Self Test,意思是加点自检。过程包括内存检查,系统总线检查等。

POST过程结束,就进入到了自举过程,自举过程把MBR(主引导扇区)加载到内存中,并且执行它。这个主引导扇区是第一个扇区的前512字节。

Master Boot Record过程是为了后面一个过程准备的。它主要做的是读入GRUB stage2所在的扇区。并且执行它。

GRUB stage2 将系统切换到保护模式。设置C运行环境。

然后进入到x86/boot/header.S中执行。在这里面,你能找到main的函数入口。这个对应到x86/boot/main.c的main函数。

这个main函数执行到最后会进入go_to_protected_mode(); 进入到pm.c的这个函数的定义,除了初始化一些逻辑以外,主要是protected_mode_jump

下面就进入到boot/pmjump.S的protected_mode_jump

29 protected_mode_jump:
30 movl %edx, %esi # Pointer to boot_params table
31
32 xorl %ebx, %ebx
33 movw %cs, %bx # 将实模式的代码段放入 bx
34 shll $4, %ebx # 转换为线性地址
35 addl %ebx, 2f # 将 in_pm32 的实模式地址转换为线性地址
36
37 movw $__BOOT_DS, %cx # ds 段选择子
38 movw $__BOOT_TSS, %di # tss 段选择子
39
40 movl %cr0, %edx
41 orb $X86_CR0_PE, %dl # Protected mode
42 movl %edx, %cr0 # 将 cr0 的0位置0是进入保护模式的标志
43 jmp 1f # Short jump to serialize on 386/486
44 1:
45 # 下面这段作用是跳转到 in_pm32,由于已经在保护模式,所以需要考虑段的问题
46 # Transition to 32-bit mode
47 .byte 0x66, 0xea # ljmpl opcode
48 2: .long in_pm32 # offset
49 .word __BOOT_CS # segment
50
51 .size protected_mode_jump, .-protected_mode_jump
52
53 .code32
54 .type in_pm32, @function
55 in_pm32: # 下面的注释挺清楚,就不翻译了
56 # Set up data segments for flat 32-bit mode
57 movl %ecx, %ds
58 movl %ecx, %es
59 movl %ecx, %fs
60 movl %ecx, %gs
61 movl %ecx, %ss
62 # The 32-bit code sets up its own stack, but this way we do have
63 # a valid stack if some debugging hack wants to use it.
64 addl %ebx, %esp
65
66 # Set up TR to make Intel VT happy
67 ltr %di # 这个比较有意思
68
69 # Clear registers to allow for future extensions to the
70 # 32-bit boot protocol
71 xorl %ecx, %ecx
72 xorl %edx, %edx
73 xorl %ebx, %ebx
74 xorl %ebp, %ebp
75 xorl %edi, %edi
76
77 # Set up LDTR to make Intel VT happy
78 lldt %cx # 又是一个骗 CPU 的东西 79 # eax 是 protected_mode_jump 的第一个参数,即 header.S 中定义的 boot_params.hdr.code32_start,即 vmlinux 的入口地址
80 jmpl *%eax # Jump to the 32-bit entrypoint
81
82 .size in_pm32, .-in_pm32

最后的jmpl就跳转到

arch/x86/kernel/head_32.S的startup_32

ENTRY(initial_code)
.long i386_start_kernel

进入到arch/x86/kernel/head32.c

asmlinkage __visible void __init i386_start_kernel(void)
{
cr4_init_shadow();
sanitize_boot_params(&boot_params); x86_early_init_platform_quirks(); /* Call the subarch specific early setup function */
switch (boot_params.hdr.hardware_subarch) {
case X86_SUBARCH_INTEL_MID:
x86_intel_mid_early_setup();
break;
case X86_SUBARCH_CE4100:
x86_ce4100_early_setup();
break;
default:
i386_default_early_setup();
break;
} start_kernel();
}

这里最后是调用了start_kernel,这里的start_kernel是与操作系统无关的init/main.c里面了。

参考

http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html

http://blog.csdn.net/alais/article/details/5129005

linux源码分析(二)-启动过程的更多相关文章

  1. mybatis源码分析:启动过程

    mybatis在开发中作为一个ORM框架使用的比较多,所谓ORM指的是Object Relation Mapping,直译过来就是对象关系映射,这个映射指的是java中的对象和数据库中的记录的映射,也 ...

  2. Nimbus<三>Storm源码分析--Nimbus启动过程

    Nimbus server, 首先从启动命令开始, 同样是使用storm命令"storm nimbus”来启动看下源码, 此处和上面client不同, jvmtype="-serv ...

  3. workerman源码分析之启动过程

    PHP一直以来以草根示人,它简单,易学,被大量应用于web开发,非常可惜的是大部分开发都在简单的增删改查,或者加上pdo,redis等客户端甚至分布式,以及规避语言本身的缺陷.然而这实在太委屈PHP了 ...

  4. elasticSearch6源码分析(1)启动过程

    1.找到bin目录,下面有elasticSearch的sh文件,查看执行过程 exec \ "$JAVA" \ $ES_JAVA_OPTS \ -Des.path.home=&qu ...

  5. Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7)

    http://blog.chinaunix.net/uid-20543672-id-3157283.html Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3 ...

  6. Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7)【转】

    原文地址:Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://bl ...

  7. Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】

    原文地址:Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.c ...

  8. linux源码分析2

    linux源码分析 这里使用的linux版本是4.8,x86体系. 这篇是 http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html  ...

  9. Dubbo 源码分析 - 服务调用过程

    注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...

  10. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

随机推荐

  1. Principles of measurement of sound intensity

    Introduction In accordance with the definition of instantaneous sound intensity as the product of th ...

  2. shell条件测试test

    shell条件测试可以通过以下两种方式: test   参数    测试内容 [ 参数  测试内容 ] 一.测试文件类型: test  -e   文件名          (测试文件是否存在) [ - ...

  3. 初识Opserver,StackExchange的监控解决方案

    Opserver是闻名遐迩的网站Stack Overflow的开源监控解决方案,由Stack Exchange发布.它基于.NET框架构建,这在监控工具领域有些与众不同. 旨在为每个受监控系统的健康状 ...

  4. 给公司部门设计的SOA架构

    新来老大年前开会说各位同学,公司业务越来越重,未来几年要成倍增长......,要梳理出一套新架构,才能更好的支持N万用户.....,以后升职加薪当上....打败..... 想想还有点小激动呢,于是过年 ...

  5. Andrew Ng机器学习公开课笔记 -- 学习理论

    网易公开课,第9,10课 notes,http://cs229.stanford.edu/notes/cs229-notes4.pdf 这章要讨论的问题是,如何去评价和选择学习算法   Bias/va ...

  6. 【Win10 应用开发】自适应Toast通知的XML文档结构

    老规矩,在开始之前老周先讲个故事. 话说公元2015年7月20日,VS 2015发布.于是,肯定有人会问老周了,C#6有啥新特性,我学不来啊.学不来的话你应该检讨.老周比较保守地计算一下,学会C# 6 ...

  7. lua解释执行脚本流程

    #include "lua.hpp" #include <iostream> using namespace std; #pragma comment(lib, &qu ...

  8. 传智播客--XAML布局--连连看界面(小白内容)

    一个简单的10*10连连看,有100个格子,可以在XAML里面用ColumnDefinition和RowDefinition各写10组,但是这样效率会很慢,因此,可以采用动态生成的方式进行. publ ...

  9. 【原创】开源Math.NET基础数学类库使用(13)C#实现其他随机数生成器

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  10. codefordream 关于js初级训练

    这里的初级训练相对简单,差不多都是以前知识温习. 比如输出“hello world”,直接使用console.log()就行.注释符号,“//”可以注释单行,快捷键 alt+/,"/*   ...