找回密码
 注册
搜索
查看: 7201|回复: 36

[讨论] windows mobile 学习日志

[复制链接]
发表于 2008-7-2 20:41:26 | 显示全部楼层 |阅读模式
提示: 该帖被管理员或版主屏蔽
 楼主| 发表于 2008-7-4 22:29:15 | 显示全部楼层

开发环境

安装mobile 是学习的开始,也可是说是整个过程的最简单的部分。不过没有朋友的指点。
一开始还真有点手忙脚乱的。

    安装的过程分为两步,第一步先装AK ,接下来安装AKU。和装通常的开发工具没有什么
区别,只有一点小的细节需要注意,首先你的操作系统最好是XP的,然后你最好为你的mobile
开发工具准备20G的空间。还有就是安装的时间比较长,要有点耐心。呵呵如果前面两条没注意
那耐心还要多一点,原因吗?很简单是你要多装两次了。不过mobile 还好了,如果你碰到NXP的
平台,如果你装的不顺,那才叫郁闷啦
   
  废话少说,装好平台就开始一个工程吧,现看看怎么创建工程吧。先选择New Build Window wizard
菜单。在哪?不就在开始菜单->程序—>microsoft platform bulider for window moblie 下吗?
这么简单还要我说。选择你的工程目录再next 后到Cofingure Build windows parameters 界面,
选择你的BSP(如果你暂时还没有,就选择 DeviceEmulator),Release Tye (现选择Retail 吧)
和语言,显示尺寸。然后next再确认下就OK了。
  
  最后开始编译刚才创建的工程,开始菜单选择运行,再敲CMD 命令,到命令行提示窗口.进入你的工程
目录进入BuildScripts 目录,这个目录里放的是你创建工程编译的批处理文件,一个工程一个目录。
在这个目录选择你刚才创建的目录,进去执行BuildAll.bat 批处理,下面的工作就是开始等待编译结果。
呵呵,慢慢等吧。[br]<p align=right><font color=red>+5 RD币</font></p>
点评回复

使用道具 举报

发表于 2008-7-9 16:26:35 | 显示全部楼层
写的不错,顶一下
点评回复

使用道具 举报

 楼主| 发表于 2008-7-9 20:45:02 | 显示全部楼层
BSP 移植是mobile 开发的主要工作,了解下BSP的目录结构的同时也了解了
我们大致要做的工作。
  我们要做的工作的代码主要放在platform 这个目录里,在这里存放各个BSP
,每个BSP一个目录,我的目录名称叫做B1 ,没有特别的含义,自己随便起的
但这个应该不是一个好的编程习惯,在实际的工作中应该避免。进入B1 目录,
当然发现几个目录和文件,挑几个自己认为重要的说吧。

      dirs 文件,这个文件记录了需要参加编译的子目录,打开b1 下的dirs
文件,在最后会发现DIRS=src 这句话,表示编译的子目录只有一个src .对啦
source 啊。
      赶快进去吧,又发现一个dirs 文件,打开后发现DIRS=common                                                           drivers                                                          apps                                                             kernel                                                           bootloader
一看就清楚了,参见编译的是common ,driver ,apps ,kernel ,bootloader目录
我们最主要关心的就是 driver,kernel,bootloader 。从哪开始,bootloader吧。
点评回复

使用道具 举报

发表于 2008-7-10 13:43:39 | 显示全部楼层
不错不错,期待后续……
点评回复

使用道具 举报

发表于 2008-7-13 16:09:32 | 显示全部楼层
期待有续集。。。。。。。。。。[em04]
点评回复

使用道具 举报

 楼主| 发表于 2008-7-16 09:19:59 | 显示全部楼层
bootloader 是什么呀?它是操作系统内核运用之前的一段小程序
通过这段小程序,可以初始化硬件设备,建立操作系统的内存空间影
射图,从而将系统的软硬件环境带到一个已经确定的状态,然后将操
作系统的内核加载的RAM中,并将系统的控制权交给内核。
   进入bootloader 目录,打开bootloader 目录下的dirs 文件了解
