历史上的今天
今天是:2025年01月20日(星期一)
2020年01月20日 | ARMv8 Linux内核head.S源码分析
2020-01-20 来源:eefocus
ARMv8Linux内核head.S主要工作内容:
1、 从el2特权级退回到el1
2、 确认处理器类型
3、 计算内核镜像的起始物理地址及物理地址与虚拟地址之间的偏移
4、 验证设备树的地址是否有效
5、 创建页表,用于启动内核
6、 设置CPU(cpu_setup),用于使能MMU
7、 使能MMU
8、 交换数据段
9、 跳转到start_kernel函数继续运行。
/*
*Low-level CPU initialisation
*Based on arch/arm/kernel/head.S
*
*Copyright (C) 1994-2002 Russell King
*Copyright (C) 2003-2012 ARM Ltd.
*Authors: Catalin Marinas * Will Deacon * *This program is free software; you can redistribute it and/or modify * itunder the terms of the GNU General Public License version 2 as *published by the Free Software Foundation. * *This program is distributed in the hope that it will be useful, *but WITHOUT ANY WARRANTY; without even the implied warranty of *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *GNU General Public License for more details. * *You should have received a copy of the GNU General Public License *along with this program. If not, see */ #include #include #include #include #include #include #include #include #include #include /* *swapper_pg_dir is the virtual address of the initial page table. We place *the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has * 2pages and is placed below swapper_pg_dir. */ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) #if (KERNEL_RAM_VADDR & 0xfffff) !=0x80000 #error KERNEL_RAM_VADDR must start at0xXXX80000 #endif #define SWAPPER_DIR_SIZE (3 * PAGE_SIZE) #define IDMAP_DIR_SIZE (2 * PAGE_SIZE) .globl swapper_pg_dir .equ swapper_pg_dir, KERNEL_RAM_VADDR -SWAPPER_DIR_SIZE .globl idmap_pg_dir .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE .macro pgtbl, ttb0, ttb1, phys add ttb1, phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE sub ttb0, ttb1, #IDMAP_DIR_SIZE .endm #ifdef CONFIG_ARM64_64K_PAGES #define BLOCK_SHIFT PAGE_SHIFT #define BLOCK_SIZE PAGE_SIZE #else #define BLOCK_SHIFT SECTION_SHIFT #define BLOCK_SIZE SECTION_SIZE #endif #define KERNEL_START KERNEL_RAM_VADDR #define KERNEL_END _end /* *Initial memory map attributes. */ #ifndef CONFIG_SMP #define PTE_FLAGS PTE_TYPE_PAGE | PTE_AF #define PMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF #else #define PTE_FLAGS PTE_TYPE_PAGE | PTE_AF | PTE_SHARED #define PMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S #endif #ifdef CONFIG_ARM64_64K_PAGES #define MM_MMUFLAGS PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS #define IO_MMUFLAGS PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_XN | PTE_FLAGS #else #define MM_MMUFLAGS PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS #define IO_MMUFLAGS PMD_ATTRINDX(MT_DEVICE_nGnRE) | PMD_SECT_XN | PMD_FLAGS #endif /* *Kernel startup entry point. *--------------------------- * *The requirements are: * MMU= off, D-cache = off, I-cache = on or off, * x0 =physical address to the FDT blob. * *This code is mostly position independent so you call this at *__pa(PAGE_OFFSET + TEXT_OFFSET). * *Note that the callee-saved registers are used for storing variables *that are useful before the MMU is enabled. The allocations are described * inthe entry routines. */ __HEAD //这是一个宏定义;#define__HEAD .section ".head.text","ax"; .section是伪指令ax代表允许执行 /* * DO NOT MODIFY. Image header expected byLinux boot-loaders. */ b stext //branch to kernel start, magic .long 0 //reserved .quad TEXT_OFFSET // Image load offset from start of RAM .quad 0 //reserved .quad 0 //reserved ENTRY(stext) mov x21, x0 //x21=FDT,x21中保存的是由Uboot传进来的,设备树在内存中的地址。 bl el2_setup //Drop to EL1,从当前特权级跳入EL1,具体函数内容请看下面el2_setup函数。 mrs x22, midr_el1 //x22=cpuid,x22中保存着cpuid,用以判断运行当前这段代码的CPU是哪一个。 mov x0, x22 //x0=cpuid,用于传送参数给函数lookup_processor_type。 bl lookup_processor_type //查看处理器类型,见后面具体定义 mov x23, x0 //x23=current cpu_table 把函数lookup_processor_type返回的cpu_table地址给x23 cbz x23, __error_p // invalid processor (x23=0)? bl __calc_phys_offset //计算起始物理地址,返回的值中x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET bl __vet_fdt //返回后的x21中要么是无效保存0,要么是有效地fdt地址 bl __create_page_tables //为内核创建临时页表 x25=TTBR0,x26=TTBR1,本函数所建立的页表在后面paging_init会销毁重建。 /* * The following calls CPU specific code in aposition independent * manner. See arch/arm64/mm/proc.S fordetails. x23 = base of * cpu_info structure selected bylookup_processor_type above. * On return, the CPU will be ready for the MMUto be turned on and * the TCR will have been set. */ ldr x27, __switch_data //由函数__enable_mmu中调用,此时MMU已经开启 adr lr, __enable_mmu //返回“地址无关”的地址,由函数__cpu_setup返回时调用,该函数中执行brx27调用__switch_data函数 ldr x12, [x23,#CPU_INFO_SETUP] add x12, x12, x28 // __virt_to_phys br x12 //x12中存放的是cpu_info结构体的cpu_setup字段 //该字段在cpu_table中被初始化为__cpu_setup函数,所里这里调用cpu_setup,不在本文件中暂不分析 //该函数返回后会把lr给pc,即直接调用上面的__enable_mmu ENDPROC(stext) /* * If we're fortunate enough to boot at EL2,ensure that the world is * sane before dropping to EL1. */ ENTRY(el2_setup) mrs x0, CurrentEL //获得当前特权级 cmp x0, #PSR_MODE_EL2t //对比当前特权级是否为EL2 ccmp x0,#PSR_MODE_EL2h, #0x4, ne //NZCV= if notequal then CMP(x0,# PSR_MODE_EL2h) else 0x4 b.eq 1f ret
史海拾趣
|
CANopen主节点的设计方案 - 基于IXXAT公司 CANopen Master API for Windows CANopen主节点除具备CANopen设备的基本条件外,还需具备NMT Master的功能,即对CANopen网络进行管理。对CANopen主节点的实现提出三种方案: ?? 方案1:在CANopen-Chip ...… 查看全部问答> |
|
先说说我的: NOKIA 3310 像板砖一样的家伙 呵呵 不过在01年的时候也算稀罕物。 经过多次高空坠落试验,都完好无损, 后来从一个酒瓶高的容器上坠落,液晶屏里的蓝色液体流出,彻底退休了。当时在工资还不高的情况下,流的不是液晶, ...… 查看全部问答> |
|
初次搞485的多机通信(一主多从),现在遇到的问题令我很困惑。 我的通信思路是,从机逐个与主机通信,即主机发送一帧数据(8字节,包含数据信息),呼叫从 ...… 查看全部问答> |
|
我大学里是学软件的,对C#之类的比较熟,C/C++也还行,汇编了解一些,电气电路和硬件几乎一点不懂。 现在有个工作是从事激光仪器里的单片机开发,请问需要学习多少电气知识?线路应该有人设计好的,我写程序要看懂电路吗?有哪里方面是要与设计电 ...… 查看全部问答> |
|
ce5.0 evc4.2. 我要在对话框中加个最小化按钮,用ShowWindow(SW_MINIMIZE)来实现,但对话框最小化就不见了.而在xp系统中就行。 感觉是任务栏没有显示,造成最小化后程序不能回到任务栏,所以不见了。 … 查看全部问答> |
|
一个简短程序放在AT89C55WD中好象不工作了,是否与程序有关? 问题1: 全部程序如下: #include sbit Fscx = P3^4; sbit CW = P3^5; void main() { int i; CW = 0; while(1) { Fscx = 1; ...… 查看全部问答> |
|
CE里默认为64M,IMGRAM128=1设置后对128M支持没有问题,但是设置IMGRAM256=1之后,就不能进入系统了 所以想问一下CE里怎么添加对256M的支持,多谢!… 查看全部问答> |
|
上周周一(6月13号)开始为一块电路板做定位工作,由于自己没有详细考虑PCB设计时的显示位置与实际模具的接口的位置关系,导致周二、三、四的布局布线工作全都白做了,实在是悲惨,只能怪自己前期考虑的不周,这也算是一次学习的机会吧 ...… 查看全部问答> |
|
这套电源管理方案指南中提供了线电源和移动设备电源的全套解决方案,而且设计目前TI最新的产品系列,对于电源方案的制定非常有参考意义。 [ 本帖最后由 wstt 于 2012-6-16 00:43 编辑 ]… 查看全部问答> |
|
今天早上刚到公司打卡看到EEWORLD寄来的快递 估计就是蓝牙板 迫不及待拆开看一下 比想象中小不少 这样可能看不出来 这样就能感觉出mini了吧 简单上个电 看下功耗 2.367mA 应该主要是有源晶振的功耗 晚 ...… 查看全部问答> |




