搜索
bottom↓
回复: 579

学ARM已经41天了,中间断断续续总有点收获,今天把我写的启动代码贴上来,注释很详细,希望

  [复制链接]

出0入0汤圆

发表于 2009-5-12 13:59:33 | 显示全部楼层 |阅读模式
启动代码是几乎是每个arm程序程序必备的,刚开始看的时候看别人的启动代码时感觉云里雾里,所以懒惰的想法浮现脑中:别人都写好了我还写什么,直接拿来用不就行了,对在我懂得情况下,我一定会拿来就用,但是现在我还不懂,一切就要从头开始,经过几天的努力,现在的感觉是启动代码不过如此 :) ,呵呵。





;---------------------------------------------------------------------
;startup.s
;系统启动代码
;起始时间        :        2009.5.7 ----->2009.5.11
;---------------------------------------------------------------------



;---------------------------------------------------------------------
        GET                ./Include/s3c2440.inc        ;寄存器地址信息
        GET                ./Include/memcfg.inc        ;内存控制器配置信息
       
;处理器模式
USERMODE                EQU         0x10
FIQMODE                        EQU         0x11
IRQMODE                        EQU         0x12
SVCMODE                        EQU         0x13
ABORTMODE                EQU         0x17
UNDEFMODE                EQU         0x1b
SYSMODE                        EQU                0x1f
;相关掩码
MODEMASK            EQU         0x1f
NOINT                        EQU         0xc0

;各个处理器模式下堆栈设置
_STACK_BASEADDRESS        EQU        0x33ff8000                ;BANK6 64MB顶部
UserStack                EQU        (_STACK_BASEADDRESS-0x3800)        ;0x33ff4800 ~
SVCStack                EQU        (_STACK_BASEADDRESS-0x2800)        ;0x33ff5800 ~
UndefStack                EQU        (_STACK_BASEADDRESS-0x2400)        ;0x33ff5c00 ~
AbortStack                EQU        (_STACK_BASEADDRESS-0x2000)        ;0x33ff6000 ~
IRQStack                EQU        (_STACK_BASEADDRESS-0x1000)        ;0x33ff7000 ~
FIQStack                EQU        (_STACK_BASEADDRESS-0x0)        ;0x33ff8000 ~

;导入操作系统入口函数
        IMPORT        OSEntry
       
;导入外部C语言编写的异常与中断处理函数
        IMPORT        vectorUNDEF
        IMPORT        vectorSWI
        IMPORT        vectorPABT
        IMPORT        vectorDABT
        IMPORT        vectorIRQ
        IMPORT        vectorFIQ

;导入镜像装载域段起始地址
        IMPORT  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
        IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
        IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
        IMPORT  |Image$$ZI$$Limit|  ; to zero initialise
;--------------------------------------------------------------------


;------------------------------------------------------
        AREA startup, CODE, READONLY
       
        ENTRY

;系统向量表

         b        vectorRESET        ;复位向量
         b        vectorUNDEF        ;未定义指令
         b        vectorSWI        ;软中断
         b        vectorPABT        ;预取指终止
         b        vectorDABT        ;数据终止
         b        .                        ;系统保留
         b        vectorIRQ        ;外部中断
         b        vectorFIQ        ;快速中断
;-------------------------------------------------------

;--------------------------------------------------------------------------
;复位向量
;复位向量是ARM处理器上电后第一个被执行的异常
;此时系统处理管理(SVC)模式

vectorRESET       

;复位向量有以下六件事要做