到bootloader目录中 参加编译的子目录为DHCP,IPL 和EBOOT。其中
DHCP实现的是TCP/IP 的协议的DHCP 协议。暂时不先不考虑移植。
    IPL目录主要实现的是IPL 功能。呵呵有点费话,谁不知道啊。
但IPL功能是什么啦?IPL是Initial Program Loader 的英文缩写。主
要功能是负责操作系统镜像的下载!
    EBOOT 吗,从单词的名字来看,就是boot啦!用来初始化硬件和软件
的基本环境,为系统的引导作准备,和它功能相似的大概有uboot程序。你
可以通过eboot 来下载程序,这个在开发中非常方便。如果在指定时间没
有选择下载,EBOOT 可以通过IPL正常启动操作系统内核。系统开机的流程
大致是开机->芯片内部boot ROM->Eboot->IPL_OS呵呵,这就是bootloader
目录的大致情况,当然它的功能远远超过上面所述。不过这只是开始,就
先这样大概看一下吧。老猪又吃了遍人参果啊!
   在正式的移植前,我们先build 下吧,确认当前的代码没问题。在保存
一个备份,这个是开发一个新系统的基本步骤。再buildAll,呵呵,受不了
啊!一两个小时啦。好在mobile有简便的方法。还是先进控制台模式,进入
工程目录下的BuildScripts。再进入自己的工程目录,这次不要BuildALl,了
运行下BaseOSEnv.bat 吧。这个时候编译环境变量已经设置好了。并且退到
工程模式的根目录下了,进入今天想编译的目录\platform\b1\src\bootloader
然后敲入build 命令。啊,这下编译快多了。
点评回复

使用道具 举报

 楼主| 发表于 2008-7-16 15:56:53 | 显示全部楼层
既然系统开机的流程是硬件开机->eboot-> IPL->OS 的内核,那么移植的工作就从eboot 开始吧。
进入eboot 的目录。里面就是EBOOT的源文件了,有些.c 文件和.S 文件。.C 文件是C 语言的源文
件,.S 是ARM 的汇编文件。
    这边还有个比较特殊文件,需要简单的开一下-source 文件。在前面已经了解到DIRS 文件,这个
文件记录的是一个目录下参加编译的子目录。而source 文件就是记录该目录下参加编译的源文件。
    打开eboot 下的source , 发现SOURCES=                                startup.s                                  util.s                                     main.c                                     debug.c                                    ether.c                                    flash.c                                    bitmap.c                                   nand.c
这些就是参加编译的源文件。根据名称就能够看出来startup.s 就是开机最初调用的开始的ARM汇编。
和大多数ARM 程序文件一样,这个文件完成基本的硬件初始化后,将通过一条跳转指令跳到main函数
中。main 函数中主要调用BootloaderMain 函数。这个函数又会调用OEMDebugInit ,OEMPlatformInit
OEMPreDownload 和OEMLauch函数。EBoot 的移植工作大致就是对这些函数实现吧。一个有趣的现象需要
移植的函数的开头都有OEM ,明白了吧需要OEM 实现的啊!
点评回复

使用道具 举报

 楼主| 发表于 2008-7-17 18:42:31 | 显示全部楼层
startup.s 是代码的开始,这段是用ARM 汇编编写的。哎,这段是比较头大的,毕竟ARM 汇编不熟悉啊
不过没办法,躲是躲不掉的。startup.s 的主要功能有哪些啦,大家都知道是初始化基本的硬件。但具体由
哪些啦。
   让我们先看下mobile 的示例代码吧,找到LEAF_ENTRY 这个宏定义,这个是程序的开始,但是通常的ARM
的开始是ENTRY。 LEAF_ENTRY 是通过网上的提示在MSDN中查到的,This macro declares the beginning of
a routine that does not require any prolog code。 Remarks: A LEAF_ENTRY must have an associated
ENTRY_END.总之这就是开始,上来第一条语句就是条ARM 跳转指令 b     ResetHandler.这表示跳转到 ResetH
andler 处去执行。
   ARM 的跳转指令有4条。B BL BLX BX,其中 B 就是简单的跳转,BL 是在跳转的同时将 当前PC的值保存到
