(转)Wince读核1-启动流程2

3. 从KernelStart开始2
KernelStart()函数代码如下。
      LEAF_ENTRY KernelStart
      ;我们现在跑在物理地址下;
     ;如前所述,r0在之前已经保存了MemoryMap的物理地址。
        mov     r11, r0                         ; (r11) = &MemoryMap (save pointer)

        ; figure out the virtual address of OEMAddressTable
        ;将MemoryMap的物理地址转换成虚拟地址,保存在r6中,以后会经常用的。
        mov     r1, r11                         ; (r1) = &MemoryMap (2nd argument to VaFromPa)
        bl      VaFromPa
        mov     r6, r0                          ; (r6) = VA of MemoryMap

        ; convert base of PTs to Physical address
        ;注意这里,=PTs居然是一个虚拟地址。现在不是跑在物理地址下吗?为什么=PTs居然返回虚拟地址?
        ;答案在在config.bib里。这个文件会有一行说明eboot(也有可能是msipl)加载内核nk的地址,注意这个地址是虚拟地址,例如
        ;NK       80300000 00200000 RAMIMAGE
        ;nk.nb0的开始部分是以0x80000000为基址链接过的内核文件nk.exe。也就是说此时所有的lable返回的都是虚拟地址。
        ;换句话说,现在是在物理地址下跑虚拟地址的映像,这时只要访问的是相对地址而不是绝对地址,是不会跑飞的。
        ;下面代码将FirstPT的物理地址保存在r10中,以后会用到。
        ldr     r4, =PTs                        ; (r4) = virtual address of FirstPT
        mov     r0, r4                          ; (r0) = virtual address of FirstPT
        mov     r1, r11                         ; (r1) = &MemoryMap (2nd argument to PaFromVa)
        bl      PaFromVa

        mov     r10, r0                         ; (r10) = ptr to FirstPT (physical)
这里有必要说一下ce内核的高地址虚拟空间(0x0xFFFD0000到0x0xFFFD0000)的使用。在armtrap.s文件的开头,我们会看到下面几行。
    ; High memory layout:
     ;       FFFD0000 - first level page table (uncached)
     ;       FFFD4000 - not used
     ;       FFFE0000 - disabled for protection
     ;       FFFF0000 - exception vectors
     ;       FFFF03E0 - exception vector jump table
     ;       FFFF0400 - not used (r/o)
     ;       FFFF1000 - disabled for protection
     ;       FFFF2000 - r/o (physical overlaps with vectors)
     ;       FFFF2400 - Interrupt stack (1k)
     ;       FFFF2800 - r/o (physical overlaps with Abort stack)
     ;       FFFF3000 - disabled for protection
     ;       FFFF4000 - r/o (physical memory overlaps with vectors & intr. stack & FIQ stack)
     ;       FFFF4900 - Abort stack (2k - 256 bytes)
     ;       FFFF5000 - disabled for protection
     ;       FFFF6000 - r/o (physical memory overlaps with vectors & intr. stack)
     ;       FFFF6800 - FIQ stack (256 bytes)
     ;       FFFF6900 - r/o (physical memory overlaps with Abort stack)
     ;       FFFF7000 - disabled
     ;       FFFFC000 - kernel stack
     ;       FFFFC800 - KDataStruct
     ;       FFFFCC00 - r/o for protection (2nd level page table for 0xFFF00000)
    
            ^ 0xFFFD0000
     FirstPT         # 0x4000
                    # 0x4000
                    # 0x8000
                    # 0x10000       ; not mapped
     ExVector        # 0x1000
                    # 0x1400        ; not mapped
                    # 0x0400        ; 1K interrupt stack
     IntStack        # 0x2000        ; not mapped                    (ffff2800)
                    # 0x0100        ; not mapped (FIQ stack)        (ffff4800)
                    # 0x0700        ; 2K-256 abort stack            (ffff4900)
     AbortStack      # 0x1800        ; not mapped                    (ffff5000)
                    # 0x0100        ; not mapped (FIQ stack)        (ffff6800)
     FIQStack        # 0xC000-0x6900 ; not mapped                    (ffff6900)
     KDBase          # 0x07E0        ; 2K-32 kernel stack
     KStack          # 0x0020        ; temporary register save area
     KData           # 0x400         ; kernel data area
    
    
            ;-----------------------------------------------------------------------
            ; .KDATA area is used to reserve physical memory for the above structures.
            AREA |.KDATA|,DATA,NOINIT
           
            EXPORT ExceptionVectors
           
     KDataArea
     PTs     %       0x4000          ; space for first-level page table
     ExceptionVectors
            %       0x0400          ; space for exception vectors
            %       0x0400          ; space for interrupt stack
            %       0x0100          ; space for FIQ stack
            %       0x0700          ; space for Abort stack
     KPage   %       0x0c00          ; space for kernel stack & KDataStruct
     HighPT %       0x0400          ; space for 2nd level page table to map 0xFFF00000
     KDEnd   %       0
这段代码分为三个部分。第一部分是注释,详细解释了第二部分的内容。第二部分以0xFFFD0000为起始地址定义了一个数据结构(关于^和%等的含义参考文档1),可以通过将这个数据结构的每一项和注释对应起来了解其字面意思,具体含义以后会解释。第三部分分配了一块物理内存,来实现对上述数据结构的物理存储。在这里有两点要注意:第一是,该物理内存并没有和第二部分的数据结构对应起来。这是因为第二部分的数据结构中间有很多没有使用的"空洞",如果物理内存也要分配空间给这些"空洞"那就太浪费了。所以只需要给有意义的部分分配物理内存,在进行虚拟地址到物理地址映射的时候给虚拟地址最大小适合的page,通过在代码访问超出这个page大小的时候发生异常,同时在访问这些虚拟地址的时候谨慎的检查,来确保不会访问到"空洞"的虚拟地址;第二是从现在开始要注意源代码给出的关于PTs和FirstPT的使用和注释,之间有微妙的区别,这些都会在下面结合代码加以解释。

 

http://hi.baidu.com/garnetttt/blog/item/819ca7862d58ee3d67096ec3.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值