You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARMv7a裸机系统静态分页:如何用符号生成页表项?

ARMv7a静态分页:自动关联顶级与二级页表的解决方案

问题分析

你遇到的报错invalid operands (.boot_data and *ABS* sections) for &,本质是GNU汇编器在单独汇编阶段无法处理未分配绝对地址符号的位运算——二级页表符号的绝对地址只有在最终链接时才能确定,汇编阶段仅能获取符号的相对偏移或未解析标记,无法完成& 0xfffffc00这类绝对地址位操作。

可行解决方案

方案1:通过链接器脚本生成顶级页表条目

这是最可靠的方式,直接利用链接器对全局符号绝对地址的计算能力,在链接阶段完成页表项的位运算和生成。

步骤1:编写链接器脚本(如linker.ld)

MEMORY {
    ROM : ORIGIN = 0x00000000, LENGTH = 1M  ; 根据实际内存布局调整
}

SECTIONS {
    .boot : {
        /* 定义顶级页表起始地址 */
        top_level_table = .;
        
        /* 生成顶级页表条目:指向二级页表1 */
        LONG((second_level_table_1 & 0xfffffc00) | 0x9)
        /* 添加其他顶级页表条目,格式同上 */
        
        /* 确保顶级页表占满1KB(ARMv7a顶级页表固定1KB大小) */
        . += (1024 - (. - top_level_table));

        /* 二级页表1:自动对齐到1KB边界 */
        . = ALIGN(1024);
        second_level_table_1 = .;
        *(.second_level_table_1)
        /* 确保二级页表占满1KB */
        . += (1024 - (. - second_level_table_1));

        /* 二级页表2:同理 */
        . = ALIGN(1024);
        second_level_table_2 = .;
        *(.second_level_table_2)
        . += (1024 - (. - second_level_table_2));
    } > ROM
}

步骤2:编写汇编文件(如page_tables.S)

只需要定义二级页表的内容,顶级页表由链接器自动生成:

.section .second_level_table_1, "a"
; 二级页表1的条目示例:映射0x0地址的1MB区域为读写、非缓存
.rept 256
    .word 0x00000000 + (. - second_level_table_1)*4096 | 0x12
.endr

.section .second_level_table_2, "a"
; 二级页表2的条目示例:映射0x10000000地址的1MB区域
.rept 256
    .word 0x10000000 + (. - second_level_table_2)*4096 | 0x12
.endr

方案2:汇编中结合链接器表达式(简化写法)

如果希望顶级页表定义在汇编文件中,可以通过链接器支持的表达式间接完成位运算,避免汇编阶段报错。

修改汇编文件中的顶级页表条目写法:

.section .boot_data, "a"
.global top_level_table
top_level_table:
    ; 利用链接器的移位运算屏蔽低10位,再或上配置位
    .word ((second_level_table_1 >> 10) << 10) | 0x9
    .word ((second_level_table_2 >> 10) << 10) | 0x9
    ; 填充剩余顶级页表条目为0或其他配置
    .space 1024 - (. - top_level_table), 0

.align 10  ; 强制二级页表按1KB对齐
.global second_level_table_1
second_level_table_1:
    .space 1024  ; 二级页表内容自行填充

.align 10
.global second_level_table_2
second_level_table_2:
    .space 1024

此时需要确保链接器支持对符号的移位运算(GNU ld完全支持),编译链接时指定链接器脚本以保证页表的正确布局。

关键说明

  • ARMv7a的二级页表必须按1KB(0x400)对齐,所以需要用.align 10或链接器的ALIGN(1024)确保布局正确。
  • 链接器脚本的方式更易于维护,尤其是当页表数量增多时,无需手动跟踪地址变化。

内容的提问来源于stack exchange,提问作者George Hodgkins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:45:00