ARM Linux (S3C6410架构/2.6.35内核)的内存映射(二)

发布者:CMOS最新更新时间:2016-06-22 来源: eefocus关键字:ARM  Linux  S3C6410架构  2.6.35内核  内存映射 手机看文章 扫描二维码
随时随地手机看文章
本文讲述Linux系统启动过程中内核空间的映射。

Linux系统内核启动过程中,会在start_kernel() -> setup_arch() -> paging_init()函数中建立页表,下面详细记录一下其中每一个重要的步骤。(下面演示的代码经过删减)

先看函数prepare_page_table()

   [c]
static inline void prepare_page_table(void)
{
 unsigned long addr;
 for (addr = 0; addr < MODULES_VADDR; addr  = PGDIR_SIZE) {
 pmd_clear(pmd_off_k(addr));
 }

for ( ; addr < PAGE_OFFSET; addr  = PGDIR_SIZE) {
 pmd_clear(pmd_off_k(addr));
 }

for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0]));
 addr < VMALLOC_END; addr  = PGDIR_SIZE) {
 pmd_clear(pmd_off_k(addr));
 }
}
[/c] 

函数prepare_page_table()的作用是清空内核页表。对于我的配置来说,前两个for循环可以合并为一个,它们的作用是清空地址区间[0x00000000, 0xC0000000)的内存映射;第三个for循环有些不一样,它所清空的区间与前面是不连续的,它从bank0的末尾开始,直到VMALLOC结束。为什么要把bank0让出来呢?因为bank0是内核正在运行的空间,这段区域已经在head.S中的汇编代码里映射好了,如果在这里一并清空的话,内核就没法运行了。
有一个地方我一直不太理解,就是PGDIR_SIZE的定义,在这个版本的内核里,这个值被定义为:

   [c]
#define PGDIR_SHIFT 21
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
[/c] 

就是说,PGDIR_SIZE被定义为2M,那么为什么不能定义成1M呢?1M正好是一个section,这样不是正好容易理解吗?而且如果这样定义的话,pmd方面的处理也会比较麻烦一些(在这里PMD其实就是PGD)。比如在pmd_clear()中,每次都需要设置两项:

   [c]
#define pmd_clear(pmdp) \
 do { \
 pmdp[0] = __pmd(0); \
 pmdp[1] = __pmd(0); \
 clean_pmd_entry(pmdp); \
 } while (0)
[/c] 

接下来的一个重要函数是map_lowmem() -> map_memory_bank() -> create_mapping()

   [c]
static void __init create_mapping(struct map_desc *md)
{
 unsigned long phys, addr, length, end;
 const struct mem_type *type;
 pgd_t *pgd;
......
 pgd = pgd_offset_k(addr);
 end = addr   length;
 do {
 unsigned long next = pgd_addr_end(addr, end);
 alloc_init_section(pgd, addr, next, phys, type);
 phys  = next - addr;
 addr = next;
 } while (pgd  , addr != end);
}
[/c] 

map_lowmem()是为低端物理内存建立映射,在我的模拟环境中,物理内存只有一个bank,共有16M。alloc_init_section()为每一个PGD建立映射。

   [c]
static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
 unsigned long end, unsigned long phys,
 const struct mem_type *type)
{
 pmd_t *pmd = pmd_offset(pgd, addr);

if (((addr | end | phys) & ~SECTION_MASK) == 0) {
 pmd_t *p = pmd;

if (addr & SECTION_SIZE)
 pmd  ;

do {
 *pmd = __pmd(phys | type->prot_sect);
 phys  = SECTION_SIZE;
 } while (pmd  , addr  = SECTION_SIZE, addr != end);

flush_pmd_entry(p);
 } else {
 alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
 }
}
[/c] 

对于low memory的情况,条件if (((addr | end | phys) & ~SECTION_MASK) == 0)得到满足,这一段是专门为段式映射而准备的。在接下来的do循环中,连续两个PMD/PGD表项会被写入新的内容,以我的系统为例,写入的第一个表项内存是:
pmd = 0xc0007000, *pmd = 0x5000040e, phys = 0x50000000
即把物理地址0x50000000映射到虚拟地址0xc0000000,PMD/PGD表项的位置是在0xc0007000,写入的内容是0x5000040e,其中高12位是段的基地址(物理地址),而低20位0x40e是段的属性。

