13007|43

72

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问 [复制链接]

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都关闭吗?
这样做有什么好处?

最新回复

没有用的  详情 回复 发表于 2009-2-8 22:41
点赞 关注

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
Launch函数其实只是把PC指针指过去,跳转到相应的地址运行
Eboot中应该有需要访问虚拟地址吧,所以不能关
关掉后再跳到Image是因为Image中还会再做一次初始化的动作,如果在Image中的起始部分把相关的初始化拿掉,应该可以不关MMU
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
引用 1 楼 hzdysymbol 的回复:
Launch函数其实只是把PC指针指过去,跳转到相应的地址运行
Eboot中应该有需要访问虚拟地址吧,所以不能关
关掉后再跳到Image是因为Image中还会再做一次初始化的动作,如果在Image中的起始部分把相关的初始化拿掉,应该可以不关MMU



你说的我明白,我的意思是对他的做法有点不解。
我觉得这个比较令人费解。
ldr r2, = PhysicalStart
ldr    r3, = (VIR_RAM_START - PHY_RAM_START) //为什么要这样做呢?
sub    r2, r2, r3
直接把这个0x30200000放到PC不行吗?


------------------------------------------------
优龙是直接跳转到相应的内存物理地址运行的
不会像在上面那样搞得模模糊糊。

  1. //====================================================
  2. //优龙bootloader加载NK运行入口函数:使用函数指针的方法,
  3. //相当巧妙,程序可读性比三星自带的eboot强悍
  4. //====================================================

  5. void call_linux(U32 a0, U32 a1, U32 a2)
  6. {
  7.         void (*goto_start)(U32, U32);
  8.        
  9.         rINTMSK=BIT_ALLMSK;
  10.        
  11.         cache_clean_invalidate();
  12.         tlb_invalidate();       

  13.         __asm{
  14. //                mov        r0, a0//%0
  15. //                mov        r1, a1//%1
  16. //                mov        r2, a2//%2
  17.                 mov        ip, #0
  18.                 mcr        p15, 0, ip, c13, c0, 0        /* zero PID */
  19.                 mcr        p15, 0, ip, c7, c7, 0        /* invalidate I,D caches */
  20.                 mcr        p15, 0, ip, c7, c10, 4        /* drain write buffer */
  21.                 mcr        p15, 0, ip, c8, c7, 0        /* invalidate I,D TLBs */
  22.                 mrc        p15, 0, ip, c1, c0, 0        /* get control register */
  23.                 bic        ip, ip, #0x0001                        /* disable MMU */
  24.                 mcr        p15, 0, ip, c1, c0, 0        /* write control register */
  25.                 //mov        pc, r2
  26.                 //nop
  27.                 //nop
  28.                 /* no outpus */
  29.                 //: "r" (a0), "r" (a1), "r" (a2)
  30.         }
  31. //        SetClockDivider(1, 1);
  32. //        SetSysFclk(FCLK_200M);                //start kernel, use 200M
  33.         //SET_IF();
  34.         goto_start = (void (*)(U32, U32))a2;//这个a2=0x30200000,在调用的时候传递进来
  35.         (*goto_start)(a0, a1);       
  36. }
复制代码
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

4
 
问题的关键是在Disable MMU后必须在2条指令内执行mov pc操作,否则程序就跑飞
但是在真正跳转到NK地址前,还需要flush cache等操作
所以就先跳到PhysicalStart处,做完其他操作再跳到NK入口
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

5
 
问题的关键是在Disable MMU后必须在2条指令内执行mov pc操作,否则程序就跑飞
这个在哪里有介绍呢?这个我是第一听说,学习了。

但是在真正跳转到NK地址前,还需要flush cache等操作 ,所以就先跳到PhysicalStart处,做完其他操作再跳到NK入口
对,的确如此。

我的疑惑是
ldr r2, = PhysicalStart
ldr    r3, = (VIR_RAM_START - PHY_RAM_START) //求出虚拟地址和物理地址之差。其实虚拟、物理地址转换就是这个原理

sub    r2, r2, r3 //这个相当于是PhysicalStart 所在地址减去(-)虚拟地址和物理地址之差