R14 寄存器中。BX 的作用是跳转的同时做状态切换,就是在Thumb 和ARM状态切换。BLX 是在跳转的的同时将
当前PC内容保存到R14 中,并进行状态转换,将工作状态由ARM切换到Thumb状态。
   下面一段语句是 ; Make sure that TLB & cache are consistent
                 mov     r0, #0
                 mcr     p15, 0, r0, c8, c7, 0           ; flush both TLB
                 mcr     p15, 0, r0, c7, c5, 0           ; invalidate instruction cache
                 mcr     p15, 0, r0, c7, c6, 0           ; invalidate data cache
   根据注释了解到这段代码的意思是保持TLB 和cache 数据的一致。 什么是TLB 啦?TLB:Translation lookaside
buffer 及旁路转化缓存或者说是页表缓存吧。再来分析下指令mov 这个是ARM 的 一条转移指令,表示叫立即数0
放到r0 寄存器中。mcr 也是arm 的一条转移指令。它的基本格式是mcr 协处理器编码 协处理操作码1  源寄存器
目的寄存器1 目的寄存器2 协处理器操作码2 。表示将源寄存器的值放到协处理器的目的寄存器中。而两个操作码
就是要协处理器进行的操作。 mcr     p15, 0, r0, c8, c7, 0  就是把r0 的值放到P15 的C8 和C7 寄存器中,并
要求P15 作 0 0 两个操作码的操作。
点评回复

使用道具 举报

发表于 2008-7-18 09:24:36 | 显示全部楼层
楼主学学可以,但不要太认真了,现在智能手机市场不好。
点评回复

使用道具 举报

 楼主| 发表于 2008-7-18 17:31:34 | 显示全部楼层
接下来的语句就是        
        ldr     r0, = GPFCON
        ldr     r1, = 0x55aa      
        str     r1, [r0]
ldr 是 ARM 中的地址转移指令。它的作用是数据从内存某个地址的数据读到寄存器中。
如ldr r0, 0x12345678  表示将地址为0x12345678 的内存的值放到r0 寄存器中。另外
ldr 也可以将立即数放到寄存器中,如ldr r0,=1 表示将1 放到r0 寄存其中。ldr 和
mov 的功能相似。和mov 的区别就是mov 只能在寄存器或者立即数之间操作,不能对内
存进行操作。str 在ARM 指令中,是ldr 的逆操作,表示将寄存器的值放到指定的内存
地址空间。str r1,[r0] 就是将r0 寄存器中的值作为内存的地址,将r1 的值放到 r0
寄存器保存值的地址上,呵呵间接寻址啦,话说得够啰嗦吧!上面三句话的意思 就是将
GPFCON 地址上的值赋为0x55aa.GPFCON 定义在s3c2410.inc 中,是2410 的GPIOF的控制
寄存器。
     下面这些语句如下,主要禁止了watch dog 配置了中断,以及clock ,ARM 语法和前
面是一样的
        ldr     r0, = WTCON                     ; disable watch dog
        ldr     r1, = 0x0         
        str     r1, [r0]

        ldr     r0, = INTMSK
        ldr     r1, = 0xffffffff                ; disable all interrupts
        str     r1, [r0]

        ldr     r0, = INTSUBMSK
        ldr     r1, = 0x7ff                     ; disable all sub interrupt
        str     r1, [r0]

        ldr     r0, = INTMOD
        mov     r1, #0x0                        ; set all interrupt as IRQ
        str     r1, [r0]

        ldr     r0, = CLKDIVN
        ldr     r1, = 0x3                       ; 0x0 = 1:1:1,  0x1 = 1:1:2
                                                ; 0x2 = 1:2:2,  0x3 = 1:2:4,
                                                ; 0x8 = 1:4:4
        str     r1, [r0]
点评回复

使用道具 举报

发表于 2008-7-18 22:55:39 | 显示全部楼层
支持楼主,我也是做wm手机开发的
不同意十楼的说法,智能手机市场不好只是暂时的,随着3g的展开以及手机电视国标的确定,三网合一的趋势已经势不可挡,而智能手机将是三网合并后的最佳终端。
楼主加油!!顶!顶!顶!
点评回复

