linux 6.11内核在riscv架构下的启动初期过程详解

本文主要记录Linux内核在riscv架构下启动的过程,内核启动早期要设置cpu模式、初始化页表、开启MMU等,这些操作都要和硬件直接交互。所以这部分代码都在arch目录下。本文探讨的基于Linux内核6.11版本

入口地址确认

既然要探究内核启动的过程第一目标就是要找到内核是从哪里开始运行,所以第一要务就是找到链接脚本。Linux链接脚本都在目标架构的kernel目录下。找到vmlinux.ld.S就可以看见关键的两行代码

OUTPUT_ARCH(riscv)
ENTRY(_start)

查看链接脚本的同时也一定要看一下Linux内核的内存布局。这是一个查看Linux内存布局最好的一种方式。

阅读head.S

早期启动的过程主要都写在了head.S中,涉及页表初始化的过程会写在arch/riscv/mm目录内的init.c中。

_start

打开head.S直接就能看见链接脚本里面定义的入口地址_start符号。Linux通过定义宏SYM_CODE_START和SYM_CODE_END让我们更方便的阅读源码。可以把这两个宏中间的部分看成是一个“”函数“”。_start部分最主要的功能是根据一些编译选项完善头信息。然后通过j _start_kernel跳转到真正的内核启动过程中。

__start_kernel

关闭中断

主要的内核启动过程都在这个里面,SYM_CODE_START(_start_kernel)后面立即就关闭所有类型的中断。保证启动过程不受中断打扰。

	/* Mask all interrupts */
	csrw CSR_IE, zero // 关闭所有中断源
	csrw CSR_IP, zero // 清空所有挂起的中断

重置寄存器和内存保护设置

这部分代码受编译选项CONFIG_RISCV_M_MODE的影响,也就是只有在M模式下启动Linux内核才这部分才生效,代码如下

#ifdef CONFIG_RISCV_M_MODE
	/* flush the instruction cache */
	fence.i

	/* Reset all registers except ra, a0, a1 */
	call reset_regs

	/*
	 * Setup a PMP to permit access to all of memory.  Some machines may
	 * not implement PMPs, so we set up a quick trap handler to just skip
	 * touching the PMPs on any trap.
	 */
	la a0, .L
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值