mov    r1, #0x0070            ; Disable MMU
mcr    p15, 0, r1, c1, c0, 0
nop
mov    pc, r2          ; Jump to PStart 这个难道会跳到PhysicalStart 去执行?按照他的程序,是会的。
难道程序这么做是把这个PhysicalStart所在的虚拟地址转换为物理地址?
就是PhysicalStart(虚拟地址) -虚拟地址和物理地址之差
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
真是这样吗?我觉得这个是比较合理的解释。
因为优龙没有使用(VIR_RAM_START - PHY_RAM_START)的原因就是因为,它在bootloader阶段已经关闭了MMU,没有必要这么做了。

各位前辈,不知道我这样理解是否正确,请指教。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

6
 
同志们,帮帮忙啊。

---------------------
整天我自问自答,心里洼凉瓦亮的
我上面的的解释我都觉得不可思议。真的好想多点人来表达自己的想法。
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

7
 

  1.         
  2.         TEXTAREA
  3.         LEAF_ENTRY Launch

  4.         mov                r10, r0             ; r0 : mov physical launch address

  5.         bl                INTERRUPTS_OFF

  6.         ldr                r1, =g_oalAddressTable
  7.         ldr                r0, =PhysicalStart
  8.         mov                r4, r0
  9.         bl                PaFromVa     ; find physical address of PhysicalStart
  10.         cmp                r0, #-1             ; found?
  11.         movne        r4, r0                     ; yes, save real address

  12.         mov     r1, #0x0070          ; Disable MMU
  13.         mcr                p15, 0, r1, c1, c0, 0        ; MMU & caches now disabled. // excute

  14.         nop                                        ; // decode
  15.         mov                pc, r4                        ; Jump to PStart // patch
  16.         nop

  17. PhysicalStart

  18.         mov                r1, #0
  19.         mcr                p15, 0, r1, c8, c7, 0        ; Flush the TLB
  20.         mov                pc, r10                        ; Jump to program we are launching.

  21.         ENTRY_END
复制代码
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

8
 
这个函数真的没有人看过吗?不可能啊?这么重要的函数。
——实在没有办法我就自己点灯了(借个有LED的板子吧,俺的没有灯。),不过这下面没有反汇编的功能,不然会比较容易理解。
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
wohuazhen 你贴个代码出来??..........这个代码我有啊。不过还是谢谢你帮顶帖子。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

10
 
1,你说优龙bootloader没有打开MMU,所以它不要虚拟地址到物理地址的转换。我认为是对的。
2,三星的eboot用到了MMU,所以它要做虚拟地址到物理地址的转换。
3,上面一段代码是我的开发板的launch。和三星的类似。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

11
 
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
这个我也不知道。
但是我的直接的理解就是,在关闭MMU前,ldr r0, =PhysicalStart,这句的PhysicalStart是个虚拟地址,它是在有MMU的情况下运行的,当mov  pc, r4   ; Jump to PStart // patch 这是在没有MMU的情况下运行的代码,所以r4的值一定要是物理地址。这里的PhysicalStart并不是指os的起始地址,而是要跳到os起始地址前的一个地址。这个我想你应该明白了。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 9 楼 wohuazhen 的回复:
1,你说优龙bootloader没有打开MMU,所以它不要虚拟地址到物理地址的转换。我认为是对的。
2,三星的eboot用到了MMU,所以它要做虚拟地址到物理地址的转换。
这个转换我理解,我不理解的是这样转换之后,还能跳到PhysicalStart 去执行?!真是匪夷所思。难道真如我在4楼的解释?
3,上面一段代码是我的开发板的launch。和三星的类似。
基本和我一样,只是我的更加直接,寄存器也用的少。


谢谢你。牛人们快出来帮忙啊。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

13
 
问题的关键是在Disable MMU后必须在2条指令内执行mov pc操作,否则程序就跑飞
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

14
 