;第一步        : 关闭看门狗定时器屏蔽所有中断
;第二步 : 配置系统时钟
;第三步        : 配置内存控制器
;第四步        : 配置每种处理器模式下堆栈指针
;第五步        : 初始化镜像运行域
;第六步        : 跳转到操作系统入口


        ;------------------------------------------
        ;第一步        : 关闭看门狗定时器
        ;具体内容请参看s3c2440a数据手册的第18章
                ldr        r0, =WTCON
                ldr         r1, =0x0
                str         r1, [r0, #0x0]
               
        ;屏蔽所有中断
                ldr r0, =INTMSK       
                ldr r1, =0xffffffff       
                str r1, [r0]
        ;------------------------------------------
       
       
       
        ;------------------------------------------
        ;第二步        : 配置系统时钟
        ;具体内容请看手册第7章
       
                ;先减少锁相环锁定时间,s3c2440a要求PLL
                ;锁定时间>300us,在上电时s3c2440a预设值
                ;mpll为晶体频率,我用的晶体频率为12MHz
                ;300us*12M = 3600设置LOCKTIME = 0xfff
                ;足够了
                ldr r0, =LOCKTIME
                ldr r1, =0xfff0fff0        ;高16为对应UPLL
                                                        ;低16为对应MPLL
                str r1, [r0, #0x0]
               
                ;根据器件手册我们还有以下几个事要做
                ;step1.配置UPLL
                ;step2.配置MPLL
                        ;注:手册要求先配置UPLL后MPLL
                        ;        且之间要间隔7NOP
                        ;        详请看手册第7-21.
                ;step3.配置分频系数
               
                        ;step1:
                        ldr r0, =UPLLCON
                        ldr r1, =((56<<12) + (2<<4) + 2)
                        ldr r1, [r0]
                       
                        ;按手册要求插入7个NOP
                        nop
                        nop
                        nop
                        nop
                        nop
                        nop
                        nop
                       
                        ;step2:
                        ldr r0, =MPLLCON
                        ldr r1, =((127<<12) + (2<<4) + 1)
                        ldr r1, [r0]
                       
                        ;step3:
                        ldr r0, =CLKDIVN
                        ldr r1, =((0<<3) + (2 << 2) + 1)
                        ldr r1, [r0]
        ;------------------------------------------
       
       
       
        ;------------------------------------------
        ;第三步        : 配置内存控制器
        ;内存控制内的寄存器器地址是连续分布的
        ;从0x4800_0000 -- 0x4800_0030,所以可以
        ;通过一个循环依次填入各个寄存器的内容
       
                ldr r0, =SMRDATA        ;装入配置值的地址
                ldr r1, =BWSCON                ;装入起始寄存器地址
                add r2, r0, #0x34        ;计算结束地址
               
                ;下面是用于向内存控制器
                ;装入配置信息的循环
0               
                ldr r3, [r0], #4        ;装入配置值到r3,后变址
                str r3, [r1], #4         ;把r3内包含的配置值写入
                                                        ;内存控制器的寄存器
                cmp r2, r0                        ;结束否?
                bne %B0                                ;没结束则继续
        ;------------------------------------------
       
       
       
        ;------------------------------------------
        ;第四步        : 配置每种处理器模式下堆栈指针
        ;方法与原则:
                ;1:        通过CPSR寄存器切换处理器模式
                ;2:        对CPSR的操作方式为 读-修改-写回
                ;3:        绝对不要跳到用户模式,跳过去容易
                ;        回来就难了
                ;4: 切到新处理器模式后要屏蔽IRQ和FIQ
                ;        防止在未设置好堆栈前进入中断处理
                ;        程序,但是在启动代码的最先我们已
                ;        经屏蔽了所有的32个中断源,所以感
                ;        觉是否屏蔽都可以
               
                        ;step1: 先把程序状态寄存器读到r0
                        mrs        r0, cpsr               
                       
                        ;step2: 清除处理器模式位(最前面5位)
                        bic        r0, r0, #MODEMASK
                       
                        ;step3:        设置未定义状态下的堆栈指针
                        orr        r1, r0, #UNDEFMODE|NOINT
                        msr        cpsr_cxsf, r1                ;UndefMode
                        ldr        sp, =UndefStack                ;UndefStack=0x33FF_5C00
                       
                        ;step4: 设置终止状态下的堆栈指针
                        orr        r1, r0, #ABORTMODE|NOINT
                        msr        cpsr_cxsf, r1                ;AbortMode
                        ldr        sp, =AbortStack                ;AbortStack=0x33FF_6000
                       
                        ;step5:        设置中断模式下的堆栈指针
                        orr        r1, r0, #IRQMODE|NOINT
                        msr        cpsr_cxsf, r1                ;IRQMode
                        ldr        sp, =IRQStack                ;IRQStack=0x33FF_7000
                       
                        ;step6:        设置快速中断模式下的堆栈指针
                        orr        r1, r0, #FIQMODE|NOINT
                        msr        cpsr_cxsf, r1                ;FIQMode
                        ldr        sp, =FIQStack                ;FIQStack=0x33FF_8000
                       
                        ;step7: 设置管理模式下的堆栈指针
                        orr        r1, r0, #SVCMODE|NOINT
                        msr        cpsr_cxsf, r1                ;SVCMode
                        ldr        sp, =SVCStack                ;SVCStack=0x33FF_5800
                       
                        ;step8: 因为管理模式与用户模式共用
                        ;                堆栈指针,所以借着系统模式
                        ;                来设置用户模式的堆栈指针
                        orr r1, r0, #SYSMODE|NOINT
                        msr cpsr_cxsf, r1                ;SYSMode
                        ldr sp, =UserStack                ;SVCStack & USERMode=0x33ff4800
                       
                        ;现在处理器处于系统模式
        ;------------------------------------------
                  
                  
                  
        ;------------------------------------------
        ;第五步        : 初始化镜像运行域
        ;复制RW段和ZI段到SDRAM指定地址
       
                LDR     r0, =|Image$$RO$$Limit| ; 装入RO段结束地址
                LDR     r1, =|Image$$RW$$Base|  ; 装入RW段起始地址
                LDR     r3, =|Image$$ZI$$Base|  ; 装入ZI段起始地址
       
               
                ;|Image$$RO$$Limit| == |Image$$RW$$Base| ? 跳过RW段复制 : 复制RW段
                CMP     r0, r1     
                BEQ     %F2
               
                ;复制RW段
1      
                CMP     r1, r3  
                LDRCC   r2, [r0], #4     
                STRCC   r2, [r1], #4
                BCC     %B1
2      
                LDR     r1, =|Image$$ZI$$Limit|
                MOV     r2, #0
               
                ;构造ZI段
3      
                CMP     r3, r1     
                STRCC   r2, [r3], #4
                BCC     %B3
       
        ;------------------------------------------          
       
       
       
        ;------------------------------------------
        ;第六步        : 跳转到操作系统入口
       
                b        OSEntry                ;不要使用main,因为如果使用main
                                                ;ads还会调用_main()初始化RW和ZI
                                                ;段,但是那里的数据和本程序不同
                                               
                b        .
               
        ;------------------------------------------
       
;---------------------------------------------------------------------------



SMRDATA DATA

        ;这里是内存控制器的配置数据
        ;配置数据需要根据你使用的存储器修改
        ;在第三步时会将以下数据写入
        ;内存控制器的相关寄存器中
        ;共13个寄存器的配置值
       
        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))   ;GCS0
        DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   ;GCS1
        DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   ;GCS2
        DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   ;GCS3
        DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   ;GCS4
        DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   ;GCS5
        DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    ;GCS6
        DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    ;GCS7
        DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
        DCD 0x32            ;SCLK power saving mode, BANKSIZE 128M/128M
        DCD 0x30            ;MRSR6 CL=3clk
        DCD 0x30            ;MRSR7 CL=3clk

        ALIGN                ;数据边界对齐
       
        END


