linux源码分析2
2016-10-26 22:00
218 查看
linux源码分析
这里使用的linux版本是4.8,x86体系。这篇是 http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html 的学习笔记。
linux的启动过程有点像是小鱼吃大鱼,最后吃成一个胖子。
![](https://images2015.cnblogs.com/blog/136188/201610/136188-20161025130134421-903353143.png)
计算机中的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.htmlhttp://blog.csdn.net/alais/article/details/5129005
相关文章推荐
- Linux netfilter源码分析(1)
- Linux内核2.6.14源码分析-双向循环链表代码分析
- Linux netfilter源码分析(5)
- 转载 linux 2.6线程创建源码分析
- Linux netfilter源码分析(2)
- Linux下Libpcap源码分析和包过滤机制
- Linux netfilter源码分析(4)
- Linux netfilter源码分析(3)
- Linux内核源码分析(1)——compiler.h分析(2)
- Uboot-1.1.2 do_bootm_linux函数源码分析
- linux 2.6 互斥锁的实现-源码分析
- linux源码分析之cpu初始化 kernel/head.s
- Linux TCP/IP 协议栈源码分析(一)
- Linux下USB suspend/resume源码分析
- Linux网桥源码框架分析初步
- Linux 学习数据专题【管理、编程、源码分析】——Linux相关图书选购指南
- arm-linux源码分析之cpu初始化
- Linux netfilter源码分析(7)
- Linux-2.6.25 select系统调用源码分析
- Linux下Libpcap源码分析和包过滤机制