请教内存分配的问题

huh1012   2008-12-17 22:05 楼主
在wince里面有两种分配方法,一种是OALPAtoVA(),一种是VirtualAlloc()、VirtualCopy()。我想问以下几个问题:
1,什么时候调用VirtualAlloc()、VirtualCopy()、什么时候调用OALPAtoVA()?看上去,驱动里面都是调用前者,OAL、EBOOT都是调用后者,这两者有什么区别,为什么driver里面不能调用后者,OAL、eboot不能调用前者?
2,OALPAtoVA()里面的VA的值都是固定的,我想问一下,比方说三星的芯片,0x30000000地址对应的V地址总是0x80000000,为什么是80000000呢,可以随便改吗?比方说,我改成9000000可以吗?
3,OALPAtoVA(),里面有个cache,加上0x20000000,为什么是这个值,由什么决定的?谢谢

回复评论 (22)

mark
点赞  2008-12-17 22:08
1. 驱动里基本上都用VirtualAlloc和VirtualCopy,并不说明驱动里不能用OALPAtoVA,
如果是跑在Kernel模式的驱动也可以用的,不是跑在Kernel里的驱动用它就会出现
DataAbort. 为什么驱动里调用前者,那应该是它需要CE OS的支持吧,而EBoot下面OS
并没有运行,所以不能调用前者
2. OALPAtoVA/OALVAtoPA是通过OEMAddressTable来映射物理地址和虚拟地址,所以只要
Table表定了,它就固定了,至于这表里的值当然不是随便可以指定,在满足CE
内存空间分配的要求下是可以修改的,理论上来说改成0x90000000应该是可以的
3. CE规定0x80000000-0xA0000000的地址是cached,而后面0x20000000是uncached
不知道有没有理解不对的地方,请大家发表意见
点赞  2008-12-17 22:25
VirtualXXX是内核函数,内核初始化虚拟内存管理比较晚,在KernelInit里面,在KernelInit以前的OAL初始化代码直接用OEMAddressTable取无聊内存对应的虚拟内存,BOOT就更不可能使用内核的函数了,加上0x20000000是对应的不缓冲的内存空间,比如要映射物理寄存器是肯定不能缓冲的。
点赞  2008-12-17 22:54
Built-in Drivers应该是可以使用OALPAtoVA,但是MS不希望你这么做,VirtualXXX比较安全
点赞  2008-12-17 23:00
hzdysymbol 兄:
我怎么确定我的驱动是不是跑在kernel模式和非kerenel模式呢?或者说,我怎么让我的驱动跑在kernel模式呢?

CE规定0x80000000-0xA0000000的地址是cached,而后面0x20000000是uncached:这是CE规定的还是ARM的缘故?还有cache,跟ARM有没有关系?


navi_dx 兄:

0x20000000是对应的不缓冲的内存空间,这里的不缓冲是个什么概念?这个值是跟ARM相关还是由CE自己定的?
点赞  2008-12-17 23:08
引用: 引用 4 楼 navi_dx 的回复:
Built-in Drivers应该是可以使用OALPAtoVA,但是MS不希望你这么做,VirtualXXX比较安全

这跟Built-in没有关系吧
点赞  2008-12-17 23:11
引用: 引用 5 楼 Seven_zhangxw 的回复:
hzdysymbol 兄:
我怎么确定我的驱动是不是跑在kernel模式和非kerenel模式呢?或者说,我怎么让我的驱动跑在kernel模式呢?

CE规定0x80000000-0xA0000000的地址是cached,而后面0x20000000是uncached:这是CE规定的还是ARM的缘故?还有cache,跟ARM有没有关系?


navi_dx 兄:

0x20000000是对应的不缓冲的内存空间,这里的不缓冲是个什么概念?这个值是跟ARM相关还是由CE自己定的?

在CE5.0下面可以设置ROMFLAGS来指定是否运行在Full kernel模式,CE6下面可以通过platform.bib中指定K Flag来让相应的DLL运行在Kernel模式下
cach还是uncach当然是跟CE有关的,跟ARM无关的
点赞  2008-12-17 23:15
我还以为你又重新开一贴呢。这个我前几天刚好看过相关的东西,我来发表一下。