我在写一个arm920T的微型OS,主要是想借着写OS的过程学习ARM的底层编程,然后跳到Linux。启动代码是固件的一部分,最经学校要搞个设计,不知OS什么时候能写好,反正搞定后立即发帖。

下边是完整的工程

运行平台:mini2440
启动代码ourdev_444408.rar(文件大小:61K) (原文件名:MicroOS.rar)

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-5-12 14:03:22 | 显示全部楼层
谢谢   记号

出0入0汤圆

发表于 2009-5-12 17:45:14 | 显示全部楼层
我也在学

出0入0汤圆

发表于 2009-5-12 18:08:50 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2009-5-12 19:21:19 | 显示全部楼层
bei ni qiangxian

出0入0汤圆

 楼主| 发表于 2009-5-12 19:56:04 | 显示全部楼层
回【4楼】 kedadiaobing

I am very sorry man 呵呵

出0入0汤圆

发表于 2009-5-12 20:13:09 | 显示全部楼层
谢谢,mark

出0入0汤圆

发表于 2009-5-13 09:58:39 | 显示全部楼层
向你学习ING

出0入0汤圆

发表于 2009-5-13 11:13:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-13 11:15:34 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-5-13 11:20:57 | 显示全部楼层
mark,顺便说下,外部中断不初始化?

出0入0汤圆

发表于 2009-5-13 12:38:11 | 显示全部楼层
请问楼主怎样理解镜像运行域的,比如这段BOOT代码,让其最后跳到MIAN中,在MAIN中再运行一个点灯程序,在ADS的LINK选项中,将|Image$$RO$$Limit| 设为0X0C000000,用JINK仿真程序正常,但是把这个工程的BIN文件下载到FLASH中发现开发板不能启动;
另外;
|Image$$RO$$Limit| 设为0X00000000,下载BIN文件到FLASH中才能启动是为什么?

