嵌入式linux开发 (二十七) 存储管理(1)从flash到内存

2024-05-27 16:18

本文主要是介绍嵌入式linux开发 (二十七) 存储管理(1)从flash到内存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 本文主要参考代码

  • 执行方式

嵌入式系统中代码的执行方式主要有3种:1.完全映射(fully shadowed)。嵌入式系统程序运行时,将所有的代码从非易失存储器(Flash、ROM等)复制到RAM中运行。例子:s3c2440的nandflash和i.mx6ull的sd卡2.按需分页(demand paging)。只复制部分代码到RAM中。这种方法对RAM中的页进行导入导出管理,如果访问位于虚存中但不在物理RAM中会产生页错误,这时才将代码和数据映射到RAM中。例子:linux系统对于可执行程序的加载3.eXecute In Place (XIP)。在系统启动时,不将代码复制到RAM,而是直接在非易失性存储位置执行。RAM中只存放需要不断变化的数据部分例子:stm32的主flash 及s3c2440的norflash
  • 问题:
代码中有变化部分和不变化部分,所以代码可以分割?如果可以,怎么分割?代码中 分割成 .code .ro-data .data .bss .heap .stack二进制文件中 分割 成 .code .ro-data .data内存中 分割成 .code .ro-data .data .bss .heap .stack
分割出来的代码怎么实现完全映射?.code .ro-data .data 复制到ram.bss 清0.stack 设置SP.heap 设置
分割出来的代码怎么实现XIP?XIP 指的是可以在 flash 取指令,然后执行,栈还是放在 ram 中的pc 顺序指向调用函数时使用.stack

  • 为什么要做内存分段
方便编码
  • hex 文件与反汇编对照
反汇编文件
87800000 <_start>:
87800000:   e10f0000    mrs r0, CPSR
87800004:   e3c0001f    bic r0, r0, #31
87800008:   e3800013    orr r0, r0, #19
8780000c:   e129f000    msr CPSR_fc, r0在 hex文件
:020000048780F3
:10000000 00000FE1 1F00C0E3 130080E3 00F029E1 CE高字节 e1 放在了 高地址, 小端. // dis(反汇编) 文件中也有显示 是小端
ARM默认设置为小端格式led 中的段位置的放置 是有道理的
SECTIONS {. = 0X87800000;.text :{start.o*(.text)}.rodata ALIGN(4) : {*(.rodata)}.data ALIGN(4) : {*(.data)}__bss_start=.;.bss ALIGN(4) : {*(.bss) *(COMMON)}__bss_end=.;
}一开始必定是 .text 段(RO)
然后还是RO的 .rodata (由const修饰的全局变量)
// 两个RO放在一起,方便一起拷贝(因为有时候有一起拷贝的必要?)
然后 .data (在二进制文件中)然后是.bss(.bss 不在二进制文件中,但是占用地址,为了不让.bss占二进制文件的空间,所以将其放在最后面.并省略这个段)
  • 段在文件及内存中的表现形式

