kernel中如何读取内存的大小和地址

本文介绍DDR内存作为手机核心组件的重要性和初始化过程。详细解释了高通平台上的内存初始化步骤,包括sbl阶段的初始化、共享内存使用、以及通过devicetree传递内存信息给内核。

目录

本文中所有的描述都是基于高通平台,并且涉及的所有的操作都是在手机上完成

内存信息的传递方式

什么是DDR

  
  本文并不对DDR具体的物理特性做详细解读, 我们只需要了解如下的一些基本概念, 就能够满足对本文描述的核心内容的理解的需求.
  1. 和LCD, TP等常规器件一样, DDR也是手机中必不可少的器件之一
  2. 我们平时常说的内存, 从目前大部分机器来看, 指的就是DDR, 只不过对于这种需要重点考虑功耗的产品来说, 我们加了LP(low power低功耗)的DDR前面, 也就是LPDDR.
  3. 全称Double Rate Synchronous Dynamic Random Access Memory, wiki翻译过来就是双倍数据率同步动态随机存取存储器.
  4. 就一般意义来说所有的程序软件必须依靠内存才能运行, 此器件非常重要!

内存信息的传递

  就像上面所述, 内存虽然必不可少, 但归根结底就是一种手机器件, 和其他器件一样, 同样需要初始化, 只不过比其他的器件初始早而已.
  就高通平台而言, 如下图所示, 内存信息的传递如下:

Created with Raphaël 2.1.0 开始 内存初始化(sbl) lk中读取信息修改dt kernel中读取dt信息,读取内存大小和地址 结束
  • 在内存没有初始化完成前, 内存是不能使用的, 这时候系统的启动程序运行在片上RAM中, 而此时的启动过程在高通平台我们称之为sbl阶段. DDR器件就是在这一阶段中完成的初始化.

  • 在初始化完成后, 内存的信息存储在共享内存(从内存中单独划分一块作为SMEM)中, 以供lk使用. 在sbl结束后, 会将lk的image从EMMC(对比PC可以理解为硬盘) 加载到内存中运行, 然后lk通过共享内存来读取器件信息.

  • 读取出了信息后, 在lk中, 需要对device tree (dt image中的数据) 进行修改, 因为当前的高通平台lk和kernel的沟通不再是atags, 而变成了device tree.

  • lk结束运行后, 系统启动到了kernel, kernel再通过读取device tree的信息将内存的信息读取出来进行管理.

代码阅览

文件列表

  下面的表, 按照顺序从lk更新dt, 到kernel读取dt列出了相应的代码实现文件和函数.
  

顺序阶段文件名函数名
1lkaboot.cboot_linux
2lkdev_tree.cupdate_device_tree
3lkmeminfo.ctarget_dev_tree_mem
4lkdev_tree.cdev_tree_add_mem_info
5kernelsetup.csetup_arch
6kernelsetup.csetup_machine_fdt
7kernelfdt.cearly_init_dt_scan
8kernelfdt.cearly_init_dt_scan_memory

代码块

  下面的两块代码实际上是两部分, 一部分是lk中修改dt, 一部分是kernel中读取dt: (下面的代码是经过精简的, 只反映了程序运行的流程)

  • lk中修改dt

    信息安全代码略 见上表 4

  • kernel中读取dt信息

    信息安全代码略 见上表 7