使用道具 举报

 楼主| 发表于 2008-7-20 10:39:46 | 显示全部楼层
下面这两条语句是
            ands    r1, r1, #0x2                    ; set AsyncBusMode
            beq     %F10

    第一条语句是and 指令,加了s 表示影响标记位。 ands r1, r1,#0x2 表示
将r1 的值和立即数#0x2 作逻辑与操作,并将根据运算结果更新标志N和Z。
    beq 是条件执行跳转,几乎所有的ARM 指令均可包含一个可选的条件码,只有
在CPSR中的条件码满足指定条件时,带条件码的指令才会执行,eq 是ARM 的条件码,
它执行的条件是Z置位。在这里只有r1寄存器的值等于0x2的时候才会执行跳转指令,
跳转到标号为10 的代码处。
    其实这段代码我不是十分明白,有两个疑问。一是前面执行的语句
        ldr     r0, = CLKDIVN
        ldr     r1, = 0x3                       ; 0x0 = 1:1:1,  0x1 = 1:1:2
                                                ; 0x2 = 1:2:2,  0x3 = 1:2:4,
                                                ; 0x8 = 1:4:4
        str     r1, [r0]
    这个时候已经将r1 的值赋为0x3 ,下面紧接着在ands r1,r1,#0x2 ,beq %F10 。这样不
是因为3 不等于2 。永远不会执行跳转指令吗?

     第二个疑问是beq %F10 ,这个%F 表示什么意思,我个人的理解是10 标号在现在这段代码
的前面。就是向前找标号10 。但是没找到资料确认。

    希望网上的高人能帮我看一下啊。哎,郁闷啦! 真是书到用时方恨少啊。
点评回复

使用道具 举报

 楼主| 发表于 2008-7-21 15:31:29 | 显示全部楼层
mrc     p15, 0, r0, c1, c0, 0
      orr     r0, r0, #R1_nF:OR:R1_iA
      mcr     p15, 0, r0, c1, c0, 0
这段代码是对协处理器P15 进行操作。Orr是ARM 汇编中的或操作。
mrc 是以前学过的mcr的逆操作。
       ldr     r0, = LOCKTIME                  ; To reduce PLL lock time, adjust the LOCKTIME register.
       ldr     r1, = 0xffffff
       str     r1, [r0]
   
       ldr     r0, = MPLLCON                   ; Configure MPLL
                                                ; Fin=12MHz, Fout=50MHz
       ldr     r1, = PLLVAL
       str     r1, [r0]

        ldr     r0, = UPLLCON                   ; Fin=12MHz, Fout=48MHz
        ldr     r1, = ((0x48 << 12) + (0x3 << 4) + 0x2)  
        str     r1, [r0]
这些代码根据前面学的,就比较好理解了是对PLL 等控制器的初始化。
         
      
        mov     r0, #0x2000
20   
        subs    r0, r0, #1
        bne     %B20
这段代码我个人认为是一段等待语句,就是先将r0 =0x2000 然后每次减1,直到等于 0 为止。
sub 是ARM汇编中的减法指令。加了S 就会影响标志位啦。ne 和eq 一样也是ARM的条件码,它的
执行条件是Z清0 ,含义就是不等。
点评回复

使用道具 举报

 楼主| 发表于 2008-7-22 16:09:24 | 显示全部楼层
下面这段语句是这样的



        ldr     r1, =GSTATUS2                   ; Determine Booting Mode
        ldr     r10, [r1]
        tst     r10, #0x2
        beq     %F30                            ; if not wakeup from PowerOffmode
                                                ;    skip MISCCR setting
      
      GSTATUS2 定义在s3c2410.inc 中,它的地址为0x560000B4,查下2410的DATASheet,得知这个是
一个reset 状态寄存器,根据这个寄存器的值,可以了解到2410 是在什么状态时reset ,如果是在power_on
状态下reset , GSTATUS2 寄存器的第一位(PWRST位)被置为1 ,如果是在power off 状态下reset 的,
GSTATUS2 寄存器的第二位(OFFRST)位将被置为1 。如果是由于watchdog 而reset 的,GSTATUS2 寄存器的
第三位将被置1。tst 是ARM 汇编中的测试指令,对置位操作的影响相当于ANDS,和ANDS的区别是它不保存计算
结果,仅仅影响标志位。上面这段代码是用来判断是否是在poweroff 模式下启动的,如果不是就跳过下面这段
代码。

        ldr     r1, =MISCCR                     ; MISCCR's Bit 17, 18, 19 -> 0
        ldr     r0, [r1]                          
        bic     r0, r0, #(7 << 17)               ; SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
        str     r0, [r1]
30
      
   MISCCR 是2410 的MISCELLANEOUS CONTROL REGIDTER,怎么翻译,我还不十分清楚,好在网上的高手比较多
希望能够得到指点。这个寄存器的17 18 19 位在系统进入poweroff 模式的时候,被设为了1 用来保护SDRAM 。
所以如果实在poweroff 模式下reset .需要把它们设回0 。上面这段代码就是这个意思。至于bic 是ARM 中的位
清0 指令。基本格式 bic rd ,rn operand ,bic 将rn 中的位与operand 的值中相应的位的反码进行与操作。以
达到位清零。
点评回复

使用道具 举报

发表于 2008-8-4 18:35:02 | 显示全部楼层
[em02]
点评回复

使用道具 举报

 楼主| 发表于 2008-8-9 09:36:35 | 显示全部楼层
奥运会开幕啦,前段时间工作上比较忙,没有闲下来学习,今天终于能够有点时间了
抓紧时间学点吧,马上还要看奥运会啦。下面这段代码是初始化内存控制器的
        add     r0, pc, #MEMCTRLTAB - (. + 8)
        ldr     r1, = BWSCON                    ; BWSCON Address
        add     r2, r0, #52                     ; End address of MEMCTRLTAB
40      ldr     r3, [r0], #4   
        str     r3, [r1], #4   
        cmp     r2, r0      
        bne     %B40
  先看看  BWSCON 是什么意思吧,2410 有一组内存控制器.它们是由BANKCON0地址开始的,这段
程序的主要目的就是对这组内存控制器进行初始化. 这段内存的初始化的值就定义在MEMCTRLTAB
里.
     MEMCTRLTAB DATA
        DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
        DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))   ; BANKCON0
        DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   ; BANKCON1
        DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   ; BANKCON2
        DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   ; BANKCON3
        DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   ; BANKCON4
        DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   ; BANKCON5
        DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))                                                        ; BANKCON6
        DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))                                                        ; BANKCON7
        DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)                            ; REFRESH
        DCD 0xB2                                                                                        ; BANKSIZE
        DCD 0x30                                                                                        ; MRSRB6
        DCD 0x30                                                                                        ; MRSRB7

        END
   
看看这个就明白啦,主要看哪边?看注释啦,BANKCON0 ,BANKCON1 等寄存器的值是不是定义好啦.
     
     明白后继续
           tst     r10, #0x2
           beq     BringUpWinCE                    ; Normal Mode Booting

      通过前面的代码明白r10保存的是GSTATUS2寄存器的地址,这段代码判断是否是正常启动模式,如果是就跳过下面
这段代码。哪段?明天再看吧,奥运比赛开始了,我等不及了,哎!知道我为什么不能成为高手了。
点评回复

使用道具 举报

 楼主| 发表于 2008-8-10 09:16:02 | 显示全部楼层
东风吹,战鼓擂,当今世道谁怕谁,不是人民怕美帝,而是美帝怕人民
奥运首日两金,厉害阿。那都是人家平时努力的结果啊。
  我也来努力下,看段代码吧。昨天要跳过的代码第一段是这样子的
        ldr     r5, =SLEEPDATA_BASE_PHYSICAL    ; pointer to physical address of reserved Sleep mode info data structure
        mov     r3, r5                          ; pointer for checksum calculation
        mov     r2, #0
        ldr     r0, =SLEEPDATA_SIZE             ; get size of data structure to do checksum on
