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)

大家都在看

  • 前端之jQuery快速入门

    一、jQuery 一款轻量级的JS框架。jQuery的核心JS文件才几十kb,不会影响页面加载速度。 丰富的DOM选择器,jQuery的选择器用起来很方便,比如要找到某个DOM对象…

    Linux 2023年6月14日
    081
  • redis在php中的基本使用

    //使用autoload加载相关库,这边重点就是为了require $file; spl_autoload_register(function($class) { $file = …

    Linux 2023年5月28日
    085
  • 用 shell 脚本做 tcp 协议模拟

    问题背景 公司有一套消息推送系统(简称GCM),由于人事变动接手了其中的客户端部分。看了一下文档,仅通讯协议部分有几页简单的说明,代码呢又多又乱,一时理不出一个头绪。由于消息是从后…

    Linux 2023年6月6日
    0135
  • JQ 实现对比两个文本的差异并高亮显示差异部分

    利用jq对比两段文本的差异,差异的内容用不同颜色表示出来。 在线参考demo:http://incaseofstairs.com/jsdiff/ 项目地址:https://gith…

    Linux 2023年6月7日
    0101
  • list底层实现

    list和vector都是容器,只不过他们的存储结构不同,vector实际底层结构是顺序表,支持随机访问。list的底层结构带头双向链表,不支持随机访问。 但list的底层实现不同…

    Linux 2023年6月13日
    096
  • 数据库的灾备

    数据是企业重要的生产资料,关键数据的丢失可能会给企业致命一击,因为数据是计算机系统存在的原因和基础。数据往往是不可再生的,一旦发生数据丢失,企业就会陷入困境:客户资料、技术文件、财…

    Linux 2023年6月6日
    093
  • MySQL提权 通过UDF

    UDF是什么 命令执行 文本写入 Example: 远程写入 反弹Shell 提权 UDF是什么 参考:https://www.cnblogs.com/litlife/p/9030…

    Linux 2023年6月6日
    085
  • linux下启动MongoDB权限不够

    bash: ./mongod: 权限不够 解决办法: 在MongoDB安装目录下: chmod -R 740 bin Original: https://www.cnblogs.c…

    Linux 2023年6月14日
    079
  • 计算机硬件的读写速度差异

    现代计算机系统 存储器 寄存器 CPU时钟周期 高速缓存 主存 固态硬盘 机械硬盘 压榨CPU性能带来的问题 有序性问题 可见性问题 原子性问题 作者:小牛呼噜噜 | https:…

    Linux 2023年6月6日
    0119
  • Centos 7 升级内核

    【背景说明】 在公司进行部署产品时,发公司内部的服务内核资源并不能满足于产品部署条件,于是我和内核就进行了一场风花雪月般的交互,在操作前,本人小白一枚,就在浩瀚的互联网海洋中搜索升…

    Linux 2023年5月27日
    091
  • NoteOfMySQL-11-权限管理

    一、权限系统 MySQL数据库中使用3种不同类型的安全检查:登录验证、授权、访问控制。 二、权限表 MySQL权限表存储在名为mysql的数据库中,常用的表有user、db、tab…

    Linux 2023年6月14日
    071
  • [20220811]奇怪的隐式转换问题(12c补充测试).txt

    [20220811]奇怪的隐式转换问题(12c补充测试).txt –//生产系统遇到一个奇怪的隐式转换问题,问题在于没有发生隐式转换,前面已经做了一些分析增加12c下的…

    Linux 2023年6月13日
    072
  • MySQL 知识点总结(简易版)

    MySQL 总结(简易版) 基本语法 0. 1基本语法 &#x767B;&#x5F55;MySQL $ mysql -u root -p12345612 &…

    Linux 2023年6月7日
    096
  • Java中QueryWrapper的基本使用

    1.单表查询 对应的sql语句为: select * from student where name = ‘?’ and class like ‘%?%’ and age betw…

    Linux 2023年6月7日
    093
  • Docker学习笔记

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 Docker概述 Docker学习链接 官网链接:Home – Docker Docker与虚拟机比较 虚拟化技术 …

    Linux 2023年5月27日
    081
  • 基于redis分布式锁实现“秒杀”

    转载:http://blog.5ibc.net/p/28883.html 最近在项目中遇到了类似”秒杀”的业务场景,在本篇博客中,我将用一个非常简单的dem…

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