Linux BSP实战课(SoC bringup篇):Kernel 的初始化过程

科技   2023-11-21 08:08   江苏  
  • 内核运行的第一行代码

    • .head.text 文本段

  • Head.S

  • start_kernel

    • setup_arch

    • mm_init

    • sched_init

    • init_IRQ

    • tick_init

    • init_timers

    • hrtimers_init

    • softirq_init

    • time_init

    • console_init

    • vfs_caches_init

    • rest_init


上文我们讲到,内核中各个阶段的初始化非常重要,涉及内容很多,比如内存管理,进程管理,文件系统,中断管理,时钟管理等。就算浅尝辄止的描述每个模块,至少也要一万字的总结,所以内核的重要程度很有必要单独作为一章梳理。

让我们一起正式进入内核的世界,站在内核的角度,内核之前的所有程序都是系统引导程序,其中 CPU 的状态如下:

r0 = 0.

r1 = CPU 类型.

r2 = kernel参数list的物理地址.

irq & fiq 必须关闭.

MMU 必须关闭,这里内存地址都是物理地址.

D-cache 必须关闭,I-cache 没有要求.

内核运行的第一行代码

Linux启动,会启动内核编译后的文件 vmlinux,vmlinux 是一个 ELF 文件,按照 ./arch/arm64/kernel/vmlinux.lds 设定的规则进行链接,vmlinux.lds 是 vmlinux.lds.S 编译之后生成的。所以为了确定 vmlinux 内核的起始地址, 首先通过 vmlinux.lds.S 链接脚本进行分析。如下所示:

$ readelf -h vmlinux
ELF Header:
  Magic:   7f 45 446 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           AArch64
  Version:                           0x1
  Entry point address:               0xffff800010000000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          494679672 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         5
  Size of section headers:           64 (bytes)
  Number of section headers:         38
  Section header string table index: 37
$ readelf -l vmlinux

Elf file type is DYN (Shared object file)
Entry point 0xffff800010000000
There are 5 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000010000 0xffff800010000000 0xffff800010000000
                 0x0000000001beacdc 0x0000000001beacdc  RWE    10000
  LOAD           0x0000000001c00000 0xffff800011c00000 0xffff800011c00000
                 0x00000000000c899c 0x00000000000c899c  R E    10000
  LOAD           0x0000000001cd0000 0xffff800011cd0000 0xffff800011cd0000
                 0x0000000000876200 0x0000000000905794  RW     10000
  NOTE           0x0000000001bfaca0 0xffff800011beaca0 0xffff800011beaca0
                 0x000000000000003c 0x000000000000003c  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10

 Section to Segment mapping:
  Segment Sections...
   00     .head.text .text .got.plt .rodata .pci_fixup __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver __ex_table .notes
   01     .init.text .exit.text .altinstructions
   02     .init.data .data..percpu .hyp.data..percpu .rela.dyn .data __bug_table .mmuoff.data.write .mmuoff.data.read .pecoff_edata_padding .bss
   03     .notes
   04

通过上面的查询可知,此 vmlinux 为一个 aarch64 架构平台的 ELF 可执行文件,其程序入口的地址为 0xffff800010000000,此段对应的 section 为.head.text .text .got.plt......,所以 vmlinux 的入口在 .head.text 文本段。

人人极客社区
工程师们自己的Linux底层技术社区,分享体系架构、内核、网络、安全和驱动。
 最新文章