出0入0汤圆

 楼主| 发表于 2009-5-13 13:22:01 | 显示全部楼层
回【10楼】 deadleon

中断的初始化代码还没写,只是在开始的时候屏蔽了



回【11楼】 henalhs  
镜像文件是对整个程序在SDRAM里存放状态的copy,因为内存中的数据段不是连续的,且有很多数据初始化为零的.所以如果严格按照在内存里的状态保存就会浪费rom空间所以在rom里的镜像状态称为装载状态,在sdram里的镜像状态称为运行状态,初始化镜像运行域就是要把在rom里处于装载状态的镜像文件还原到处于sdram里的运行状态,实现的方法是把RO RW ZI 段copy到编译器设置sdram 地址上去.我也是刚学,这只是我的想法,仅供参考 :)


如果要下载到Flash,只要把|Image$$RO$$Base|设置到0x0就可以了,同时修改下
"第二步 :配置系统时钟 "(程序时钟的配置有点问题),系数在s3c2440手册的7-21页,这段代码是固件的一部分,我正在写从Nand flash引导的代码,现在只能引导 <=4K的程序.

出0入0汤圆

发表于 2009-5-13 13:39:31 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-5-13 20:43:55 | 显示全部楼层
谢谢楼主的讲解,期待楼主基于从Nand flash引导的代码!

出0入4汤圆

发表于 2009-5-13 21:40:25 | 显示全部楼层
值得学习!都没研究过启动代码,就只会用别人做好的模板!

出0入0汤圆

发表于 2009-5-15 21:02:30 | 显示全部楼层
同是新手,不过LZ比我强多了,呵呵
MASK一下。

出0入0汤圆

发表于 2009-5-15 22:10:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-15 22:29:56 | 显示全部楼层
楼主真认真,建议阿莫加酷

出0入0汤圆

发表于 2009-5-17 20:07:03 | 显示全部楼层
发现注释里有点小bug:

  ;第六步        : 跳转到操作系统入口
         
                b        OSEntry                ;不要使用main,因为如果使用main
                                                ;ads还会调用_main()初始化RW和ZI
                                                ;段,但是那里的数据和本程序不同
                                                
                b .

应该是不要写成这样  IMPORT __main
                    .
                    .
                    .
                    b  __main

__main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()函数。

写成               IMPORT main
                    .
                    .
                    .
                    b  main
是可以的。

当然楼主写成OSEntry  没有问题,main只是个符号而已

期待楼主更多的学习资料。

出0入0汤圆

发表于 2009-5-17 20:44:05 | 显示全部楼层
会L19

谢谢指点

有点问题请教如果不使用_main()初始化C库好像也可以调用C库(我只使用了一部分C库),是不是不使用_main()也可以使用C库,_main()到底干什么了,等我改下代码,看看汇编代码再说。

出0入0汤圆

发表于 2009-5-17 20:47:49 | 显示全部楼层
楼上使用同学号回的 :)

出0入0汤圆

发表于 2009-5-17 21:16:17 | 显示全部楼层
楼主这个代码根本不是在SDRAM里运行的

出0入0汤圆

发表于 2009-5-17 22:18:10 | 显示全部楼层
不好意思,我也不清楚调用_main()系统干什么去了,我也是看了别人写的代码注释里这么说
我看友善的光盘里的启动代码也是直接跳到.c文件里的main函数执行了,这个__main()有待验证...

出0入0汤圆

发表于 2009-5-18 23:29:08 | 显示全部楼层
大师,野性的一比!

出0入0汤圆

发表于 2009-5-19 02:20:27 | 显示全部楼层
期待有大大详细说一下__main()的功能。

出0入0汤圆

发表于 2009-5-19 09:02:08 | 显示全部楼层
学习中

出0入0汤圆

发表于 2009-5-19 17:00:30 | 显示全部楼层
mark~

出0入0汤圆

发表于 2009-5-19 21:20:16 | 显示全部楼层
b        OSEntry                ;不要使用main,因为如果使用main
                                                ;ads还会调用_main()初始化RW和ZI
                                                ;段,但是那里的数据和本程序不同