-----------------在二进制文件中.text段 为RO,.text 段有相对地址(相对PC),.text 段中有可能有绝对地址,是因为可能使用了地址相关汇编代码(不是C代码)
.rodata 段 为RO, 紧紧挨着 .text段. 在 .text段中如果有对 const变量的引用,引用的不是地址,是 值
.data 段 为RW, 紧紧挨着 .rodata段. 在 .text段中如果有对 data变量的引用,引用的是地址
.bss 段 为RW , 不存在于 二进制文件中. 在 .text段中如果有对 bss变量的引用,引用的是地址,但是可以确定.bss开始与结束的地址及每个bss变量的地址.stack 段, 不存在于二进制文件中.
.heap段, 不存在于二进制文件中.-----------------怎么讲二进制文件拷贝到内存中,并做好内存环境配置1. 对于.text 段. 一定要拷贝到对应的地址上去.因为.text中有可能使用了地址相关汇编代码
2. 对于.rodata 段.其实可以不用拷贝,因为.rodata 的值已经在 .text 中了.
3. 对于.data 段.需要拷贝到对应的地址上去,因为 .text 中要引用 data变量的地址
4. 对于 bss 段, 因为二进制文件中没有,但是.text中会对其变量地址引用 .所以 每个变量的地址,每个变量都要初始化为0. 要在内存中,从段的起始到结束,设置为0.5. 对于stack 段,因为 代码调用 实际上被编译成了 push pop 指令,所以函数实质就是 压栈弹栈.虽然PC一直指向.text段,但是运行时的状态是在.stack段.. 那么栈空间肯定要设置.栈空间的设置只需要初始化SP指针即可. 另外,栈的类型(先增,后增,先减,后减)由具体芯片定义.// 如果对应做菜, 可以这么说 .text是菜谱 , .ro-data 是厨具(不变的数据) , .data和.bss 是菜,.heap段 是个大菜 ,菜谱中有搅拌的动作(类似于代码中有出栈入栈的动作) 
// 也就是说一般菜谱中都会有搅拌的动作,也就是说一般情况下,代码在执行过程中会有出栈入栈的动作.6. 对于 heap 段,一般用来存储数据.如果要使用动态内存,则肯定要用初始化heap ,即,找一块内存,将该内存用数据结构进行管理,malloc和free的时候其实本质也是对数据结构的管理-----------------在内存中.text段 为RO,.text 段有相对地址(相对PC),.text 段中有可能有绝对地址,是因为可能使用了地址相关汇编码(不是C代码)
.rodata 段 为RO, 紧紧挨着 .text段. 在 .text段中如果有对 const变量的引用,引用的不是地址,是 值
.data 段 为RW, 紧紧挨着 .rodata段. 在 .text段中如果有对 data变量的引用,引用的是地址
.bss 段 为RW , 紧紧挨着 .data段. 在 .text段中如果有对 bss变量的引用,引用的是地址.stack 段一般 为 高地址->低地址 发展,往.heap发展,不和.text .rodata .data .bss 段重复
.heap 段一般为 低地址->高地址 发展, 往.stack发展,不和.text .rodata .data .bss 段重复// https://www.bravegnu.org/gnu-eprog/c-startup.html
段有哪些
  • elf 文件中

$ readelf -S ledc.elf 
There are 11 section headers, starting at offset 0x8320:Section Headers:[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al[ 0]                   NULL            00000000 000000 000000 00      0   0  0[ 1] .text             PROGBITS        87800000 008000 000158 00  AX  0   0  4[ 2] .text.startup     PROGBITS        87800158 008158 0000f8 00  AX  0   0  4[ 3] .rodata           PROGBITS        87800250 008250 000004 00   A  0   0  4[ 4] .data             PROGBITS        87800254 008254 000004 00  WA  0   0  4[ 5] .bss              NOBITS          87800258 008258 00000c 00  WA  0   0  4[ 6] .comment          PROGBITS        00000000 008258 000046 01  MS  0   0  1[ 7] .ARM.attributes   ARM_ATTRIBUTES  00000000 00829e 000027 00      0   0  1[ 8] .shstrtab         STRTAB          00000000 0082c5 00005b 00      0   0  1[ 9] .symtab           SYMTAB          00000000 0084d8 000310 10     10  30  4[10] .strtab           STRTAB          00000000 0087e8 0000f2 00      0   0  1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)
  • elf 文件反汇编出来的dis文件中
.text
.text.startup
.rodata
.data
.bss
.comment
.ARM.attributes
  • bin 文件中 (最终只有bin文件被烧写到flash中)
.text
.text.startup // 和-O2 有关系 https://www.raspberrypi.org/forums/viewtopic.php?t=126964// 如果用-O0 或者-O1编译,是没有.text.startup 段的
.rodata
.data

这篇关于嵌入式linux开发 (二十七) 存储管理(1)从flash到内存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1007970

相关文章

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc