混沌初开--内核启动笔记

先隆重介绍这个网站 https://www.gitbook.com/book/0xax/linux-insides/details

实在太好了,膜拜,膜拜,膜拜。

bootloader加载内核到内存

bootloader之前的我就不关心了,主要关心加载到内存以及之后的事情。从这篇文章中才知道原来内核加载是有自己的协议的,我也是醉了阿。这个可以从 boot protocol 看到原文,有兴趣的同学可以参考。

先看一眼人家是怎么讲的。

When using bzImage, the protected-mode kernel was relocated to
0x100000 (“high memory”), and the kernel real-mode block (boot sector,
setup, and stack/heap) was made relocatable to any address between
0x10000 and end of low memory. Unfortunately, in protocols 2.00 and
2.01 the 0x90000+ memory range is still used internally by the kernel; the 2.02 protocol resolves that problem.

再看人家怎么给你画的一张图。

    ~                        ~
        |  Protected-mode kernel |
100000  +------------------------+
        |  I/O memory hole       |
0A0000  +------------------------+
        |  Reserved for BIOS     |  Leave as much as possible unused
        ~                        ~
        |  Command line          |  (Can also be below the X+10000 mark)
X+10000 +------------------------+
        |  Stack/heap            |  For use by the kernel real-mode code.
X+08000 +------------------------+  
        |  Kernel setup          |  The kernel real-mode code.
        |  Kernel boot sector    |  The kernel legacy boot sector.
      X +------------------------+
        |  Boot loader           |  <- Boot sector entry point 0000:7C00
001000  +------------------------+
        |  Reserved for MBR/BIOS |
000800  +------------------------+
        |  Typically used by MBR |
000600  +------------------------+ 
        |  BIOS use only         |
000000  +------------------------+

看到这里我真的是眼泪水也要掉出来了,你看人家工程师是多么敬业,这个都给你画出来了呀。

这里我来多说两句,这张图上我们关心的,(应该说是我)

  • 一个是 Kernel boot sector + Kernel setup
  • 一个是 Protected-mode kernel

记得 我们 之前看bzImage编译过程中遇到过啥, bzImage 是由两部分组成的

  • setup.bin
  • vmlinux.bin

正好一个对一个。 Kernel boot sector是setup.bin中前512字节。

啊,世界突然清净了些。。。

跳跳跳~ 那些年都没有理清的细节

忙活了一两个月,总结了这么一张图。希望你会喜欢。

                  +------------------------+
                  |                        |
                  |  *relocated            |
                  |                        |
                  |                        |
                  |  Protected-mode kernel |
                  |                        |
                  |                        |
    1000000 + off |                        |
                  +........................+  5th jump: after compressed kernel relocated
                  |                        |
                  |                        |
                  |                        |  9th jump: to start_kernel()
                  |                        |
                  |                        |  8th jump: to the c code world
                  |                        |
                  |                        |  7th jump: use virtual address
                  |                        |
                  |                        |
                  |                        |
    1000000 (16M) +------------------------+  6th jump: to startup_64 in arch/x86/kernel/head_64.S
                  |                        |
                  ~                        ~
                  |                        |
                  +------------------------+
                  |  page table (16k size) |
                  |                        |
                  +........................+
                  |  stack (4k or 16k size)|
                  +........................+
                  |  heap  (16k or 4M size)|
                  +........................+
                  |                        |
                  |                        |
                  |                        |
                  |  Protected-mode kernel |
                  |                        |
                  |                        |
    100200        |  *startup_64           |   4th jump: from 32bit protected mode to long mode
                  |                        |
                  |  *startup_32           |
    100000  (1M)  +------------------------+   3rd jump: from header.S to head_64.S
                  |                        |
                  ~                        ~
                  |                        |        
    X+10000       +------------------------+
                  |  Stack/heap            |        
    X+08000       +------------------------+        
                  |  Kernel setup          |   2nd jump: real mode to protected mode 
    x+512         +------------------------+   1st jump: boot loader to header.S
                  |  Kernel boot sector    |        
    X             +------------------------+
                  |  Boot loader           |        
    001000  (4K)  +------------------------+
                  |                        |
                  ~                        ~
                  |                        |
    000000        +------------------------+

人往高处走,水往地处流。看来代码他也是往高处走的~

第一跳 – 从bootloader到setup

从硬盘上加载内核到内存后,就开始要第一次跳转到我们亲手编译的内核了。那这第一跳是跳到哪里呢?

用了内核这么多年,编了内核这么多年,还写了不少补丁,竟然不知道!还是这个boot protocol 中有写。

摘出最关键的部分,其余的大家自行研究~

The kernel is started by jumping to the kernel entry point, which is
located at segment offset 0x20 from the start of the real mode
kernel. This means that if you loaded your real-mode kernel code at
0x90000, the kernel entry point is 9020:0000.

其实就是从setup.bin的0x200 = 512的位置,瞅一眼代码

"archc/x86/boot/head.S"

    # offset 512, entry point

    .globl  _start
_start:

你的明白?

第二跳 – 进入保护模式

我们现在已经愉快的进入了内核的世界。不过这个时候CPU还是运行在实模式的,内核需要做点准备进入到保护模式。可以认为就是让CPU运行在一个高级的模式。

刚才在arch/x86/boot/head.S的_start后面做了点简单的初始化,就运行到了main函数。这个函数定义在arch/x86/boot/main.c,样子是

"arch/x86/boot/main.c"

void main(void)
{
    /* First, copy the boot
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值