LK ARM64 start.S处理

2024-02-17 14:08
文章标签 处理 arm64 start lk

本文主要是介绍LK ARM64 start.S处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

arch/arm64/start.S

 

#include <asm.h> #include <arch/arm64/mmu.h> #include <arch/asm_macros.h> #include <kernel/vm.h>

/** Register use:  *  x0-x3   Arguments*  x9-x15  Scratch*  x19-x28 Globals*/

定义一些别名 tmp                     .req x9 tmp2                    .req x10 wtmp2                   .req w10 index                   .req x11 index_shift             .req x12 page_table              .req x13 new_page_table          .req x14 phys_offset             .req x15

cpuid                   .req x19 page_table0             .req x20 page_table1             .req x21 mmu_initial_mapping     .req x22 vaddr                   .req x23 paddr                   .req x24 mapping_size            .req x25 size                    .req x26 attr                    .req x27

.section .text.boot FUNCTION(_start) .globl arm_reset arm_reset:bl      arm64_elX_to_el1

#if WITH_KERNEL_VM/* enable caches so atomics and spinlocks work */mrs     tmp, sctlr_el1orr     tmp, tmp, #(1<<12) /* Enable icache */orr     tmp, tmp, #(1<<2)  /* Enable dcache/ucache */orr     tmp, tmp, #(1<<3)  /* Enable Stack Alignment Check EL1 */orr     tmp, tmp, #(1<<4)  /* Enable Stack Alignment Check EL0 */bic     tmp, tmp, #(1<<1)  /* Disable Alignment Checking for EL1 EL0 */msr     sctlr_el1, tmp

    /* set up the mmu according to mmu_initial_mappings */

    /* load the base of the translation table and clear the table */adrp    page_table1, arm64_kernel_translation_tableadd     page_table1, page_table1, #:lo12:arm64_kernel_translation_table

    /* Prepare tt_trampoline page table *//* Calculate pagetable physical addresses */adrp    page_table0, tt_trampolineadd     page_table0, page_table0, #:lo12:tt_trampoline