这个B后面要是跳到MAIN话,ADS会根据
|Image$$RO$$Limit|
|Image$$RW$$Base|
算出你程序的代码段地址(也就是程序的运行段)和读写段地址(也就是已初始的变量段)
说白一点,如果你想把程序在FLASH里面运行,这时要把|Image$$RO$$Limit|设为0X00000000(FLASH地址),
                                                 |Image$$RW$$Base| 设为0X0C000000(RAM地址)
                想用UBOOT引导后在RAM运行,这时要把|Image$$RO$$Limit|设为0X0C000000(RAM地址),
                                                  |Image$$RW$$Base| 设为0X0C000000(RAM地址)

这是我这几天的理解,我上面的方法在恒丰的44B0开发板上已验正通过,希望给初学的朋友有点帮助。

出0入0汤圆

 楼主| 发表于 2009-5-20 00:28:57 | 显示全部楼层
回【28楼】 henalhs
谢谢分享学习成果 :)

大家好像都对地址,装载很感兴趣,我也来唠唠:)

我认为之所以要指定镜像的各段的起始位置是因为程序中的标号,函数,变量的位置是在编译时根据镜像运行时(注意)计算出来的,所以镜像的各段的位置设置在哪里就一定要把镜像的各段放在那里,否者程序就会由于地址对不上而跑飞。

但是究竟位置应该设定在哪呢 ?

主要有两种情况:

1。 程序放在Nor里

程序的代码段可知放在Nor里运行,为什么?想想看,你的程序应该不会在运行时动态改变程序的指令吧,也就意味着只会读Nor,cpu(在有内存控制器的时候)读Nor和读RAM除了速度慢其他的没什么区别。
但是对于RW ZI 不只有读还有写,应为没法向写RAM一样的写Nor,所以RW ZI 一定要放到 RAM里(不管是SRAM还是DRAM),只有在那里程序才能写RW ZI

   如何装载?
   编译好的镜像处于一种“压缩”的状态。这么压缩的? 比如镜像运行时 RO从0x0 - 0x10  RW从Ox3000_0000 - 0x3000_0004  ZI 0x3000_0008 - 0x3000_000C 如果直接原样镜像,镜像文件肯定会有很大空隙,且ZI全是零完全没必要镜像下来,只要记住起始 结束地址就行了。所以镜像文件在运行前RO RW ZI 是连载一起的,且RO在最前边

   所以就以上分析装载分两大步
   step1:由bootloader完成
          (1).bootloader直接把整个镜像copy到RAM里,从哪读镜像无所谓,ROM,uart,usb,SD卡,以太,甚至是无线都可以,但是目的位置一定是RO$$Base
          (2).然后PC = Ro$$Base
   step2:由镜像自己干
           上边过后由于Ro段在镜像的最前边且RO的起始位置正好就在Ro$$base所以镜像Ro顺利运行,但是RW ZI还不一定在正确位置上,所以有了启动代码的第五步


2.  程序在Nand上
    这是的区别就是与nor相比想直接读nand都难了,所以这是要想让程序顺利运行就必须把Ro段也搬到RAM里,这时要有两个东西,一个小程序 《4k 在NAND最前边,负责装载,就是bootloader。把正真想完成任务的程序放在后边,上电时小程序最先被自动copy到sram,sram是定位在0x0的,所以bootloader 的 Ro起始地址必须设置在0x0,然后bootloader就和上边的没什么区别了,先把nand里的大程序整个copy到DRAM,然后大程序执行把自己的RW ZI copy 到正确位置,所以大程序的RO$$Base可以是DRAM的地址。







“这个B后面要是跳到MAIN话,ADS会根据
|Image$$RO$$Limit|
|Image$$RW$$Base|
算出你程序的代码段地址(也就是程序的运行段)和读写段地址(也就是已初始的变量段) "

我觉得bootloader完全没必要分析镜像,只要直接copy就行了,只要镜像自己保证自己的Ro在最前边就行了,这是编译器的事,后边的RW zi 镜像自己就搞定了。


”说白一点,如果你想把程序在FLASH里面运行,这时要把|Image$$RO$$Limit|设为0X00000000(FLASH地址),
                                                 |Image$$RW$$Base| 设为0X0C000000(RAM地址) “


这个|Image$$RO$$Limit| =0x0 那Base在哪?没看见ADS可以设置Limit啊.


"想用UBOOT引导后在RAM运行,这时要把|Image$$RO$$Limit|设为0X0C000000(RAM地址),
                                                  |Image$$RW$$Base| 设为0X0C000000(RAM地址)”

在ads里如果只设置 ro$$base 那后边的段是接起来的

  请看

