ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

arm linux ddr 内存布局

arm linux ddr 内存布局 1. 512MB DDR 内存分布规划假设系统物理内存基址为0x80000000大小为0x20000000512MB。地址范围大小用途运行时属性0x80000000 - 0x800FFFFF1 MBSecure Monitor / ATF安全世界EL30x80100000 - 0x803FFFFF3 MBU-Boot裸机运行Cache 开启0x80400000 - 0x80DFFFFF10 MBKernel 加载区 (Image)压缩/未压缩内核镜像存放地0x80E00000 - 0x80EFFFFF1 MB设备树 (DTB)硬件描述结构0x80F00000 - 0x88FFFFFF128 MBRootfsSquashFS/UBIFS 映射通常为只读文件系统缓存区0x89000000 - 0x9BFFFFFF~300 MB堆 (Heap) / 用户态空间malloc、mmap分配区0x9C000000 - 0x9FFFFFFF64 MB内核栈 / 内核堆 / 异常向量栈向下增长高地址→低地址2. 512Mbit (64MB) Flash 分区规划lash 物理地址从0x00000000开始总大小0x04000000。分区名起始地址结束地址大小存储内容Bootloader0x000000000x0005FFFF384 KBSPL U-BootEnv / Param0x000600000x0007FFFF128 KBMAC 地址、启动参数Kernel A0x000800000x006FFFFF6.5 MB系统 A 内核镜像Rootfs A0x007000000x01FFFFFF25 MB系统 A 根文件系统Kernel B0x020000000x0267FFFF6.5 MB系统 B 内核镜像双系统Rootfs B0x026800000x03EFFFFF25 MB系统 B 根文件系统Reserved0x03F000000x03FFFFFF1 MBOTP/工厂校准数据数据结构定义内核头 Squashfs 头1. ARM64 Linux 内核镜像头 (Image)struct arm64_image_header { uint32_t magic; // 固定值 0x644D5241 (ARM\x64) uint32_t text_offset; // 内核文本段偏移 uint32_t image_size; // 内核镜像总大小 uint32_t flags; // 启动标志如 4K/64K 页 uint64_t res3; uint64_t res4; uint32_t version; // 版本号 uint32_t res5; uint64_t res6; uint64_t res7; uint64_t res8; };2. Squashfs 文件系统超级块Squashfs 镜像头部固定位于文件偏移0处结构体定义如下struct squashfs_super_block { __le32 s_magic; // 固定魔数 0x73717368 (hsqs) __le32 inodes; // 节点数量 __le32 bytes_used; // 已使用字节数镜像有效大小 __le32 uid_start; // UID 表起始 __le32 guid_start; // GID 表起始 __le32 xattr_id_start; // xattr 表起始 __le32 id_table_start; // ID 表起始 __le32 s_major; // 主版本号 __le32 s_minor; // 次版本号 __le16 block_size; // 块大小如 4K/8K/16K __le16 compression; // 压缩算法1Zlib, 2LZMA, 3LZO // ... 后续还有更多字段 };3单板的启动过程数据交互流程Flash - DDR 各阶段数据流向分析阶段源地址 (Flash)目标地址 (DDR)数据内容校验方法Stage 1BootROM0x00000000内部 SRAM非 DDRSPL 前 4KB硬件 CRCStage 2U-Boot 加载0x00080000(Kernel)0x80400000压缩内核md.l 0x80400000查魔数Stage 3U-Boot 加载0x00700000(Rootfs)0x80F00000Squashfs 镜像md.b 0x80F00000查 hsqsStage 4内核启动DDR0x80400000自解压到0x80008000解压后的内核内核 bootm 校验Stage 5挂载 RootfsFlash0x00700000通过 MTD/UBI 映射不整块拷贝文件系统节点cat /proc/mtd检查挂载点4数据读取流程1 读取并验证 Kernel 头部1. 探测 Flashsf probe 02. 将 Kernel A flash分区 (偏移 0x80000) 读入 DDR 0x80400000 读取大小 0x680000 (6.5MB)sf read 0x80400000 0x00080000 0x6800003. 打印 ddr Kernel 头前 64 字节 (32位字共 16 个)md.l 0x80400000 0x10预期输出分析80400000: 644d5241 00000000 00c16000 00000000 # magic 0x644d5241 (正确!) 80400010: 00000000 00000000 00000001 00000000 # version1, image_size ~ 12.7MB ...若md.l输出首位为0x644d5241则内核镜像有效。若首位为0xFFFFFFFF或0x00000000说明 Flash 读取失败或分区为空。2. 读取并验证 Squashfs 头部# 读取flash Rootfs A 分区 (偏移 0x700000)到 DDR 0x80F00000sf read 0x80F00000 0x00700000 0x1900000按字节打印ddr前 64 字节因为魔数是字符 hsqsmd.b 0x80F00000 0x40预期输出分析80F00000: 68 73 71 73 88 8b 02 00 03 00 00 00 ... # hsqs 即为有效魔数偏移0x00处应为68 73 71 73即 ASCII 字符h s q s。3. 查看内核栈/堆的默认数据未使用前为 0栈区通常初始化为 0 或特定填充值如0xAAAAAAAA。读取栈底附近md.l 0x9FFFE000 0x105堆/栈与 Rootfs 地址重叠导致系统挂死(后续补充)
返回列表