OK6410A 开发板 (八) 100 linux-5.11 OK6410A 内核空间虚拟内存布局

发布者:Dingsir1902最新更新时间:2022-08-15 来源: csdn关键字:OK6410A  开发板  11  内核空间 手机看文章 扫描二维码
随时随地手机看文章

物理内存

物理内存或大或小,(256M或512M或1G或2G或4G) , 这里取 PHY_MAX


在这里 https://blog.csdn.net/u011011827/article/details/117413163 中的 "arm32 要不要配置 CONFIG_HIGHMEM" 讲述了

arm物理内存的不同 情况下 需要的配置


我们如果要配置 高端内存(虚拟内存概念) 

// 但是一个zone 中有成员 zone_start_pfn , 这是 物理地址的概念,表示了一个zone的开始

// 所以 高端内存 属于 zone ,而 zone 又是  与 物理地址有关,所以感觉,这个 高端内存 像是 物理内存概念 

则 我们会考虑 在 物理内存中 选择一个地址PHY_LINE(分界线)

往上 , 我们采取 一组   映射策略

往下 , 我们采取 另一组 映射策略


内核空间

内核空间 是 虚拟内存概念, 一般是指 3G-4G 区域

我们可以通过 https://blog.csdn.net/u011011827/article/details/117413163  中的 "内核空间与用户空间的比例" 来更改

内核空间所在的位置

以下,我们以  3G-4G 为例


内核空间 的 地址(虚拟地址) 范围 为  3G-4G , 这个地址空间要映射 所有的物理内存 (256M或512M或1G或2G或4G)


我们将 内核空间的地址分类

低端内存

3G - 3G+某个值(VIR_LINE)

高端内存

3G+某个值 - 4G


这个值   可以 通过  https://blog.csdn.net/u011011827/article/details/117413163 中的 "arm32 怎么调整 低端内存 和高端内存大小" 调整



我们的映射关系如下

低端虚拟内存空间(3G - 3G+VIR_LINE) - 物理地址空间(0G - PHY_LINE) // 线性映射关系

高端虚拟内存空间(3G+VIR_LINE - 4G) - 物理地址空间(PHY_LINE - PHY_MAX) // 非线性映射关系


内核空间的映射关系

我们知道 虚拟地址空间 3G-4G 要映射到 物理地址 (0-PHY_MAX),其中分为

A:低端虚拟内存空间(3G - 3G+VIR_LINE) - 物理地址空间(0G - PHY_LINE)

B:高端虚拟内存空间(3G+VIR_LINE - 4G) - 物理地址空间(PHY_LINE - PHY_MAX)


A 中的映射关系

是 线性关系, 只需要线性映射即可

PHY_ADDR = VIR_ADDR - 0xC000 0000 + OFFSET // OFFSET  一般为 内存在memory map中的首地址

只需要一类函数即可转换

B 中的映射关系,又分为三大类,五小类

vmalloc : 0xef80 0000 - 

fixmap  : 

永久 :

临时 : 

kmap :

kmap :

kmap_atomic : 


描述在 https://blog.csdn.net/u011011827/article/details/117335579 中的 虚拟内存管理机制的区别


典型内存分区

Memory: 1031428K/1048576K available (4787K kernel code, 156K rwdata, 1364K rodata, 1348K init, 166K bss, 17148K reserved, 0K cma-reserved, 270336K highmem)

Virtual kernel memory layout:

    vector  : 0xffff0000 - 0xffff1000   (   4 kB)

    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)

    vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)

    lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)

    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)

    modules : 0xbf000000 - 0xbfe00000   (  14 MB)

      .text : 0xc0008000 - 0xc060a09c   (6153 kB)

      .init : 0xc060b000 - 0xc075c000   (1348 kB)

      .data : 0xc075c000 - 0xc07833c0   ( 157 kB)

       .bss : 0xc07833c0 - 0xc07acbf0   ( 167 kB)


分区描述

1. vector  : 0xffff0000 - 0xffff1000   (   4 kB)

   异常向量表

   The CPU vectors are mapped here if the CPU supports vector relocation (control register V bit.)

2. fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)

   三小类 虚拟内存管理机制 "fixmap 临时" "fixmap 永久" "kmap_atomic" 管理的虚拟内存区

3. vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)

   一小类 虚拟内存管理机制 "vmalloc" 管理的虚拟内存区

4. lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)

   一小类 虚拟内存管理机制 "线性映射管理机制" 管理的虚拟内存区

5. pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)

   一小类 虚拟内存管理机制 "kmap" 管理的虚拟内存区

6. modules : 0xbf000000 - 0xbfe00000   (  14 MB)

   TODO

   Kernel module space Kernel modules inserted via insmod are placed here using dynamic mappings.

8. 以下是 kernel(vmlinux) 在 内存中 的 分区 

      .text : 0xc0008000 - 0xc060a09c   (6153 kB)

      .init : 0xc060b000 - 0xc075c000   (1348 kB)

      .data : 0xc075c000 - 0xc07833c0   ( 157 kB)

       .bss : 0xc07833c0 - 0xc07acbf0   ( 167 kB)


linux官方定义的 ARM32 4G虚拟内存空间的布局

在 linux代码中 Documentation/arm/memory.rst 有写其布局


以前我总认为

用户空间 为 0x0000 0000 - 0xBFFF FFFF 

内核空间 为 0xC000 0000 - 0xFFFF FFFF

现在看了手册才知道,布局可能是这样子的


这些空间唯一的不同是 用户不同, 而 用户 分为两类

1. 特权级用户

2. 非特权级用户


0000 0000            - 0000 0fff :CPU vector page 或 null pointer trap

0000 1000                       - TASK_SIZE(bf00 0000)-1    :用户空间

bf00 0000                 - MODULES_VADDR(bfe0 0000)-1  :modules空间

PKMAP_BASE(bfe0 0000)     - PAGE_OFFSET(c000 0000)-1  :kmap空间

PAGE_OFFSET(c000 0000)                - high_memory-1  :lowmem 线性映射空间

high_memory                  - high_memory+800000-1 :8MB空洞,用于捕获

VMALLOC_START(high_memory+800000)      - VMALLOC_END(ff80 0000)-1 :vmalloc空间

ff80 0000 - ffbf ffff :fixmap空间

fffe 0000 - fffe 7fff :itcm空间

fffe 8000 - fffe ffff :dtcm空间

ffff 0000 - ffff 0fff  :CPU vector page

ffff 1000    - ffff 7fff :Reserved

ffff 8000    - ffff ffff    :copy_user_page / clear_user_page use


内核空间虚拟内存布局和进程内核态的关系


进程一旦陷入内核态,PC就跳转到了 3G-4G空间

1.

并随着函数的调用开始填充栈,填充的栈是局部变量 // 参考 https://blog.csdn.net/u011011827/article/details/122303983

// 地址在 thread_info 中 , thread_info 在 内核空间 哪个区? // TODO

2.

函数的执行还有指令的运行,如果这些指令又申请了空间,

// 地址根据不同的申请函数的不同(kmalloc vmalloc alloc_pages),而不同,具体在哪个区?//TODO

关键字:OK6410A  开发板  11  内核空间 引用地址:OK6410A 开发板 (八) 100 linux-5.11 OK6410A 内核空间虚拟内存布局

上一篇:OK6410A 开发板 (八) 101 linux-5.11 OK6410A printf 在 glibc 和 linux 中的流程
下一篇:OK6410A 开发板 (八) 99 linux-5.11 OK6410A 文件访问实例mmap与read的比较

推荐阅读最新更新时间:2024-10-19 01:58