(原文件名:Capture.JPG)

我想自己设置肯定可以,如果开MMU的话具体放在哪应该还是要仔细考虑的。



具体那个_main()干了什么,我现在也没看,大家反汇编看下吧,这几天搞学校的设计,学校给钱,不玩白不玩 :)

出0入0汤圆

发表于 2009-5-20 00:47:49 | 显示全部楼层
mark!!!!
头像被屏蔽

出0入0汤圆

发表于 2009-5-20 04:12:22 | 显示全部楼层
Cool

出0入0汤圆

发表于 2009-5-20 09:23:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-20 20:08:03 | 显示全部楼层
眼泪阿

居然是2440的

先顶下。

出0入0汤圆

发表于 2009-5-20 20:44:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-20 21:41:55 | 显示全部楼层
楼主比我强百倍
我都学三年了
哈哈

出0入0汤圆

发表于 2009-5-20 21:44:23 | 显示全部楼层
谢谢
刚拿到开发板,想研究一下启动代码
好好学习,天天向上!

出0入0汤圆

发表于 2009-5-20 22:30:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-20 23:52:50 | 显示全部楼层
高手啊,学习了

出0入4汤圆

发表于 2009-5-21 00:04:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-21 08:56:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-22 17:09:27 | 显示全部楼层
楼上
你是个MM么
我郑重的要求你上PP
不然我会一直在猜想你到底是GG还是MM
严重影响我的正常工作

出0入0汤圆

发表于 2009-5-22 18:41:30 | 显示全部楼层
标记!,有时间再看,楼主不错夸奖一下!

出0入0汤圆

发表于 2009-5-23 12:11:32 | 显示全部楼层
mark,很详细,楼主费心了!

出0入0汤圆

发表于 2009-5-23 16:00:52 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-5-23 20:13:19 | 显示全部楼层
好,厉害学习一下

出0入0汤圆

发表于 2009-5-26 21:15:12 | 显示全部楼层
注释很详细,去掉了一些无关紧要的部分,很适合学习启动代码!
楼主厉害!

出0入0汤圆

发表于 2009-5-30 21:14:50 | 显示全部楼层
楼上
你是个青蛙吗?
我郑重的要求你上PP
不然我会一直在猜想你到底是青蛙还是MM
严重影响我的正常工作

出0入0汤圆

发表于 2009-6-1 12:15:43 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2009-6-5 18:12:18 | 显示全部楼层
re: 【47楼】 csformat

晕咯,想不到随便灌水都会被人惦记上。
很遗憾,我是永远都变不成王子的青蛙GG。
而且,我想没有哪个MM会喜欢用爬虫做logo吧?嘿嘿

出0入0汤圆

发表于 2009-6-16 10:58:19 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-6-16 18:17:36 | 显示全部楼层
__main 是keil的库入口函数,我感觉主要就是会根据你设置的heap地址给你初始化heap空间。

出0入0汤圆

发表于 2009-6-17 20:20:30 | 显示全部楼层
__main 是一个初始化函数...

编译器里有一大堆的__开头的隐含函数,(可以找找编译器的帮助文档)

需要设置相关内容时,可以重载这些函数进行参数的配置.

比如全局变量赋初值(非零),内存执行函数的加载,及一些系统默认函数等..

B __main;就是先执行这些函数后,再转到main()函运行.


比如以下代码即为重载__函数:

__user_initial_stackheap   
    LDR   R0,=bottom_of_heap
        BX    LR

__rt_div0
        B       __rt_div0

出0入0汤圆

发表于 2009-6-18 12:53:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-6-20 13:29:18 | 显示全部楼层
这么好的资料,真是好!!

出0入0汤圆

发表于 2009-6-24 17:49:31 | 显示全部楼层
mark.

出200入0汤圆

发表于 2009-6-24 23:00:32 | 显示全部楼层
标记一下

等有时间好好看看

出0入0汤圆

发表于 2009-6-25 09:40:48 | 显示全部楼层
标记一下 有时间好好看看

出0入0汤圆

发表于 2009-6-25 11:00:31 | 显示全部楼层
记号。。

出0入0汤圆

发表于 2009-6-25 18:58:29 | 显示全部楼层
cool

出0入0汤圆

发表于 2009-6-26 16:11:32 | 显示全部楼层
初学和好的东西

出0入0汤圆

发表于 2009-6-27 03:18:18 | 显示全部楼层
谢谢楼主的分享

