Linux内核在arm上的启动过程

简介: Linux内核在arm上的启动过程

Linux内核加载过程


通常,Linux内核都是经过gzip加载过之后的映像文件。


  • bootloader复制压缩内核到内存空间。
  • 内核自解压。
  • 运行内核。


编译完成的Linux内核存放在哪里?


  • ./vmlinux elf格式未压缩内核。
  • arch/arm/boot/compressed/vmlinux 压缩以后的elf格式内核。
  • arch/arm/boot/zImage 压缩内核。


压缩内核(zImage)的入口


  • /arch/arm/boot/compressed/vmlinux.lds 该文件为编译器指定link顺序。
  • ENTRY(_start) 压缩内核从.start段开始执行。
  • 在/arch/arm/boot/compressed/head.S中执行以下爱操作:
  (1)检测系统空间。
  (2)初始化C代码空间。
  (3)跳转到C代码decompress_kernel,
           arch/arm/boot/compressed/misc.c中。

解压之前的串口输出


  • include/asm-arm/arch-s3c2410/uncompress.h 中定义了puts作为串口输出函数。
  • 解压结束之后,程序跳转到r5:解压之后内核的起始地址。


开始真正的Linux内核


1、入口在arch/arm/kernel/head-armv.S


2、查找处理器类型


__lookup_processor_type


__lookup_architecture_type


3、初始化页表:__creat_page_tables


4、初始化C代码空间


5、跳转到C代码中,start_kernel


ARM的MMU单元


MMU:内存管理单元


作用:


  • 虚拟地址到物理地址的映射
  • 存储器访问权限
  • 控制Cache


通过MMU的访存


  • MMU会先查找TLB中的虚拟地址表
  • 如果TLB中没有虚拟地址的入口,硬件从主存储器中的转换表中获取转换与访问权限。


ARM的MMU访存原理

20210424223447968.png

ARM的MMU页表格式


MMU支持基于节或者页的存储器访问。


  • 节:1MB的存储器块
  • 大页:64KB的存储器块
  • 小页:4KB的存储器块
  • 微页:1KB的存储器块


页表的级别


存在主存储器内的转换页表有两个级别:


  • 第一级表:存储节转换表与指向第二级表的指针
  • 第二级表:


(1)存储大页和小页的转换表。
(2)存储微页的转换表。


一级页表的地址


第一级表占用空间16KB,必须16KB对齐


20210424223612515.png

第一级描述符


一级表每个入口描述了它所关联的1MB虚拟地址是如何映射的。


20210424223623462.png

节描述符


Bits[1:0] 描述符类型(10b 表示节描述符)

Bits[3:2] 高速缓存(cache)和缓冲位(buffer)

Bits[4] 由具体实现定义

Bits[8:5] 控制的节的16 种域之一

Bits[9] 现在没有使用,应该为零

Bits[11:10] 访问控制(AP)

Bits[19:12] 现在没有使用,应该为零

Bits[31:20] 节基址,形成物理地址的高12 位


节的转换过程



2021042422370656.png

临时内核页表的创建 __create_page_tables


__create_page_tables:
pgtbl r4 @ page table address 0x30008000-0x4000
mov r0, r4 @r0=0x30004000
mov r3, #0
add r2, r0, #0x4000
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r2
bne 1b


把一级页表0x30004000-0xa0080000清空


krnladr r2, r4 @ start of kernel


r4=0xa0004000,r2 = 内核起始地址所在1MB对齐空间,0x30000000


add r3, r8, r2 @ flags + kernel base


r8 为从处理器信息中得到的MMU 页表标志,r8=0xc0e, r3=0x30000c0e


str r3, [r4, r2, lsr #18]@ identity mapping


地址:0x300068000, value:0x30000c0e

add r0, r4, #(TEXTADDR & 0xff000000) >> 18 
@ start of kernel
bic r2, r3, #0x00f00000
str r2, [r0] @ PAGE_OFFSET + 0MB
add r0, r0, #(TEXTADDR & 0x00f00000) >> 18
str r3, [r0], #4 @ KERNEL + 0MB

映射表内容


20210424223805883.png


映射结果


20210424223818218.png


进入C代码


init/main.c中的start_kernel函数,进入到了Linux内核代码中。


  • printk函数
  • 重新初始化页表
  • 初始化中断,trap_init
  • 设置系统定时器、控制台…
  • 创建内核进程init
相关文章
|
4月前
|
安全 网络协议 Linux
深入理解Linux内核模块:加载机制、参数传递与实战开发
本文深入解析了Linux内核模块的加载机制、参数传递方式及实战开发技巧。内容涵盖模块基础概念、加载与卸载流程、生命周期管理、参数配置方法,并通过“Hello World”模块和字符设备驱动实例,带领读者逐步掌握模块开发技能。同时,介绍了调试手段、常见问题排查、开发规范及高级特性,如内核线程、模块间通信与性能优化策略。适合希望深入理解Linux内核机制、提升系统编程能力的技术人员阅读与实践。
471 1
|
4月前
|
Ubuntu Linux
Ubuntu 23.04 用上 Linux 6.2 内核,预计下放到 22.04 LTS 版本
Linux 6.2 带来了多项内容更新,修复了 AMD 锐龙处理器设备在启用 fTPM 后的运行卡顿问题,还增强了文件系统。
|
4月前
|
Ubuntu Linux
Ubuntu 23.10 现在由Linux内核6.3提供支持
如果你想在你的个人电脑上测试一下Ubuntu 23.10的最新开发快照,你可以从官方下载服务器下载最新的每日构建ISO。然而,请记住,这是一个预发布版本,所以不要在生产机器上使用或安装它。
|
4月前
|
传感器 监控 Ubuntu
10 月发布,Ubuntu 23.10 已升级到 Linux Kernel 6.3 内核
硬件方面,Linux 6.3 引入了在 HID 中引入了原生的 Steam Deck 控制器接口,允许罗技 G923 Xbox 版赛车方向盘在 Linux 上运行;改善 8BitDo Pro 2 有线控制器的行为;并为一系列华硕 Ryzen 主板添加传感器监控。
|
4月前
|
Ubuntu Linux
Ubuntu24.04LTS默认采用Linux 6.8内核,实验性版本可通过PPA获得
IT之家提醒,当下的 Ubuntu 23.10 也是一个“短期支持版本”,该版本将在今年 7 月终止支持,而今年 4 月推出的 Ubuntu 24.04 LTS 长期支持版本将获得 5 年的更新支持。
|
4月前
|
监控 Ubuntu Linux
什么Linux,Linux内核及Linux操作系统
上面只是简单的介绍了一下Linux操作系统的几个核心组件,其实Linux的整体架构要复杂的多。单纯从Linux内核的角度,它要管理CPU、内存、网卡、硬盘和输入输出等设备,因此内核本身分为进程调度,内存管理,虚拟文件系统,网络接口等4个核心子系统。
359 0
|
4月前
|
Web App开发 缓存 Rust
|
4月前
|
Ubuntu 安全 Linux
Ubuntu 发行版更新 Linux 内核,修复 17 个安全漏洞
本地攻击者可以利用上述漏洞,攻击 Ubuntu 22.10、Ubuntu 22.04、Ubuntu 20.04 LTS 发行版,导致拒绝服务(系统崩溃)或执行任意代码。
|
4月前
|
Ubuntu 机器人 物联网
Linux Ubuntu 22.04 LTS 测试版实时内核已可申请
请注意,在启用实时内核后您需要手动配置 grub 以恢复到原始内核。更多内容请参考: