打印

linux下如何指定一个函数在指定地址(ARM片内SRAM)执行?

[复制链接]
2882|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bjlny|  楼主 | 2012-12-9 12:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 bjlny 于 2012-12-9 22:39 编辑

各位好:
我现在在做低功耗相关,如果要让系统处于低功耗状态,除了要关闭液晶等外设,还要将ARM处于低功耗,DDR处于自刷新,但是在DDR自刷新之前,程序必须运行在DDR之外,因为按照厂家的说法,这时DDR就已经不能运行程序了(我的理解是DDR自刷新情况下可以执行,但是只要执行程序那么就不会进入自刷新,也就不能休眠DDR,所以要换地方让CPU取指)。目前计划是在DDR自刷新之前将程序运行在内部32K的SRAM上,这样在DDR自刷新之后还可以继续执行将ARM休眠之类的操作。

这样问题就来了:如何让一个程序在指定地址运行?
目前常规的有几种办法:1.函数指针跳转2.编写汇编指令
1.函数指针跳转时,我如何编写一个函数,指定他的运行地址是在我要的片内SRAM上,即0地址开始的32K空间内?
2.如果是采用C嵌套汇编,那么如何指定运行地址?在linux环境下是否采用lds文件指定运行地址?那么如果可以用Lds文件指定,那么在执行这段函数之前是否还要进行搬运?如何搬运?
请各位讨论下,如果能贴出来代码,那么更好,这是个很实际的问题,也很考验对程序执行的理解。

相关帖子

沙发
圆圈| | 2012-12-9 15:51 | 只看该作者
理论上说:
休眠后,系统不能进入内核态【将所有中断关闭】。否则你要将相关内核代码copy出来还要建立相应的MMU映射机制及中断跳转代码,这个很难

函数指定地址跳转这个很简单。用函数指针就可以。不过难的是此时你的MMU打开还是关闭,打开的话如何手动建立MMU映射机制,同时将相关代码copy到sram中。

=========================================================
现在想到的比较简单的办法是:
在链接文件里做**。将一小段函数链接时自动定位在sram相应地址,该函数做个循环,同时检测退出状态。 另注意,此时还是要将所有中断关闭【目的是防止系统进入内核态】,另外线程调度是否也要关闭,这些细节需要调试才能知道【让整个系统只在这段代码内执行,当需要时才退出循环正常执行】。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
bjlny + 2 很给力!
板凳
bjlny|  楼主 | 2012-12-9 22:44 | 只看该作者
圆圈 发表于 2012-12-9 15:51
理论上说:
休眠后,系统不能进入内核态【将所有中断关闭】。否则你要将相关内核代码copy出来还要建立相应 ...

这个倒是我也考虑了一部分,难的就是MMU映射的处理,这个貌似可以通过Ioremap解决,另外代码拷贝到sram这个感觉有点模糊

使用特权

评论回复
地板
jlass| | 2012-12-10 09:36 | 只看该作者
在操作系统下应该很困难,裸奔可行性高一些。
主要应该是个地址分区的问题。

使用特权

评论回复
5
圆圈| | 2012-12-10 11:08 | 只看该作者
本帖最后由 圆圈 于 2012-12-10 11:40 编辑
bjlny 发表于 2012-12-9 22:44
这个倒是我也考虑了一部分,难的就是MMU映射的处理,这个貌似可以通过Ioremap解决,另外代码拷贝到sram这 ...


错了,还是要处理虚拟地址 MMU之类的事情~~

使用特权

评论回复
6
lu-永| | 2012-12-14 08:01 | 只看该作者
好像在编译时指定!

使用特权

评论回复
7
john_lee| | 2012-12-14 10:49 | 只看该作者
这个需求用不着MMU参与,简单的方法就是定制一个链接器脚本(linker descript),在MEMORY中指定这个SRAM区域,你的程序中需要在SRAM中运行的函数,就加个__attribute__((section("区域"))) 属性,这样链接器就可以确定这个函数的地址了,然后,你还要定制一个copy函数,在内核启动时执行,负责把那个需要在SRAM中执行的代码copy到SRAM中,这个copy函数,不是由你的程序调用,而是由内核启动代码来调用,为此,你要给这个copy函数加上__attribute__((constructor)) 属性。

使用特权

评论回复
8
圆圈| | 2012-12-14 23:49 | 只看该作者
楼上的不可行吧。linux启动后,打开MMU,那么所有的链接地址【程序运行后其地址空间】都是虚拟地址。实际具体定位到哪个物理地址,你还得看MMU。开始我想的和你是一样的。但后来发觉通过链接脚本控制还是不能实现,还是得做MMU处理。  楼主我看你还是做下MMU重映射吧。将睡眠唤醒相关代码重映射到SRAM上。 然后copy相关代码到SRAM来处理。
具体边调试边琢磨了要。我们也只是提示个思路。

使用特权

评论回复
9
bjlny|  楼主 | 2013-7-7 08:25 | 只看该作者
现在已经实现了,参考的是Linux里边的PM电源管理的实现方式

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

19

帖子

0

粉丝