出0入0汤圆

发表于 2009-7-6 16:40:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-7 00:39:58 | 显示全部楼层
好贴!!!!

出0入0汤圆

发表于 2009-7-7 10:34:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-8 17:17:18 | 显示全部楼层
哈哈,终于找到了,感谢楼主!

出0入0汤圆

发表于 2009-7-9 23:02:24 | 显示全部楼层
最近在初学AT91RM9200,,,向楼主学习!!!

出0入0汤圆

发表于 2009-7-14 17:30:41 | 显示全部楼层
看源代码看不懂,还是LZ这篇文章详细啊!

出0入0汤圆

发表于 2009-7-15 22:37:38 | 显示全部楼层
楼主用的是S3C2440,我刚买了个哈哈,顶啊 先标记!

出0入0汤圆

发表于 2009-7-16 22:06:09 | 显示全部楼层
你的头文件是哪儿来的?不会自己写的吧。。。。

出0入0汤圆

发表于 2009-7-27 22:22:52 | 显示全部楼层
感谢楼主

出0入0汤圆

发表于 2009-8-3 23:18:45 | 显示全部楼层
很好 顶一个

出0入0汤圆

发表于 2009-8-4 06:46:38 | 显示全部楼层
高手啊,学习

出0入0汤圆

发表于 2009-8-4 22:39:09 | 显示全部楼层
嗯 很好 标记下  值得借鉴

出0入0汤圆

发表于 2009-8-5 15:52:01 | 显示全部楼层
哈哈,标记

出0入0汤圆

发表于 2009-8-9 12:33:13 | 显示全部楼层
mark 好东西

出0入0汤圆

发表于 2009-8-16 17:50:37 | 显示全部楼层
先标记一下,之前看启动代码看的都晕掉了

出0入0汤圆

发表于 2009-8-16 19:01:19 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-8-20 22:36:04 | 显示全部楼层
很不错,谢谢。
不过发现给问题啊,你step1:
step1:
ldr r0, =UPLLCON
ldr r1, =((56<<12) + (2<<4) + 2)
ldr r1, [r0]

最好应该str r1, [r0]吧

出0入0汤圆

发表于 2009-8-21 00:12:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-26 11:09:13 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-8-26 11:25:31 | 显示全部楼层
好东西,帮你顶!

出0入0汤圆

发表于 2009-8-26 16:05:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-31 03:34:04 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-9-1 20:22:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-2 08:24:49 | 显示全部楼层
顶.

出0入0汤圆

发表于 2009-9-2 08:52:22 | 显示全部楼层

出0入0汤圆

发表于 2009-9-2 14:46:04 | 显示全部楼层
我买的板子中初始化程序没有;
step8: 因为管理模式与用户模式共用
; 堆栈指针,所以借着系统模式
; 来设置用户模式的堆栈指针
orr r1, r0, #SYSMODE|NOINT
msr cpsr_cxsf, r1 ;SYSMode
ldr sp, =UserStack ;SVCStack & USERMode=0x33ff4800

没有对用户栈的初始化? 为何?

还有下面处于系统态也可以运行?

出0入0汤圆

发表于 2009-9-2 21:59:01 | 显示全部楼层
;导入外部C语言编写的异常与中断处理函数
IMPORT vectorUNDEF
IMPORT vectorSWI
IMPORT vectorPABT
IMPORT vectorDABT
IMPORT vectorIRQ
IMPORT vectorFIQ

这样直接定义编译的时候不会提示找不到么?

在头文件中有没有指定地址?

出0入0汤圆

发表于 2009-9-2 23:28:58 | 显示全部楼层
好详细 mark

出0入0汤圆

发表于 2009-9-4 10:38:00 | 显示全部楼层
启动代码我都是直接用keil的,从来没研究过这是怎么回事。

出0入0汤圆

发表于 2009-9-4 14:54:09 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-9-7 17:17:32 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-9-11 16:59:37 | 显示全部楼层

出0入0汤圆

发表于 2009-9-17 15:58:58 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-9-17 18:37:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-19 00:20:27 | 显示全部楼层
留爪!!

出0入0汤圆

发表于 2009-9-20 01:06:44 | 显示全部楼层
标记

出0入0汤圆

发表于 2009-9-20 08:57:07 | 显示全部楼层
footprint

出0入0汤圆

发表于 2009-9-25 16:04:25 | 显示全部楼层
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 08:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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