OK6410A 开发板 (八) 100 linux-5.11 OK6410A 内核空间虚拟内存布局
物理内存 物理内存或大或小,(256M或512M或1G或2G或4G) , 这里取 PHY_MAX 在这里 https://blog.csdn.net/u011011827/article/details/117413163 中的 arm32 要不要配置 CONFIG_HIGHMEM 讲述了 arm物理内存的不同 情况下 需要的配置 我们如果要配置 高端内存(虚拟内存概念) // 但是一个zone 中有成员 zone_start_pfn , 这是 物理地址的概念,表示了一个zone的开始 // 所以 高端内存 属于 zone ,而 zone 又是 与 物理地址有关,所以感觉,这个 高端内存 像是 物理内存概念
[单片机]
OK6410A 开发板 (八) 116 linux-5.11 OK6410A 用户空间虚拟内存布局
不同架构的 用户空间虚拟内存布局 不同, 以 arm 为例 用户空间实际从0x10 000开始,从低到高有代码段,数据段,堆,栈 用户空间范围为1000 -beff ffff vdso stack sigpage heap-mmap-ld libc heap-brk 数据段 代码段 vdso 为了提供系统调用 ,x86提供了3类指令int/sysenter/syscall 其中 sysenter和syscall相对于int来说,快一点 而不管怎么快,都要从用户态切换到内核态 新机制出现了,vsyscall vsyscall主要是 1.对特定的系统调用使用函数调用代替,即对一些系统调用进行加速 2.vsy
[单片机]
OK6410A 开发板 (八) 49 linux-5.11 OK6410A linux用户空间虚拟内存的管理 VMA
之前介绍过了 linux 虚拟内存管理方式 有5种,其中一种(名为VMA)用于 用户空间虚拟内存的管理,本篇就介绍 VMA VMA 是什么 task_struct 中的 mm_struct 中的 mmap(VMA) // mmap 的结构体类型 为 vm_area_struct 可以看出来 , VMA是一种数据结构,结构体类型为vm_area_struct,那么对应的就有算法 VMA 相关的数据结构 与 算法的集合 就是我们这篇要讨论的内容 用户空间 可访问的区域 是 0G-3G 当然不是 0-3G内的所有地址都可访问 , 可访问的地址空间 被称为 进程地址空间 只有做了内存申请的区域才可以被访问 做一次内存申请 ,
[单片机]
OK6410A 开发板 (八) 63 linux-5.11 OK6410A linux内核空间常见的异常情景及分析 kernel exception
异常情景的level1 异常情景的level1 是最底层 show 当前状况的 api 其他具体的异常情景会根据 自身情景 调用 这些api oops 打印 Unable to ... 到 --- 3. oom Out of memory意味着已无可用的memory,这样的问题必然存在一些耗费资源的进程耗尽了memory的资源触发的KE Kernel panic - not syncing: Out of memory and no killable processes... 4. 未定义指令异常 一般是CPU/DRAM不稳定导致的问题 Internal error: Oops - unde
[单片机]
OK6410A 开发板 (八) 121 linux-5.11 OK6410A 以linux用户角度去应用内核空间内存
以用户角度去应用内核空间内存 // https://blog.csdn.net/u011011827/article/details/117335579 level 1 api level1 phy mem api : get_page_from_freelist add_to_free_list level1 virt mem api : 1.线性映射/直接映射区 page_to_virt page_address 2.vmalloc 动态映射区 __alloc_vmap_area 3.持久映射区 kmap map_new_virtual 4.临时映射区 fixma
[单片机]
OK6410A 开发板 (八) 62 linux-5.11 OK6410A linux应用空间常见的异常情景及分析
应用程序运行的时候,是感觉不到其他进程的 应用程序运行的时候,有三种情况 1. 用户空间执行指令 2. 发生异常陷入内核 6种异常 // 不包括reset异常 , reset 异常发生后就回不来了 3. 退出 正常退出 1.在main函数中使用了return返回 // return之后把控制权交给调用函数 2.调用exit()或者_exit // exit()之后把控制权交给系统 异常退出 1.调用abort函数 会产生 SIGABRT 信号 2.进程收到某个信号,而该信号是程序中止 SIGINT SIGFPE SIGSEGV SIGPIPE
[单片机]
OK6410A 开发板 (八) 122 linux-5.11 OK6410A 以linux用户角度去应用用户空间内存
以linux用户角度去应用用户空间内存 // 在 用户空间是以 段的形式管理的 在内核空间是通过 VMA 来管理这些段的 // https://blog.csdn.net/u011011827/article/details/117335579 中的 VMA 代码段内存 通过增加代码长度 通过汇编指定一个段为代码段(虽然里面可能是数据) 数据段内存 全局变量 // __attribute__((section( .ARM.__at_address ))) , 这个东西要该默认的连接脚本?//TODO 栈内存 局部变量 堆内存 level1 api: syscall
[单片机]
OK6410A 开发板 (八) 29 linux-5.11 OK6410A 主要内核线程解析
kthreadd这篇博客简述了 一下 系统内创建的 所有内核线程 // 进程 1 2 的 父进程为 0 // 其他所有内核线程(被 包括的) 父进程都是 kthreadd 进程ID 所属用户 状态 COMMAND进程名 进程创建文件 进程创建函数 // 1号用户进程 1 root 1412 S {linuxrc} init //init/main.c kernel_thread // 1号用户进程 // 2号内核进程 2 root 0 SW // init/main.c kernel_thread // 2号内核线程,负责 创建所有的内核线程 //
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved