关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问

gooogleman 2008-12-17 11:53:20
加精
void Launch(DWORD dwLaunchAddr)这个函数是在SMDK2440A\Src\Bootloader\Eboot\util.s(32)实现的
;******************************************************************************

INCLUDE kxarm.h

PHY_RAM_START EQU 0x30000000
VIR_RAM_START EQU 0x80000000

TEXTAREA

LEAF_ENTRY Launch

ldr r2, = PhysicalStart
ldr r3, = (VIR_RAM_START - PHY_RAM_START)

sub r2, r2, r3

mov r1, #0x0070 ; Disable MMU
mcr p15, 0, r1, c1, c0, 0
nop
mov pc, r2 ; Jump to PStart
nop

; MMU & caches now disabled.

PhysicalStart

mov r2, #0
mcr p15, 0, r2, c8, c7, 0 ; Flush the TLB
mov pc, r0 ; Jump to program we are launching.
根据C语言中void Launch(DWORD dwLaunchAddr),只有一个参数以及C和汇编函数调用的参数传递规则。
这个DWORD dwLaunchAddr应该传递给汇编中的r0。
但是我搞不明白这东西是怎么启动起来的。并且这个启动方法和优龙的有很大差别。
根据config.bib中的设置,这个内核开始的物理地址应该是)0x30200000
按照道理应该是直接运行PhysicalStart这个汇编段才能运行起来,但是怎么会在前面横插下面的代码呢?
ldr r2, = PhysicalStart
ldr r3, = (VIR_RAM_START - PHY_RAM_START)

sub r2, r2, r3

mov r1, #0x0070 ; Disable MMU
mcr p15, 0, r1, c1, c0, 0
nop
mov pc, r2 ; Jump to PStart

还有一个疑问,为什么eboot要在nboot之后开启MMU,但是在启动内核的时候又关闭MMU,不能在eboot把MMU都关闭吗?
这样做有什么好处?
...全文
637 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
WINCEANDROID 2012-05-25
  • 打赏
  • 举报
回复
好帖,再顶下。
embedded007 2011-06-08
  • 打赏
  • 举报
回复
好贴阿,必须再顶顶
逸萌 2010-12-28
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 gooogleman 的回复:]
这个帖子还有一些错误的观点,现在纠正一下:
一、在PB下编译的文件由bib文件控制,由于bib文件定义的是虚拟地址,所以程序中的标号就是虚拟地址的,所以本帖的疑惑就自然而解答了。
二、优龙的bootloader其实已经开了cache和MMU,以前我犯了严重的错误,以为没有开,其实在程序中巧妙把虚拟地址和物理地址映射相等。这样造成了我的误解,不过这样有好处的:一是启动内核函数变简单,还有就是访问……
[/Quote]up
m925411 2009-02-08
  • 打赏
  • 举报
回复
没有用的
liwei222 2009-02-05
  • 打赏
  • 举报
回复
都是强人啊
gooogleman 2009-02-05
  • 打赏
  • 举报
回复
这个帖子还有一些错误的观点,现在纠正一下:
一、在PB下编译的文件由bib文件控制,由于bib文件定义的是虚拟地址,所以程序中的标号就是虚拟地址的,所以本帖的疑惑就自然而解答了。
二、优龙的bootloader其实已经开了cache和MMU,以前我犯了严重的错误,以为没有开,其实在程序中巧妙把虚拟地址和物理地址映射相等。这样造成了我的误解,不过这样有好处的:一是启动内核函数变简单,还有就是访问物理地址和虚拟地址一样了,代码可以复用。

哈哈。再次回头,发现一切是那么顺其自然。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
ViewBin... mboot.bin
Image Start = 0x00010000, length = 0x00022738
Start address = 0x00011000
Checking record #5 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC = 0x00031e90
ROMOFFSET = 0x00000000

ROMHDR ----------------------------------------
DLL First : 0x02000000
DLL Last : 0x02000000
Physical First : 0x00010000
Physical Last : 0x00032738
RAM Start : 0x00050000
RAM Free : 0x00060000
RAM End : 0x00070000
Kernel flags : 0x00000000
Prof Symbol Offset : 0x00000000
Num Copy Entries : 1
Copy Entries Offset : 0x00031F04
Num Modules : 1
Num Files : 0
MiscFlags : 0x00000002
CPU : 0x01c2 (Thumb)
Extensions : 0x00000000