引用 10 楼 wohuazhen 的回复:
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
这个我也不知道。
但是我的直接的理解就是,在关闭MMU前,ldr r0, =PhysicalStart,这句的PhysicalStart是个虚拟地址,它是在有MMU的情况下运行的,当mov  pc, r4  ; Jump to PStart // patch 这是在没有MMU的情况下运行的代码,所以r4的值一定要是物理地址。这里的PhysicalStart并不是指os的起始地址,而是要跳到os起始地址前的一个地址。这个我想你应该明白了。


我正是这么想的。但是我总觉得怪怪的。
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

15
 
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
我认为ldr r0, =PhysicalStart中的PhysicalStart,编译器给的是物理地址,但是当在打开MMU后,这段代码加载到cpu解释过程中会被处理器转换成虚拟地址。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

16
 
引用 14 楼 wohuazhen 的回复:
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
我认为ldr r0, =PhysicalStart中的PhysicalStart,编译器给的是物理地址,但是当在打开MMU后,这段代码加载到cpu解释过程中会被处理器转换成虚拟地址。


不是啊,这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址,由于,这个代码已经在MMU打开的时候跑到内存运行了,所以我们要手动把它变回物理地址,就是下面的代码
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

——这个代码非常巧妙。刚开始还真是没有反映过来。

好,明白了。明天结贴!
谢谢各位。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

17
 
至于eboot为什么要开MMU,而优龙的ADS Bootloader为什么不开,
我想大家一定和我一样很想知道为什么。
——其实这是由于eboot要调用 FMD驱动以及一些微软的函数,这些函数是运行在虚拟内存的,eboot为了讨好她,利用他们,只能委曲求全了,裸奔还要开MMU,岂有此理!哈哈。
优龙 Bootloader,自然是没有和上面这些联系了。自然没有必要开。

所以才会造成启动NK函数有如此大的不同。

哈哈。自己解决也不错。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

18
 
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX

至于为什么Disable MMU后2条指令内必须mov pc
是因为执行mcr    p15, 0, r1, c1, c0, 0 指令时pc是虚地址8XXXXXXX
执行完MMU就关了,8XXXXXXX就不存在了,所以需要马上让pc变成实地址3XXXXXXX

2条指令内是因为ARM流水线的原因,所以MMU关了,但是mcr之后的两条指令以及在pc是虚地址的时候预取了,所以不会报错

如果2条指令之内不mov pc到3XXXXXXX,接下来就要Prefetch Abort了。。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

19
 
引用 17 楼 hhyh612 的回复:
编译器其实是不区分虚实地址的,只不过boot.bib里写了RAMIMAGE的地址是80000000(所谓的虚地址),所以PhysicalStart这个标号的值就是8XXXXXXX的虚地址,在关闭mmu后,必须把它转成物理地址3XXXXXXX

至于为什么Disable MMU后2条指令内必须mov pc
是因为执行mcr    p15, 0, r1, c1, c0, 0 指令时pc是虚地址8XXXXXXX
执行完MMU就关了,8XXXXXXX就不存在了,所以需要马上让pc变成实地址3XXXXXXX

2条指令内是因为ARM流水线的原因,所以MMU关了,但是mcr之后的两条指令以及在pc是虚地址的时候预取了,所以不会报错

如果2条指令之内不mov pc到3XXXXXXX,接下来就要Prefetch Abort了。。——完全明白了,谢谢你


谢谢 hhyh612 ,所有迷惑解了。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

20
 
引用 15 楼 gooogleman 的回复:
引用 14 楼 wohuazhen 的回复:
难道编译器编译出来的东西也有物理地址和虚拟地址之分的?
我认为ldr r0, =PhysicalStart中的PhysicalStart,编译器给的是物理地址,但是当在打开MMU后,这段代码加载到cpu解释过程中会被处理器转换成虚拟地址。


不是啊,这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址,由于,这个代码已经在MMU打开的时候跑到内存运行了,所以我们要手动把它变回物理地…

关于程序相关标号,昨下班回去我查看了《ARM系列处理器应用完全技术手册》一书,它的解释,这种标号在汇编时被处理成PC值加上或减去一个数字常量。我想这是为什么“这个标号所标识的地址在MMU打开的时候是是标识虚拟地址,当关闭MMU它就是物理地址”的原因了。
另外“2条指令内是因为ARM流水线的原因”合理的解释,学习了。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表