<think>我们正在讨论如何使用devmem命令读取指定大小内存区域。根据之前的引用,我们知道devmem是一个用于直接访问物理内存的工具,它允许通过物理地址读取或写入数据。用户现在想了解如何指定读取内存大小。首先,回顾devmem命令的基本用法: devmem命令的语法通常为:```bashdevmemADDRESS[WIDTH [VALUE]]``` 其中: -ADDRESS:要访问的物理内存地址(十六进制或十进制)- WIDTH:可选,指定访问的宽度(单位:字节),可以是8、16、32(默认是32位) -VALUE:可选,如果指定则表示写入该地址的值,不指定则表示读取因此,要读取指定大小内存,我们需要在命令中明确指定WIDTH参数。 例如: 1.读取32位(4字节)的内存地址0x10000000:```bashdevmem0x1000000032```这将输出该地址处的32位值。 2.读取16位(2字节)的内存地址0x10000000:```bashdevmem0x1000000016```3.读取8位(1字节)的内存地址0x10000000:```bashdevmem0x100000008```注意:地址必须是物理地址,并且需要对齐到访问宽度(例如,32位访问的地址必须是4字节对齐,16位访问必须是2字节对齐,8位则任意地址)。另外,使用devmem需要root权限。如果需要读取连续的一段内存区域(多个地址),则不能直接使用devmem命令,因为它每次只能读取一个地址。但我们可以写一个简单的shell脚本来循环读取。例如,读取从0x10000000开始的16个字节(即4个32位字): ```bashfor iin {0..3};doaddr=$(printf"0x%X" $((0x10000000+ i*4)))devmem$addr32done```或者,读取16个字节(每次8位): ```bashfor iin {0..15};doaddr=$(printf"0x%X"$((0x10000000 +i)))devmem $addr8done``` 这样,我们就可以读取指定大小内存区域了。总结:-使用devmem命令并指定WIDTH参数可以读取特定大小(8/16/32位)的内存值。 -如果需要读取连续区域,可以通过循环多次调用devmem。注意:直接操作物理内存具有风险,可能导致系统不稳定或数据损坏,请谨慎使用。 §§相关问题§§1.如何确保使用devmem命令时的地址对齐?2.使用devmem写入内存的方法是什么?3.除了devmem,还有哪些工具可以用于内存访问调试?</think>### 如何使用 devmem 命令读取指定大小内存区域 `devmem` 命令用于直接访问物理内存地址,其基本语法为: ```bash devmem ADDRESS [WIDTH [VALUE]] ``` 其中: - **ADDRESS**:要访问的物理内存地址(十六进制或十进制) - **WIDTH**:可选参数,指定访问的字节宽度(默认为32位) - **VALUE**:可选参数,写入操作时的新值(不指定则执行读取) #### 读取指定大小内存方法: 1. **读取8位(1字节)数据** 使用宽度参数 `8`: ```bash devmem 0x10000000 8 # 读取地址0x10000000处的1字节数据 ``` 2. **读取16位(2字节)数据** 使用宽度参数 `16`: ```bash devmem 0x10000000 16 # 读取地址0x10000000处的2字节数据 ``` 3. **读取32位(4字节)数据**(默认) 可省略宽度参数: ```bash devmem 0x10000000 # 等效于 devmem 0x10000000 32 ``` #### 注意事项: 1. **地址对齐要求**: - 32位访问需4字节对齐(地址末位为0x0, 0x4, 0x8, 0xC) - 16位访问需2字节对齐(地址末位为偶数) - 8位访问无对齐要求 ```bash devmem 0x10000004 32 # ✅ 正确对齐 devmem 0x10000002 32 # ❌ 错误对齐(可能触发总线错误) ``` 2. **权限要求**: 需 root 权限执行: ```bash sudo devmem 0x10000000 8 ``` 3. **连续区域读取**: `devmem` 每次只能读取单个地址。如需读取连续区域,需编写循环脚本: ```bash for i in {0..3}; do addr=$(printf "0x%X" $((0x10000000 + i))) devmem $addr 8 done # 读取0x10000000到0x10000003的4字节 ``` 4. **输出解析**: 结果以十六进制显示: ``` Value at address 0x10000000 (8-bit): 0xA5 ``` > ⚠️ **警告**:直接操作物理内存可能导致系统崩溃或硬件损坏,仅限调试场景使用[^1][^2]。 --- ### 相关问题 1. 如何确保使用 `devmem` 时的地址对齐要求? 2. 除了 `devmem`,还有哪些工具可以安全地读取物理内存? 3. 如何通过 `/dev/mem` `mmap` 实现更高效的内存访问? 4. `devmem` 在嵌入式开发中的典型应用场景有哪些? [^1]: devmem 是一个用于直接访问物理内存的命令行工具。它允许用户通过物理内存地址读取或写入数据。这个命令特别适合嵌入式开发硬件调试,尤其是在没有操作系统支持的情况下,直接与硬件交互时。 [^2]: "/dev/mem"设备通常与"mmap"结合使用,可将指定内存映射到用户空间。类似的还有/dev/kmem设备,kernel看到的虚拟内存的全镜像。可以用来访问kernel的内容。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值