内存地址重映射的选项_ARM芯片的地址重映射

本文详细阐述了ARM9处理器的MMU映射表在内核启动过程中的作用,涉及一级和二级页表的区别,以及在LINUX内核中的应用。重点讲解了内核解压缩时的临时映射表和页表创建的两个关键阶段,以及它们与操作系统交互的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这种机制是纯粹的高速硬件操作,

并不需要操作系统来完成。

操作系统只要提供内存转换表

就可以了,但是需要符合一定的格式。

ARM9

MMU

映射表分为两种,一级页表的变换和二级页表变换。两者的不同之处就是实现

的变换地址空间大小不同。一级页表变换支持

1 M

大小的存储空间的映射,而二级可以支

64

kB

4

kB

1

kB

大小地址空间的映射。在

LINUX

中最终使用了

1

M

一级页表和

4

kB

的二级页表(即

1M

段区和

4KB

页面)

内核中地址转换表建立过程

地址转换表建立是和内核的启动一起完成的,页表的建立也可以分为三个阶段:

第一阶段是发生在内核解压缩、自引导时,也就内核镜像

zimage

的文件头部分。相关

代码从某种意义上来讲不属于内核,它是

BSP

代码中的一部分,是需要根据不同的架构来

分别实现的。

通过平面映射的方式建立了

256M

空间节描述表。

但是,

这个映射表是临时的,

是为了提高内核解压缩时的速度而实现的。

在解压缩结束之后,

进入内核代码之前,

MMU

能就被关闭了,随之的映射表也被废弃不用。

decompress_kernel

函数实现内核的解压缩之后,那么内核启动的第一阶段工作就

完成了。接下来就准备启动真正的内核,但是内核启动时必须要先关闭

MMU

,以至于刚才的

第一阶段映射表不能使用了。

第二阶段是的页表创建是非常关键的。

同样也是使用汇编语言来实现。

在代码中,

有个

#include "stm32f10x.h" #include "i2c.h" // 假设已经配置好了 I2C 的驱动 #define OLED_ADDRESS 0x78 // SH1106 的 I2C 地址通常是 0x78 (7-bit) void OLED_WriteCommand(uint8_t command) { I2C_Write(OLED_ADDRESS, 0x00, &command, 1); // 0x00 表示写入命令 } void OLED_WriteData(uint8_t *data, uint16_t size) { I2C_Write(OLED_ADDRESS, 0x40, data, size); // 0x40 表示写入数据 } void OLED_Init(void) { // 初始化 OLED 的基本命令 OLED_WriteCommand(0xAE); // 关闭显示 OLED_WriteCommand(0xD5); // 设置时钟分频因子和振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); // 设置多路复用率 OLED_WriteCommand(0x3F); // 1/64 duty OLED_WriteCommand(0xD3); // 设置显示偏移 OLED_WriteCommand(0x00); // 不偏移 OLED_WriteCommand(0x40); // 设置显示开始行 OLED_WriteCommand(0x8D); // 充电泵设置 OLED_WriteCommand(0x14); // 开启内部充电泵 OLED_WriteCommand(0x20); // 设置内存地址模式 OLED_WriteCommand(0x00); // 水平地址模式 OLED_WriteCommand(0xA1); // 设置段重映射 OLED_WriteCommand(0xC8); // 设置 COM 输出扫描方向 OLED_WriteCommand(0xDA); // 设置 COM 硬件引脚配置 OLED_WriteCommand(0x12); // COM 引脚配置 OLED_WriteCommand(0x81); // 对比度设置 OLED_WriteCommand(0xCF); // 对比度值 OLED_WriteCommand(0xD9); // 设置预充电周期 OLED_WriteCommand(0xF1); // 预充电周期 OLED_WriteCommand(0xDB); // 设置 VCOMH 电压 OLED_WriteCommand(0x40); // VCOMH 电压值 OLED_WriteCommand(0xA4); // 开启整个显示区域 OLED_WriteCommand(0xA6); // 设置正常显示模式 OLED_WriteCommand(0xAF); // 开启显示 } void OLED_Clear(void) { uint8_t i, j; uint8_t clearData[128]; // SH1106 的有效分辨率为 128x64,每页 128 字节 for (i = 0; i < 8; i++) { // SH1106 分为 8 页 (0-7) OLED_WriteCommand(0xB0 + i); // 设置页地址 OLED_WriteCommand(0x00); // 设置低列地址 OLED_WriteCommand(0x10); // 设置高列地址 for (j = 0; j < 128; j++) { clearData[j] = 0x00; // 清除数据为 0x00 } OLED_WriteData(clearData, 128); // 写入清除数据到显存 } } int main(void) { // 初始化系统时钟、GPIO、I2C 等 OLED_Init(); // 初始化 OLED OLED_Clear(); // 清除 OLED 显示内容 while (1) { // 主循环 } } D:\徐景川作业相关\传感器实验\智能传感与检测技术 实习\sketch_jul10a_copy_20250714175331\sketch_jul10a_copy_20250714175331.ino:1:10: fatal error: stm32f10x.h: No such file or directory compilation terminated. exit status 1 Compilation error: stm32f10x.h: No such file or directory
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值