引用: 引用楼主 Seven_zhangxw 的帖子:
1,什么时候调用VirtualAlloc()、VirtualCopy()、什么时候调用OALPAtoVA()?看上去,驱动里面都是调用前者,OAL、EBOOT都是调用后者,这两者有什么区别,为什么driver里面不能调用后者,OAL、eboot不能调用前者?
回答:VirtualAlloc,VirtualCopy的作用是分配虚拟内存,和物理地址转换成虚拟地址的OALPAtoVA的作用还是有点区别的。一般来说前者在驱动中经常使用,在EVC下也可以使用
OALPAtoVA的源码我看过,在C:\WINCE500\PLATFORM\COMMON\SRC\ARM\COMMON\MEMORY\memory.c下面有详细的实现和注释。其实OALPAtoVA/OALVAtoPA就是利用OEMAddressTable来实现虚拟内存和物理内存之间的转换,具体怎么做,你可以看看代码。


2,OALPAtoVA()里面的VA的值都是固定的,我想问一下,比方说三星的芯片,0x30000000地址对应的V地址总是0x80000000,为什么是80000000呢,可以随便改吗?比方说,我改成9000000可以吗?
回答:OALPAtoVA和 OEMAddressTable有关系,所以不是随便弄的,至于0x30000000地址对应的V地址总是0x80000000,这个是由于0x30000000是物理内存的起始地址,0x80000000是虚拟内存的起始地址,这样对其自然比较好了,改动是可以的,但是没有什么好处,在cached情况下。改成小于等于0x9FFFFFFF都可以,但是会导致虚拟内存不够了,没有意义
3,OALPAtoVA(),里面有个cache,加上0x20000000,为什么是这个值,由什么决定的?
回答:cached和uncached是为了提高访问速度的问题。在Bootloader之后,除了访问内存(提高速度)是cached以为,其他外设基本都是uncached,像GPIO使用cached
会得到错误的结果。还有这个OEMAddressTable为了统一,都是cached的虚拟地址,在访问的时候除了内存,其他还是变成uncached的——这点切记。
其实我发现,这个虚拟内存和物理内存转换是有规律的,我们可以不使用OALPAtoVA等,直接访问地址(数字,比如0x88000000).这个我做过。


以上是我个人看法,欢迎大家一起讨论这个这么有意思的事情。

至于为什么要使用虚拟内存,这个东西要追究到操作系统的设计以及MMU的厉害特性了。
点赞  2008-12-17 23:17
引用: 引用 5 楼 Seven_zhangxw 的回复:
hzdysymbol 兄:
我怎么确定我的驱动是不是跑在kernel模式和非kerenel模式呢?或者说,我怎么让我的驱动跑在kernel模式呢?

CE5.0的驱动都是跑在非kerenel模式,据说CE6.0可以选择跑在两个地方都行CE规定0x80000000-0xA0000000的地址是cached,而后面0x20000000是uncached:这是CE规定的还是ARM的缘故?还有cache,跟ARM有没有关系?
这个是cache其实是个硬件的,操作系统为了使用它,就要这样做,估计这个 0x20000000起到片选/使能cache这个强大硬件的缘故。


navi_dx 兄:

0x20000000是对应的不缓冲的内存空间,这里的不缓冲是个什么概念?这个值是跟ARM相关还是由CE自己定的?

这个所谓缓冲就是ARM内部的cache起了作用。这个是ARM的硬件,CE为了使用它,故而有了这个设计,我觉得0x20000000刚好片选了cache这个硬件,


楼主,找本ARM官方的结构体系的书籍看看。——700多页,讲的相当精彩,
你白天不能上MSN?不然我传给你的。貌似我传在我的eeworld 资源了。
你上eeworld的时候发个话给我吧。
点赞  2008-12-17 23:25
这个ARM9之所以能够使用虚拟内存,完全是因为有MMU和cache这两个硬件单元。

——hzdysymbol 兄说的是偏软件了,少了ARM9的MMU和cache这两个硬件单元,wince和linux就不能跑了,ARM9和ARM7最大区别就在这里。
点赞  2008-12-17 23:30
上面搞错一点。纠正一下
引用: 引用 9 楼 gooogleman 的回复:
hzdysymbol 兄:
我怎么确定我的驱动是不是跑在kernel模式和非kerenel模式呢?或者说,我怎么让我的驱动跑在kernel模式呢?

CE5.0的驱动都是跑在非kerenel模式,据说CE6.0可以选择跑在两个地方都行CE规定0x80000000-0xA0000000的地址是cached,而后面0x20000000是uncached:这是CE规定的还是ARM的缘故?还有cache,跟ARM有没有关系?
这个是cache其实是个硬件的,操作系统为了使用它,就要这样做,估计这个 0x20000000起到片选/使能cache这个强大硬件的缘故。
——这里搞晕了一下 这个 0x20000000起到片选/禁止cache这个强大硬件的缘故


navi_dx 兄:

0x20000000是对应的不缓冲的内存空间,这里的不缓冲是个什么概念?这个值是跟ARM相关还是由CE自己定的?

这个所谓缓冲就是ARM内部的cache起了作用。这个是ARM的硬件,CE为了使用它,故而有了这个设计,这个所谓缓冲就是ARM内部的cache起了作用。这个是ARM的硬件,CE为了使用它,故而有了这个设计,我觉得0x20000000刚好片选/禁止了cache这个硬件,

在wince中
cached 虚拟地址 0x80000000~0x9fffffff——512M
uncached 虚拟地址 0xA0000000~0xBfffffff
我想windows CE最多支持512M物理内存就由此而来。

——以上是我个人的理解。不知道对不对。
点赞  2008-12-18 09:23
以前看何宗健的书,看不明白,现在重新看,收获不小。
——
在一些文档上,说在OAL阶段,读入OEMAddressTable是用来设置MMU 页表的。这个页表挺复杂的
过几天再看看代码吧。

点赞  2008-12-18 09:32
额~~好精彩~~~
点赞  2008-12-18 09:58
精彩啊,学习了。我这几天也要看看ARM core方面的书,说不定也会有收获的。
希望大家继续啊。讨论讨论,疑惑就变得清晰了。
我觉得这些讨论才能让我们更深入内核,无论是wince还是linux,最核心的往往是这些吧,那些driver的编写,相对于这个简直都是小小菜啊
点赞  2008-12-18 10:16
引用: 引用 14 楼 Seven_zhangxw 的回复:
精彩啊,学习了。我这几天也要看看ARM core方面的书,说不定也会有收获的。
希望大家继续啊。讨论讨论,疑惑就变得清晰了。
我觉得这些讨论才能让我们更深入内核,无论是wince还是linux,最核心的往往是这些吧,那些driver的编写,相对于这个简直都是小小菜啊


是的,是的,一旦问到这些和硬件相关的问题。
就没有什么人回答了。

两个月前我专门看了MMU、cache,的原理,当时只是看,怕理解错误,不敢以博客形式写下自己的想法。
过几天吧,如果顺利,完成公司交给的工作,就重新看一遍,把协处理器相关的文档,翻译出来,写几篇博客。
结合OAL所涉及的代码看一遍,一定收获不小。不记录下来很快就忘记了。
——这个topic比较有意思,牛人们快来啊。
点赞  2008-12-18 10:25
引用: 引用 14 楼 Seven_zhangxw 的回复:
精彩啊,学习了。我这几天也要看看ARM core方面的书,说不定也会有收获的。
希望大家继续啊。讨论讨论,疑惑就变得清晰了。
我觉得这些讨论才能让我们更深入内核,无论是wince还是linux,最核心的往往是这些吧,那些driver的编写,相对于这个简直都是小小菜啊


是的,是的,一旦问到这些和硬件相关的问题。
就没有什么人回答了。

两个月前我专门看了MMU、cache,的原理,当时只是看,怕理解错误,不敢以博客形式写下自己的想法。
过几天吧,如果顺利,完成公司交给的工作,就重新看一遍,把协处理器相关的文档,翻译出来,写几篇博客。
结合OAL所涉及的代码看一遍,一定收获不小。不记录下来很快就忘记了。
——这个topic比较有意思,牛人们快来啊。
点赞  2008-12-18 10:25
driver比较独立,完成的功能也很单一,bootloader本身也比较小,OAL要复杂得多,代码也巨多,一般是对那部分有问题就看那一部分,但是看完很快就忘记了,我没有做笔记的好习惯,也没有精力把OAL都看一遍,gooogleman 这样谨慎的态度值得学习。
点赞  2008-12-18 10:37
引用: 引用 16 楼 gooogleman 的回复:
是的,是的,一旦问到这些和硬件相关的问题。
就没有什么人回答了。

两个月前我专门看了MMU、cache,的原理,当时只是看,怕理解错误,不敢以博客形式写下自己的想法。
过几天吧,如果顺利,完成公司交给的工作,就重新看一遍,把协处理器相关的文档,翻译出来,写几篇博客。
结合OAL所涉及的代码看一遍,一定收获不小。不记录下来很快就忘记了。



期待你的文章和blog早日面世!!!
点赞  2008-12-19 09:34
学习了一把
点赞  2008-12-20 10:02
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复