COPY Sections ---------------------------------
Src: 0x00032000 Dest: 0x00050000 CLen: 0x738 DLen: 0xFEF0

MODULES ---------------------------------------
12/11/2008 03:07:04 143360 nk.exe

FILES ----------------------------------------
Done.
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
MEMORY
; Name Start Size Type
; ------- -------- -------- ----
MBOOT 00010000 0003F000 RAMIMAGE
RAM 00050000 00020000 RAM

CONFIG
COMPRESSION=OFF
PROFILE=OFF
KERNELFIXUPS=ON
ROMOFFSET=0
SRE=OFF
ROMSTART=00010000
ROMWIDTH=32
; ROMSIZE=3F000
ROMSIZE=25000

MODULES
; Name Path Memory Type
; -------------- ---------------------------------------------- -----------
nk.exe $(_TARGETPLATROOT)\target\$(_TGTCPU)\$(WINCEDEBUG)\mboot.exe MBOOT
hhyh612 2008-12-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 wohuazhen 的回复:]
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX

按你的解释,就是当编译出来的PhysicalStart这个标号的值就是8XXXXXXX的虚地址。那么在bootloader刚启动并未打开MMU的那伙,如果也存在一个标号的话,那编译出来是物理地址还是虚拟地址呢?如果是虚拟地址能正确运行吗?如果是…
[/Quote]

在bootloader刚启动并未打开MMU的那伙,pc的实际值和程序地址是不一致,因此那段指令必须都是位置无关的,并且不能直接引用全局变量,不能直接使用标号
gooogleman 2008-12-18
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 wohuazhen 的回复:]
我的开发板mboot(支持USB,NAND,SD,Ether等)boot.bib中
MBOOT 00010000 0003F000 RAMIMAGE
我用viewbin查看了一下,mboot.bin,也都是0x0开头的。
我在6楼也贴出了我的launch的汇编代码。也是用到MMU的。也做了那个虚拟地址到物理地址的转换。
如果做虚拟地址到物理地址的转换是因为RAMIMAGE的设置问题,显然是不成立的。
---我的理解。
我也觉得PC的值是绝对地址。但是当涉及到MMU的时候,在执行的过程中PC这个绝对地址会不会有所变化呢?
[/Quote]

我觉得你是否是看到开MMU之前使用的那个bib文件。在bootloader中用到两个bib文件

对于2440 5.0 BSP中有boot.bib和stepldr.bib
=================boot.bib=========================
;******************************************************************************

MEMORY
; Name Start Size Type
; ------- -------- -------- ----
ARGS 80020800 00000800 RESERVED
RAM 80026000 00006000 RAM
STACK 8002c000 00004000 RESERVED
EBOOT 80038000 00040000 RAMIMAGEMMU打开,所以是虚拟地址,对应物理地址30038000
BINFS 80080000 00021000 RESERVED

; Area used to cache nk.bin while programming flash
FLSCACHE 80200000 01400000 RESERVED
DISPLAY 80100000 00100000 RESERVED

CONFIG
COMPRESSION=OFF
PROFILE=OFF
KERNELFIXUPS=ON
; ROMOFFSET=25FC8000
SRE=ON
ROMSTART=80038000
ROMWIDTH=32
ROMSIZE=40000
============================stepldr.bib========================
MEMORY
; Name Start Size Type
; ------- -------- -------- ----
STEPLDR 00000000 00001000 RAMIMAGE nboot阶段,没有开MMU,使用的是物理地址对应2440内部4K SRAM
STACK 33ff5800 00001000 RESERVED
RAM 33ff0000 00001000 RAM

CONFIG
COMPRESSION=ON
PROFILE=OFF
KERNELFIXUPS=ON

ROMSTART=00000000
ROMWIDTH=32
ROMSIZE=00001000

-----------------------------------------wohuazhen 请你把你的两个bib文件都贴出来看看。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
我的开发板mboot(支持USB,NAND,SD,Ether等)boot.bib中
MBOOT 00010000 0003F000 RAMIMAGE
我用viewbin查看了一下,mboot.bin,也都是0x0开头的。
我在6楼也贴出了我的launch的汇编代码。也是用到MMU的。也做了那个虚拟地址到物理地址的转换。
如果做虚拟地址到物理地址的转换是因为RAMIMAGE的设置问题,显然是不成立的。
---我的理解。
我也觉得PC的值是绝对地址。但是当涉及到MMU的时候,在执行的过程中PC这个绝对地址会不会有所变化呢?
gooogleman 2008-12-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 wohuazhen 的回复:]
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX

按你的解释,就是当编译出来的PhysicalStart这个标号的值就是8XXXXXXX的虚地址。那么在bootloader刚启动并未打开MMU的那伙,如果也存在一个标号的话,那编译出来是物理地址还是虚拟地址呢?如果是虚拟地址能正确运行吗?如果是…
[/Quote]

越来越有意思了。本来想结贴了的。看来还是不行。
——在这里我也发表一下我的看法。
我觉得这个boot.bib文件是打包eboot的时候,把一些信息写进被打包的文件。在读出来的时候起到一些作用。
所以我觉得
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX
的说法比较合理。
这也是优龙 ADS bootloader为什么可以不用转换的原因之一。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
还有,我不明白在smdk2410的eboot的里边boot.bib里的memory都是0x8开头,说明都是虚拟地址。可是我的都是0x0开头说明是物理地址。都用到了MMU。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX

按你的解释,就是当编译出来的PhysicalStart这个标号的值就是8XXXXXXX的虚地址。那么在bootloader刚启动并未打开MMU的那伙,如果也存在一个标号的话,那编译出来是物理地址还是虚拟地址呢?如果是虚拟地址能正确运行吗?如果是物理地址,那么编译器就要去关注什么时候打开MMU,反之当然也要注意什么时候关闭MMU,那么编译器就再智能一点,将PhysicalStart编译成物理地址好了。还要用户去做转换,多麻烦啊。
Seven_zhangxw 2008-12-18
  • 打赏
  • 举报
回复
好文章,学习了
hhyh612 2008-12-18
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 wohuazhen 的回复:]
引用 15 楼 gooogleman 的回复:
引用 14 楼 wohuazhen 的回复:
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
我认为ldr r0, =PhysicalStart中的PhysicalStart,编译器给的是物理地址,但是当在打开MMU后,这段代码加载到cpu解释过程中会被处理器转换成虚拟地址。


不是啊,这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址,由于,这个代码已经在MMU打开的时候跑到内存运行…
[/Quote]

不是吧,标号的值不会变得
用mov pc的话,一定用的是绝对地址,和pc无关
如果用b指令,那么用的是pc相关的相对地址
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 gooogleman 的回复:]
引用 14 楼 wohuazhen 的回复:
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
我认为ldr r0, =PhysicalStart中的PhysicalStart,编译器给的是物理地址,但是当在打开MMU后,这段代码加载到cpu解释过程中会被处理器转换成虚拟地址。


不是啊,这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址,由于,这个代码已经在MMU打开的时候跑到内存运行了,所以我们要手动把它变回物理地…
[/Quote]
关于程序相关标号,昨下班回去我查看了《ARM系列处理器应用完全技术手册》一书,它的解释,这种标号在汇编时被处理成PC值加上或减去一个数字常量。我想这是为什么“这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址”的原因了。
另外“2条指令内是因为ARM流水线的原因”合理的解释,学习了。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
; 182 : mmuOn( PTs, (unsigned int)(main));

00024 e59f1008 ldr r1, [pc, #8] ;r1是main的地址
00028 e3a00902 mov r0, #2, 18 ;r0是PTs的值,2右循环18位为0x8000,确实这样定义
0002c eb000000 bl mmuOn
00030 |$L41691|

; 183 :
; 184 : while(1);

00030 eafffffe b |$L41691|
00034 |$L41740|
00034 00000000 DCD |main|
00038 |$M41736|

ENDP ; |BootMain|
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
你不是可以反汇编吗?去反汇编你的eboot,看看那段代码反汇编过来是什么。
wohuazhen 2008-12-18
  • 打赏
  • 举报
回复
难道这个bib的文件不起作用?我觉得不太可能。因为这个文件是专门组织bin文件的。
怎么不起作用了?用viewbin查看,确实是按boot.bib来的啊。
问题是你认为那个程序相关标号是因为boot.bib的关系,编译时设定为0x8开头了。如果不是,倒是是什么呢?
我以前看何老师的书时也很困惑,为什么他说boot.bib里的地址是虚拟地址,而我的是物理地址。那时忙着调试板子我还是没去深究。
加载更多回复(25)

19,498

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