50      ldr     r1, [r3], #4                    ; pointer to SLEEPDATA
        and     r1, r1, #0x1
        mov     r1, r1, LSL #31
        orr     r1, r1, r1, LSR #1
        add     r2, r2, r1
        subs    r0, r0, #1                      ; dec the count
        bne     %b50                            ; loop till done   

        ldr     r0,=GSTATUS3
        ldr     r3, [r0]                        ; get the Sleep data checksum from the Power Manager Scratch pad register
        teq     r2, r3                          ; compare to what we saved before going to sleep
        bne     BringUpWinCE                    ; bad news - do a cold boot

这段代码的主要目的是判断是否正常开机,否则就要做初始化MMU的一些工作。GSTATUS3 是2410 的一个用来保存信息的寄存器。这个寄存器的
特殊之处在与,它在power off 的时候仍然能够保存信息。判断是否正常开机的原理就简单了,关机时,将特定信息保存到GSTATUS3寄存器中,
开机后比一下啦。确定是否执行以下代码
      ;   2. MMU Enable

        ldr     r10, [r5, #SleepState_MMUDOMAIN] ; load the MMU domain access info
        ldr     r9,  [r5, #SleepState_MMUTTB]    ; load the MMU TTB info
        ldr     r8,  [r5, #SleepState_MMUCTL]    ; load the MMU control info
        ldr     r7,  [r5, #SleepState_WakeAddr ] ; load the LR address
        nop         
        nop
        nop
        nop
        nop
   
    这段代码也是比较清楚的,就是使能MMU。
  再然后判断是否是软启动,是的话就作恢复的工作。代码就是下面这段
      mov     r1, #0
        teq     r1, r7
        bne     %f60
        bl      BringUpWinCE

; wakeup routine
60      mcr     p15, 0, r10, c3, c0, 0          ; setup access to domain 0
        mcr     p15, 0, r9,  c2, c0, 0          ; PT address
        mcr     p15, 0, r0,  c8, c7, 0          ; flush I+D TLBs
        mcr     p15, 0, r8,  c1, c0, 0          ; restore MMU control

;   3. Jump to Kernel Image's fw.s (Awake_address)

        mov     pc, r7                          ;  jump to new VA (back up Power management stack)
        nop
点评回复

使用道具 举报

发表于 2008-8-11 13:39:21 | 显示全部楼层
加油楼主[em06][em06]
点评回复

使用道具 举报

 楼主| 发表于 2008-8-11 16:17:13 | 显示全部楼层
所有的前面代码最终都会调到这边
       BringUpWinCE
        ldr     r0, = GPFDAT
        mov     r1, #0x60
        str     r1, [r0]
    顾名思义,现在需要装在wince 了,bring up  查了下金山词霸,就是教育,培养 ,达到目的的意思。
    呵呵,教育和达到目的是一个意思。GPFDAT 是2410 的port 7 的数据寄存器。这边首先对他做了个初始化。
        ands    r9, pc, #0xFF000000     ; see if we are in flash or in ram
        bne     %f20                    ; go ahead if we are already in ram
        
    通过判断当前PC 的地址范围,确定当前的代码是在flash 里还是在ram 里,如果在ram里 就不需要将代码从
    Flash 里拷贝到ram 里啦,否则就要做以下代码.
       ldr     r0, = 0x21000           ; offset into the RAM
        add     r0, r0, #PHYBASE        ; add physical base
        mov     r1, r0                  ; (r1) copy destination
        ldr     r2, =0x0                ; (r2) flash started at physical address 0
        ldr     r3, =0x10000            ; counter (0x40000/4)
10      ldr     r4, [r2], #4
        str     r4, [r1], #4
        subs    r3, r3, #1
        bne     %b10
     来装载代码,然后使用 mov pc, r0重起机器。
     如果在RAM 中,就要进行OEMAddressTable 地址表的装载使用下面一长串代码
        add     r10, r10, #0x2000       ; (r10) = ptr to 1st PTE for "unmapped space"
        mov     r0, #0x0E               ; (r0) = PTE for 0: 1MB cachable bufferable
        orr     r0, r0, #0x400          ; set kernel r/w permission
25      mov     r1, r11                 ; (r1) = ptr to MemoryMap array

        
30      ldr     r2, [r1], #4            ; (r2) = virtual address to map Bank at
        ldr     r3, [r1], #4            ; (r3) = physical address to map from
        ldr     r4, [r1], #4            ; (r4) = num MB to map

        cmp     r4, #0                  ; End of table?
        beq     %f40

        ldr     r5, =0x1FF00000
        and     r2, r2, r5              ; VA needs 512MB, 1MB aligned.               

        ldr     r5, =0xFFF00000
        and     r3, r3, r5              ; PA needs 4GB, 1MB aligned.

        add     r2, r10, r2, LSR #18
        add     r0, r0, r3              ; (r0) = PTE for next physical page

35      str     r0, [r2], #4
        add     r0, r0, #0x00100000     ; (r0) = PTE for next physical page
        sub     r4, r4, #1              ; Decrement number of MB left
        cmp     r4, #0
        bne     %b35                    ; Map next MB

        bic     r0, r0, #0xF0000000     ; Clear Section Base Address Field
        bic     r0, r0, #0x0FF00000     ; Clear Section Base Address Field
        b       %b30                    ; Get next element
        
40      tst     r0, #8
        bic     r0, r0, #0x0C           ; clear cachable & bufferable bits in PTE
        add     r10, r10, #0x0800       ; (r10) = ptr to 1st PTE for "unmapped uncached space"
        bne     %b25                    ; go setup PTEs for uncached space
        sub     r10, r10, #0x3000       ; (r10) = restore address of 1st level page table

        ; Setup mmu to map (VA == 0) to (PA == 0x30000000).
        ldr     r0, =PTs                ; PTE entry for VA = 0
        ldr     r1, =0x3000040E         ; uncache/unbuffer/rw, PA base == 0x30000000
        str     r1, [r0]

        ; uncached area.
        add     r0, r0, #0x0800         ; PTE entry for VA = 0x0200.0000 , uncached     
        ldr     r1, =0x30000402         ; uncache/unbuffer/rw, base == 0x30000000
        str     r1, [r0]
        
        ; Comment:
        ; The following loop is to direct map RAM VA == PA. i.e.
        ;   VA == 0x30XXXXXX => PA == 0x30XXXXXX for S3C2400
        ; Fill in 8 entries to have a direct mapping for DRAM
        ;
        ldr     r10, =PTs               ; restore address of 1st level page table
        ldr     r0,  =PHYBASE

        add     r10, r10, #(0x3000 / 4) ; (r10) = ptr to 1st PTE for 0x30000000

        add     r0, r0, #0x1E           ; 1MB cachable bufferable
        orr     r0, r0, #0x400          ; set kernel r/w permission
        mov     r1, #0
        mov     r3, #64
45      mov     r2, r1                  ; (r2) = virtual address to map Bank at
        cmp     r2, #0x20000000:SHR:BANK_SHIFT
        add     r2, r10, r2, LSL #BANK_SHIFT-18
        strlo   r0, [r2]
        add     r0, r0, #0x00100000     ; (r0) = PTE for next physical page
        subs    r3, r3, #1
        add     r1, r1, #1
        bgt     %b45

        ldr     r10, =PTs               ; (r10) = restore address of 1st level page table
         
    再打开MMU
       ; Initialize the MMU and turn it on.
        mov     r1, #1
        mcr     p15, 0, r1, c3, c0, 0   ; setup access to domain 0
        mcr     p15, 0, r10, c2, c0, 0

        mcr     p15, 0, r0, c8, c7, 0   ; flush I+D TLBs
        mov     r1, #0x0071             ; Enable: MMU
        orr     r1, r1, #0x0004         ; Enable the cache

        ldr     r0, =VirtualStart

        cmp     r0, #0                  ; make sure no stall on "mov pc,r0" below
        mcr     p15, 0, r1, c1, c0, 0
        mov     pc, r0                  ;  & jump to new virtual address
        nop

        ; MMU & caches now enabled.
        ;   (r10) = physcial address of 1st level page table
        ;
    最后设置下栈指针,跳至main 函数
VirtualStart

        mov     sp, #0x80000000
        add     sp, sp, #0x65000        ; arbitrary initial super-page stack pointer
        b       main
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-5-6 13:37 , Processed in 0.055238 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表