#if WITH_SMPmrs     cpuid, mpidr_el1ubfx    cpuid, cpuid, #0, #SMP_CPU_ID_BITScbnz    cpuid, .Lmmu_enable_secondary #endif

    mov     tmp, #0

    /* walk through all the entries in the translation table, setting them up */ .Lclear_top_page_table_loop:str     xzr, [page_table1, tmp, lsl #3]add     tmp, tmp, #1cmp     tmp, #MMU_KERNEL_PAGE_TABLE_ENTRIES_TOPbne     .Lclear_top_page_table_loop

    /* load the address of the mmu_initial_mappings table and start processing */adrp    mmu_initial_mapping, mmu_initial_mappingsadd     mmu_initial_mapping, mmu_initial_mapping, #:lo12:mmu_initial_mappings

.Linitial_mapping_loop: /* Read entry of mmu_initial_mappings (likely defined in platform.c) */ldp     paddr, vaddr, [mmu_initial_mapping, #__MMU_INITIAL_MAPPING_PHYS_OFFSET]ldp     size, tmp, [mmu_initial_mapping, #__MMU_INITIAL_MAPPING_SIZE_OFFSET]

    tbzmask tmp, MMU_INITIAL_MAPPING_FLAG_DYNAMIC, .Lnot_dynamicadr     paddr, _startmov     size, x0str     paddr, [mmu_initial_mapping, #__MMU_INITIAL_MAPPING_PHYS_OFFSET]str     size, [mmu_initial_mapping, #__MMU_INITIAL_MAPPING_SIZE_OFFSET]

.Lnot_dynamic:/* if size == 0, end of list, done with initial mapping */cbz     size, .Linitial_mapping_donemov     mapping_size, size

    /* set up the flags */tbzmask tmp, MMU_INITIAL_MAPPING_FLAG_UNCACHED, .Lnot_uncachedldr     attr, =MMU_INITIAL_MAP_STRONGLY_ORDEREDb       .Lmem_type_done

.Lnot_uncached:/* is this memory mapped to device/peripherals? */tbzmask tmp, MMU_INITIAL_MAPPING_FLAG_DEVICE, .Lnot_deviceldr     attr, =MMU_INITIAL_MAP_DEVICEb       .Lmem_type_done .Lnot_device:

/* Determine the segment in which the memory resides and set appropriate*  attributes.  In order to handle offset kernels, the following rules are*  implemented below:*      KERNEL_BASE    to __code_start             -read/write (see note below)*      __code_start   to __rodata_start (.text)   -read only*      __rodata_start to __data_start   (.rodata) -read only, execute never*      __data_start   to .....          (.data)   -read/write**  The space below __code_start is presently left as read/write (same as .data)*   mainly as a workaround for the raspberry pi boot process.  Boot vectors for*   secondary CPUs are in this area and need to be updated by cpu0 once the system*   is ready to boot the secondary processors.*   TODO: handle this via mmu_initial_mapping entries, which may need to be*         extended with additional flag types*/ .Lmapping_size_loop:ldr     attr, =MMU_PTE_KERNEL_DATA_FLAGSldr     tmp, =__code_startsubs    size, tmp, vaddr/* If page is below  the entry point (_start) mark as kernel data */b.hi    .Lmem_type_done

    ldr     attr, =MMU_PTE_KERNEL_RO_FLAGSldr     tmp, =__rodata_startsubs    size, tmp, vaddrb.hi    .Lmem_type_doneorr     attr, attr, #MMU_PTE_ATTR_PXNldr     tmp, =__data_startsubs    size, tmp, vaddrb.hi    .Lmem_type_doneldr     attr, =MMU_PTE_KERNEL_DATA_FLAGSldr     tmp, =_endsubs    size, tmp, vaddrb.lo    . /* Error: _end < vaddr */cmp     mapping_size, sizeb.lo    . /* Error: mapping_size < size => RAM size too small for data/bss */mov     size, mapping_size

.Lmem_type_done:subs    mapping_size, mapping_size, sizeb.lo    . /* Error: mapping_size < size (RAM size too small for code/rodata?) */

    /* Check that paddr, vaddr and size are page aligned */orr     tmp, vaddr, paddrorr     tmp, tmp, sizetst     tmp, #(1 << MMU_KERNEL_PAGE_SIZE_SHIFT) - 1bne     . /* Error: not page aligned */

    /* Clear top bits of virtual address (should be all set) */eor     vaddr, vaddr, #(~0 << MMU_KERNEL_SIZE_SHIFT)

    /* Check that top bits were all set */tst     vaddr, #(~0 << MMU_KERNEL_SIZE_SHIFT)bne     . /* Error: vaddr out of range */

.Lmap_range_top_loop:/* Select top level page table */mov     page_table, page_table1mov     index_shift, #MMU_KERNEL_TOP_SHIFT

    lsr     index, vaddr, index_shift

/* determine the type of page table entry to use given alignment and size*  of the chunk of memory we are mapping*/ .Lmap_range_one_table_loop:/* Check if current level allow block descriptors */cmp     index_shift, #MMU_PTE_DESCRIPTOR_BLOCK_MAX_SHIFTb.hi    .Lmap_range_need_page_table

    /* Check if paddr and vaddr alignment allows a block descriptor */orr     tmp2, vaddr, paddrlsr     tmp, tmp2, index_shiftlsl     tmp, tmp, index_shiftcmp     tmp, tmp2b.ne    .Lmap_range_need_page_table

    /* Check if size is large enough for a block mapping */lsr     tmp, size, index_shiftcbz     tmp, .Lmap_range_need_page_table

    /* Select descriptor type, page for level 3, block for level 0-2 */orr     tmp, attr, #MMU_PTE_L3_DESCRIPTOR_PAGEcmp     index_shift, MMU_KERNEL_PAGE_SIZE_SHIFTbeq     .Lmap_range_l3orr     tmp, attr, #MMU_PTE_L012_DESCRIPTOR_BLOCK .Lmap_range_l3:

    /* Write page table entry */orr     tmp, tmp, paddrstr     tmp, [page_table, index, lsl #3]

    /* Move to next page table entry */mov     tmp, #1lsl     tmp, tmp, index_shiftadd     vaddr, vaddr, tmpadd     paddr, paddr, tmpsubs    size, size, tmp/* TODO: add local loop if next entry is in the same page table */b.ne    .Lmap_range_top_loop /* size != 0 */

    /* Restore top bits of virtual address (should be all set) */eor     vaddr, vaddr, #(~0 << MMU_KERNEL_SIZE_SHIFT)/* Move to next subtype of ram mmu_initial_mappings entry */cbnz     mapping_size, .Lmapping_size_loop

    /* Move to next mmu_initial_mappings entry */add     mmu_initial_mapping, mmu_initial_mapping, __MMU_INITIAL_MAPPING_SIZEb       .Linitial_mapping_loop

.Lmap_range_need_page_table:/* Check if page table entry is unused */ldr     new_page_table, [page_table, index, lsl #3]cbnz    new_page_table, .Lmap_range_has_page_table

    /* Calculate phys offset (needed for memory allocation) */ .Lphys_offset:adr     phys_offset, .Lphys_offset /* phys */ldr     tmp, =.Lphys_offset /* virt */sub     phys_offset, tmp, phys_offset

    /* Allocate new page table */calloc_bootmem_aligned new_page_table, tmp, tmp2, MMU_KERNEL_PAGE_SIZE_SHIFT, phys_offset

    /* Write page table entry (with allocated page table) */orr     new_page_table, new_page_table, #MMU_PTE_L012_DESCRIPTOR_TABLEstr     new_page_table, [page_table, index, lsl #3]

.Lmap_range_has_page_table:/* Check descriptor type */and     tmp, new_page_table, #MMU_PTE_DESCRIPTOR_MASKcmp     tmp, #MMU_PTE_L012_DESCRIPTOR_TABLEb.ne    . /* Error: entry already in use (as a block entry) */

    /* switch to next page table level */bic     page_table, new_page_table, #MMU_PTE_DESCRIPTOR_MASKmov     tmp, #~0lsl     tmp, tmp, index_shiftbic     tmp, vaddr, tmpsub     index_shift, index_shift, #(MMU_KERNEL_PAGE_SIZE_SHIFT - 3)lsr     index, tmp, index_shift

    b       .Lmap_range_one_table_loop

.Linitial_mapping_done:

    /* Prepare tt_trampoline page table */

    /* Zero tt_trampoline translation tables */mov     tmp, #0 .Lclear_tt_trampoline:str     xzr, [page_table0, tmp, lsl#3]add     tmp, tmp, #1cmp     tmp, #MMU_PAGE_TABLE_ENTRIES_IDENTblt     .Lclear_tt_trampoline

    /* Setup mapping at phys -> phys */adr     tmp, .Lmmu_on_pclsr     tmp, tmp, #MMU_IDENT_TOP_SHIFT    /* tmp = paddr index */ldr     tmp2, =MMU_PTE_IDENT_FLAGSadd     tmp2, tmp2, tmp, lsl #MMU_IDENT_TOP_SHIFT  /* tmp2 = pt entry */

    str     tmp2, [page_table0, tmp, lsl #3]     /* tt_trampoline[paddr index] = pt entry */

#if WITH_SMPadrp    tmp, page_tables_not_readyadd     tmp, tmp, #:lo12:page_tables_not_readystr     wzr, [tmp]b       .Lpage_tables_ready

.Lmmu_enable_secondary:adrp    tmp, page_tables_not_readyadd     tmp, tmp, #:lo12:page_tables_not_ready .Lpage_tables_not_ready:ldr     wtmp2, [tmp]cbnz    wtmp2, .Lpage_tables_not_ready .Lpage_tables_ready: #endif

    /* set up the mmu */

    /* Invalidate TLB */tlbi    vmalle1isisbdsb     sy

    /* Initialize Memory Attribute Indirection Register */ldr     tmp, =MMU_MAIR_VALmsr     mair_el1, tmp

    /* Initialize TCR_EL1 *//* set cacheable attributes on translation walk *//* (SMP extensions) non-shareable, inner write-back write-allocate */ldr     tmp, =MMU_TCR_FLAGS_IDENTmsr     tcr_el1, tmp

    isb

    /* Write ttbr with phys addr of the translation table */msr     ttbr0_el1, page_table0msr     ttbr1_el1, page_table1isb

    /* Read SCTLR */mrs     tmp, sctlr_el1

    /* Turn on the MMU */orr     tmp, tmp, #0x1

    /* Write back SCTLR */msr     sctlr_el1, tmp .Lmmu_on_pc:isb

    /* Jump to virtual code address */ldr     tmp, =.Lmmu_on_vaddrbr      tmp

.Lmmu_on_vaddr:

    /* Disable trampoline page-table in ttbr0 */ldr     tmp, =MMU_TCR_FLAGS_KERNELmsr     tcr_el1, tmpisb

/* Invalidate TLB */tlbi    vmalle1isb

#if WITH_SMPcbnz    cpuid, .Lsecondary_boot #endif #endif /* WITH_KERNEL_VM */

    ldr tmp, =__stack_endmov sp, tmp

    /* clear bss */ .L__do_bss:/* clear out the bss excluding the stack and kernel translation table  *//* NOTE: relies on __post_prebss_bss_start and __bss_end being 8 byte aligned */ldr     tmp, =__post_prebss_bss_startldr     tmp2, =__bss_endsub     tmp2, tmp2, tmpcbz     tmp2, .L__bss_loop_done .L__bss_loop:sub     tmp2, tmp2, #8str     xzr, [tmp], #8cbnz    tmp2, .L__bss_loop .L__bss_loop_done:

    bl  lk_mainb   .

#if WITH_SMP .Lsecondary_boot:and     tmp, cpuid, #0xffcmp     tmp, #(1 << SMP_CPU_CLUSTER_SHIFT)bge     .Lunsupported_cpu_trapbic     cpuid, cpuid, #0xfforr     cpuid, tmp, cpuid, LSR #(8 - SMP_CPU_CLUSTER_SHIFT)

    cmp     cpuid, #SMP_MAX_CPUSbge     .Lunsupported_cpu_trap

    /* Set up the stack */ldr     tmp, =__stack_endmov     tmp2, #ARCH_DEFAULT_STACK_SIZEmul     tmp2, tmp2, cpuidsub     sp, tmp, tmp2

    mov     x0, cpuidbl      arm64_secondary_entry

.Lunsupported_cpu_trap:wfeb       .Lunsupported_cpu_trap #endif

.ltorg

#if WITH_SMP .data DATA(page_tables_not_ready).long       1 #endif

.section .bss.prebss.stack.align 4 DATA(__stack).skip ARCH_DEFAULT_STACK_SIZE * SMP_MAX_CPUS DATA(__stack_end)

#if WITH_KERNEL_VM .section ".bss.prebss.translation_table" .align 3 + MMU_PAGE_TABLE_ENTRIES_IDENT_SHIFT DATA(tt_trampoline).skip 8 * MMU_PAGE_TABLE_ENTRIES_IDENT #endif

 

这篇关于LK ARM64 start.S处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/718011

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

GNSS CTS GNSS Start and Location Flow of Android15

目录 1. 本文概述2.CTS 测试3.Gnss Flow3.1 Gnss Start Flow3.2 Gnss Location Output Flow 1. 本文概述 本来是为了做Android 14 Gnss CTS 的相关环境的搭建和测试,然后在测试中遇到了一些问题,去寻找CTS源码(/cts/tests/tests/location/src/android/locat

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

Oracle Start With关键字

Oracle Start With关键字 前言 旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人. Start With (树查询) 问题描述: 在数据库中, 有一种比较常见得 设计模式, 层级结构 设计模式, 具体到 Oracle table中, 字段特点如下: ID, DSC, PID; 三个字段, 分别表示 当前标识的 ID(主键), DSC 当

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

明明的随机数处理问题分析与解决方案

明明的随机数处理问题分析与解决方案 引言问题描述解决方案数据结构设计具体步骤伪代码C语言实现详细解释读取输入去重操作排序操作输出结果复杂度分析 引言 明明生成了N个1到500之间的随机整数,我们需要对这些整数进行处理,删去重复的数字,然后进行排序并输出结果。本文将详细讲解如何通过算法、数据结构以及C语言来解决这个问题。我们将会使用数组和哈希表来实现去重操作,再利用排序算法对结果

8. 自然语言处理中的深度学习:从词向量到BERT

引言 深度学习在自然语言处理(NLP)领域的应用极大地推动了语言理解和生成技术的发展。通过从词向量到预训练模型(如BERT)的演进,NLP技术在机器翻译、情感分析、问答系统等任务中取得了显著成果。本篇博文将探讨深度学习在NLP中的核心技术,包括词向量、序列模型(如RNN、LSTM),以及BERT等预训练模型的崛起及其实际应用。 1. 词向量的生成与应用 词向量(Word Embedding)

使用协程实现高并发的I/O处理

文章目录 1. 协程简介1.1 什么是协程?1.2 协程的特点1.3 Python 中的协程 2. 协程的基本概念2.1 事件循环2.2 协程函数2.3 Future 对象 3. 使用协程实现高并发的 I/O 处理3.1 网络请求3.2 文件读写 4. 实际应用场景4.1 网络爬虫4.2 文件处理 5. 性能分析5.1 上下文切换开销5.2 I/O 等待时间 6. 最佳实践6.1 使用 as