如果条件if (((addr | end | phys) & ~SECTION_MASK) == 0)不满足的话,函数alloc_init_section()的另外一半代码是为什么设计的呢?
答案是这段代码用于设备内存的映射。

接下来,内核要为设备内存建立映射,在paging_init()->devicemaps_init()->create_mapping()->alloc_init_section()->alloc_init_pte()这个调用栈中,就将用到alloc_init_section()的另外一半代码。与用于存储数据的一般内存不同,这里所说的设备内存往往是为访问设备用的特定地址或者用于特定功能的小段内存(比如中断向量表所占用的内存),而且各块设备内存在物理上可能并不连续,如果使用段为单位来做映射的话,就会浪费很多虚拟地址空间,所以设备内存使用页式映射,即二级映射。

以“中断向量表”的映射为例,在下面这段代码中,内核使用boot memory manager为中断向量表申请一页(4K)内存,并将这页内存映射到虚拟地址的0xffff0000处。对于中断向量表的位置,ARM为操作系统提供了两个选项,可以把它配置到内存的最低地址0x00000000处,也可以把它配置到到地址0xffff0000处,这里所说的地址都是虚拟地址,即经过MMU映射过后的地址。Linux默认选择后者,即高地址。

   [c]
static void __init devicemaps_init(struct machine_desc *mdesc) {
......
vectors = alloc_bootmem_low_pages(PAGE_SIZE);
......
 map.pfn = __phys_to_pfn(virt_to_phys(vectors));
 map.virtual = 0xffff0000;
 map.length = PAGE_SIZE;
 map.type = MT_HIGH_VECTORS;
 create_mapping(&map);
[/c] 

至于为设备内存做二级映射的过程,我将另写一篇做详细记录,因为内容比较多。

关键字:ARM  Linux  S3C6410架构  2.6.35内核  内存映射 引用地址:ARM Linux (S3C6410架构/2.6.35内核)的内存映射(二)

上一篇:ARM Linux (S3C6410架构/2.6.35内核)的内存映射(三)
下一篇:Arm-Linux二级页表的问题

推荐阅读最新更新时间:2024-03-16 14:58

ARM·存储器配置
关于配置SDRAM的这个程序,因为研究了2天,所以这里最后再复习一下 首先补充一下基本的知识: 运行地址- 链接地址 在SRAM或者SDRAM中执行程序时,PC指向这个地址,那么命令就应该在这个地址里面 ; 加载地址- 存储地址 程序保存在NAND FLSAH中的地址 位置无关码:B,BL,MOV 位置有关码:LDR PC,=Label 【关于Makefile】 sdram.bin : head.S leds.c arm-linux-gcc -c -o head.o head.S arm-linux-gcc -c -o leds.o leds.c arm-linux-l
[单片机]
ARM嵌入式平台的VGA接口设计
大多数嵌入式产品的显示终端都选择LCD,但在某些需要大屏幕显示的应用中,工业级LCD的价格比较昂贵,且现有的大屏幕显示器(包括CRT显示器和LCD显示器)一般都采用统一的15针VGA显示接口。三星公司ARM9芯片S3C2410以其强大的功能和高性价比在目前嵌入式产品中得到广泛的应用。笔者在开发基于ARM嵌入式平台的血液流变测试仪的过程中,成功地利用高性能视频D/A转换芯片ADV7120,将S3C2410自带的LCD扫描式接口转换为VGA接口,使之能够驱动VGA接口的显示器。 1 VGA接口介绍 近年来,业界制定出了众多数字化的显示接口协议,较为典型的是DVI(Digital Visual Interface)。由于数字接口的标
[工业控制]
[Linux 底层]U-boot编译移植
系统版本:Ubuntu18.04-64 编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) uboot版本:2018.07 -linux4sam_6.0 板子型号:at91sama5d3x-xplained MCU型号:sama5d36 1、uboot目录如下: 2、在configs/ 文件夹下面有官方的默认配置 # To put environment variables in nandflash (default): sama5d3_xplained_nandflash_defconfig # To put envi
[单片机]
[<font color='red'>Linux</font> 底层]U-boot编译移植
Linux下vim编辑器的使用小技巧
Vim是Linux操作系统中最常用一个编辑器。如配置文件的更改、环境变量的设置等等基本上都是在这个vim编辑器上完成。所以这是Linux系统管理员最常用的一个工具。不过这个工具虽然小,但是其有很多的实用小技巧。有些系统管理员可能并不知道。在此笔者就把这些技巧共享出来,大家若觉得有用,不妨在工作中用用看。 一、备份个性化配置文件。 Vim文本编辑器有很多默认的设置。但是当系统管理员熟悉了这个工具之后,可能这个默认的设置就不符合他们的需求了。为此系统管理员希望能够像Word等文本处理器一样对其进行一些个性化的设置,以方便他们编写配置文件、设置环境变量等等。如系统管理员可能会重新定义某些键的功能、创建一些缩写符号、或者设置特定的
[嵌入式]
基于ARM的在线更新机制的设计实现
0 引言 分散型控制系统中的现场终端一般由控制器和各检测模块构成,它们之间通过一定的通信网络建立数据的交换链路。这种系统具有高可靠、开放性、灵活性、协调性、易维护等优点。然而,该分散型系统也具有终端数量多、分布范围广的特点。一旦终端系统软件存在缺陷或用户提出新的功能和指标要求时,其升级、维护的工作量和成本都非常大。本文针对上述情况,设计了一种方便、灵活、快速及稳定地对MCU节点进行在线更新的机制。基于LPC11C24微控制器组成的CAN网络,采用IAP编程技术(In Application Programming),实现了对目标节点MCU的软件更新功能。 1 LPC11C24单片机和CAN总线 恩智浦半导体(NXP)推出业界首款内嵌
[单片机]
基于<font color='red'>ARM</font>的在线更新机制的设计实现
ARM、DSP、FPGA的技术特点和区别有哪些
ARM、DSP、FPGA与什么区别?各自有什么特点?这是一个很基础的问题,本文对ARM、DSP、FPGA的各自特点和技术进行了分析。 ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,设计了大量高性能、廉价、耗能低的RISC处理器、相关技术及软 件。ARM架构是面向低预算市场设计的第一款RISC微处理器,基本是32位单片机的行业标准,它提供一系列内核、体系扩展、微处理器和系统芯片方案,四 个功能模块可供生产厂商根据不同用户的要求来配置生产。由于所有产品均采用一个通用的软件体系,所以相同的软件可在所有产品中运行。目前ARM在手持设备 市场占有90以上的份额,可以有效地缩短应用程序开发与测试
[单片机]
Arm联合创始人:Arm收购将使美形成新的技术垄断
据thisismoney报道,Arm联合创始人Hermann Hauser警告称,若将Arm出售给英伟达,美国将形成技术垄断。 Hauser称,基于Arm架构设计的芯片无处不在。收购Arm将意味着Arm不再是“半导体行业的瑞士”,它的知识产权可能会让英伟达成为谷歌、Facebook和亚马逊那样的主导力量。 在一封给议会外交事务委员会的信中,Hauser说:“世界上任何一家重要的半导体公司都能获得Arm许可证。” 英伟达有机会成为全球微处理器的准垄断供应商。这将使英伟达在所有处理器领域占据主导地位,并形成另一家美国技术垄断企业。英伟达虽一再强调,它将保持Arm对竞争对手的中立立场,但有人呼吁对该交易进行调查。
[手机便携]
ARM入门笔记
ISP实验 一.背景 由于前面的实验都是用仿真器将代码下载到AT91SAM7S64的SRAM里调试的,还不能在实际的Flash ROM里跑。所以在这个实验中,我们将通过ATMEL提供的SAM-BA 软件和AT91SAM7S64自带的ROMBoot功能,完成AT91SAM7S64的Flash ROOM的在线烧写。 二.实验目的 用前面 I/O口输入实验 的源程序生成二进制文件,下载到AT91SAM7S64的Flash ROM中,且能脱机正确运行。 三.操作方法 1 安装。双击Install SAM-BA.exe文件运行,按提示一步步安装即可。 2 连接好硬件,且使AT91SAM7S64处于RomBoot状态。 3 运行。双
[单片机]
<font color='red'>ARM</font>入门笔记
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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