Linux ARMv7中断向量表搬移(2)【转】

经历过kernel的汇编阶段,进入C语言start_kernel后对中断向量表的位置进行搬移,搬移函数是early_trap_init。

early_trap_init函数的调用流程为:
start_kernel(init/main.c)—>setup_arch(arch/arm/kernel/setup.c)—>paging_init(arch/arm/mm/mmu.c)—>devicemaps_init(arch/arm/mm/mmu.c)—>early_trap_init(arch/arm/kernel/traps.c)

/** Set up the device mappings. Since we clear out the page tables for all* mappings above VMALLOC_START, except early fixmap, we might remove debug* device mappings. This means earlycon can be used to debug this function* Any other function or debugging method which may touch any device _will_* crash the kernel.*/static void __init devicemaps_init(const struct machine_desc *mdesc){        struct map_desc map;        unsigned long addr;        void *vectors;        /*         * Allocate the vector page early.         *分配两个页的内存空间,arm中每个页的大小为4K,这两个页的内存空间,一个是为保存中断向量         *表,一个是为了保存中断的处理部分代码,这两部分代码的排布可以在         *(arch/arm/kernel/vmlinux.lds和arch/arm/kernel/entry-armv.S)中可以具体分析出来         */        vectors = early_alloc(PAGE_SIZE * 2);        early_trap_init(vectors);         /*          * Clear page table except top pmd used by early fixmaps          */         for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE)                pmd_clear(pmd_off_k(addr));         /*          * Map the kernel if it is XIP.          * It is always first in the modulearea.          */#ifdef CONFIG_XIP_KERNEL  //此宏未定义        map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);        map.virtual = MODULES_VADDR;        map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;        map.type = MT_ROM;        create_mapping(&map);#endif        /*         * Map the cache flushing regions.         */#ifdef FLUSH_BASE  //此宏未定义        map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);        map.virtual = FLUSH_BASE;        map.length = SZ_1M;        map.type = MT_CACHECLEAN;        create_mapping(&map);#endif#ifdef FLUSH_BASE_MINICACHE  //此宏未定义        map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);        map.virtual = FLUSH_BASE_MINICACHE;        map.length = SZ_1M;        map.type = MT_MINICLEAN;        create_mapping(&map);#endif        /*         * Create a mapping for the machine vectors at the high-vectors         * location (0xffff0000). If we aren't using high-vectors, also         * create a mapping at the low-vectors virtual address.         */        /*         *创建一个页的内存地址映射,虚拟地址为0xffff0000,此地址为中断向量表的高端地址         *设置中断向量表的高端地址在汇编的v7_setup中,使用的v7_crval设置了cp15的c1寄存器         *v7_crval定义在arch/arm/mm/proc-v7-2level.S。         */        map.pfn = __phys_to_pfn(virt_to_phys(vectors));        map.virtual = 0xffff0000;        map.length = PAGE_SIZE;#ifdef CONFIG_KUSER_HELPERS  //此宏有定义        map.type = MT_HIGH_VECTORS;#else        map.type = MT_LOW_VECTORS;#endif        create_mapping(&map);        /*         *判断中断向量表的位置是否设置在高端地址,如果中断向量表没有设置在高端地址,         *在映射低端中断向量表地址。         */        if (!vectors_high()) {                map.virtual = 0;                map.length = PAGE_SIZE * 2;                map.type = MT_LOW_VECTORS;            create_mapping(&map);        }        /* Now create a kernel read-only mapping */        map.pfn += 1;        map.virtual = 0xffff0000 + PAGE_SIZE;        map.length = PAGE_SIZE;        map.type = MT_LOW_VECTORS;        create_mapping(&map);        /*         * Ask the machine support to map in the statically mapped devices.         */        if (mdesc->map_io)                mdesc->map_io();        else                debug_ll_io_init();                fill_pmd_gaps();        /* Reserve fixed i/o space in VMALLOC region */        pci_reserve_io();         /*          * Finally flush the caches and tlb to ensure that we're in a          * consistent state wrt the writebuffer. This also ensures that          * any write-allocated cache lines in the vector page are written          * back. After this point, we can start to touch devices again.          */        local_flush_tlb_all();        flush_cache_all();        /* Enable asynchronous aborts */        early_abt_enable();}
        /*   AT         *  TFR   EV X F   I D LR    S         * .EEE ..EE PUI. .T.T 4RVI ZWRS BLDP WCAM         * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced         *   01    0 110       0011 1100 .111 1101 < we want         */        .align  2        .type   v7_crval, #objectv7_crval:        crval   clear=0x2120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c

early_trap_init函数的分析

void __init early_trap_init(void *vectors_base){#ifndef CONFIG_CPU_V7M        unsigned long vectors = (unsigned long)vectors_base;        extern char __stubs_start[], __stubs_end[];        extern char __vectors_start[], __vectors_end[];        unsigned i;        vectors_page = vectors_base;        /*         * Poison the vectors page with an undefined instruction.  This         * rly_trap_init instruction is chosen to be undefined for both ARM and Thumb         * ISAs.  The Thumb version is an undefined instruction with a         * branch back to the undefined instruction.         * 将申请的4K先设置为未定义指令,防止在发生其他中断时,没有处理导致cpu错误         */        for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)                ((u32 *)vectors_base)[i] = 0xe7fddef1;/*         * Copy the vectors, stubs and kuser helpers (in entry-armv.S)         * into the vector page, mapped at 0xffff0000, and ensure these         * are visible to the instruction stream.         */        /*         *将中断向量表和中断处理的代码搬移到申请的两页地址空间内         */        memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);        memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);        kuser_init(vectors_base);        flush_icache_range(vectors, vectors + PAGE_SIZE * 2);#else /* ifndef CONFIG_CPU_V7M */        /*         * on V7-M there is no need to copy the vector table to a dedicated         * memory area. The address is configurable and so a table in the kernel         * image can be used.         */#endif}

Original: https://www.cnblogs.com/yifeichongtian2021/p/15512262.html
Author: 壹飞冲天
Title: Linux ARMv7中断向量表搬移(2)【转】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585777/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 《Redis开发与运维》——(九)哨兵(脑图)

    posted @2021-01-09 15:09 雪山上的蒲公英 阅读(181 ) 评论() 编辑 / 返回顶部代码 / Original: https://www.cnblogs…

    Linux 2023年5月28日
    0107
  • 27. rz与sz上传下载文件

    工作中需要在 Linux 和 Windows 之间传输文件,一般使用xftp等gui工具完成。但是有些第三方linux命令也可以完成上传下载操作 从Linux下载文件到本机 , 在…

    Linux 2023年5月27日
    082
  • 分而治之-快排

    分而治之:把复杂的算法问题按一定的”分解”方法分为等价的规模较小的若干部分,然后逐个解决,分别找出个部分的解,把各部分的解组成整个问题的解。 &#x…

    Linux 2023年6月7日
    098
  • Vmware部署Linux无人值守安装Centos7系统

    Linux – 无人值守安装服务 需求分析 – 使用光盘镜像来安装 Linux 系统的方式; 坦白讲, 该方法适用于只安装少量 Linux 系统的情况, 如果生产环境中…

    Linux 2023年6月13日
    0111
  • Linux 0.11源码阅读笔记-文件IO流程

    文件IO流程 用户进程read、write在高速缓冲块上读写数据,高速缓冲块和块设备交换数据。 何时将磁盘块数据读取到缓冲块? [En] when will the disk bl…

    Linux 2023年5月27日
    084
  • Arrays.binarySearch方法

    Arrays .binarySearch(int[] arr,int b) 1,数组arr必须排序后调用查找b在arr数组中的下标是多少。 2,存在:返回在数组中的下标 不存在:返…

    Linux 2023年6月8日
    072
  • 在Windows下使用CodeBlock使用libiconv第三方库

    在 Windows 下使用 CodeBlock 使用 libiconv 第三方库 1、 选择在Project—>Build options下: 2、 如下图添加libicon…

    Linux 2023年6月6日
    090
  • 操作系统实现-简单热身

    博客网址:www.shicoder.top微信:18223081347欢迎加群聊天 :452380935 这次对上次的boot.asm进行代码讲解,也可以对汇编的相关理论进行补充 …

    Linux 2023年6月13日
    092
  • Lua集成Redis及Nginx

    1 Lua介绍 Lua是一门以其性能著称的脚本语言,被广泛应用在很多方面。Lua一般用于嵌入式应用,现在越来越多应用于游戏 当中,魔兽世界,愤怒的小鸟都有用到。优势 Lua极易嵌入…

    Linux 2023年6月13日
    078
  • Linux用户和用户组

    Linux用户和用户组 1.添加新的用户 (用户ID从500开始,0-99系统管理级别、100-499系统预留) useradd 选项 用户名 参数说明 选项: -c commen…

    Linux 2023年6月11日
    098
  • Postfix发送邮件时报错“libmysqlclient.so.18: cannot open shared object file: No such file or directory”

    在一台Linux服务器上使用postfix发送邮件时遇到上面错误: sendmail.postfix: error while loading shared libraries: …

    Linux 2023年5月27日
    087
  • [ Linux ] 设置开机自动登录

    https://www.cnblogs.com/yeungchie/ 查看桌面环境 file -L /etc/systemd/system/display-manager.serv…

    Linux 2023年6月7日
    0104
  • python的日期处理

    俗话说,工欲善其事必先利其器,所以在使用日期前要先对日期进行处理,所以时间戳和字符串的来回来去转换这个事肯定是要搞的 这次的函数有一个?有两个?有三个?有四个!上代码! 哈哈,像不…

    Linux 2023年6月6日
    085
  • Consider defining a bean of type `xxx` in your configuration问题解决

    在使用SpringBoot装配mybatis时出现了异常 *************************** APPLICATION FAILED TO START *****…

    Linux 2023年6月13日
    0115
  • 3.21 Linux PATH环境变量及作用(初学者必读)

    在讲解 PATH 环境变量之前,首先介绍一下 which 命令,它用于查找某个命令所在的绝对路径。例如: [root@localhost ~]# which rm /bin/rm …

    Linux 2023年6月7日
    087
  • Postman环境变量的使用

    前言 请注意,Postman新版有ui上的改动,本文使用的Postman 版本8.4.0 for Mac, ui有调整,但是功能无改变。 Postman是一款接口调测的软件,服务端…

    Linux 2023年6月14日
    0102
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球