收藏 分销(赏)

s3c2440的一些解释.doc

上传人:xrp****65 文档编号:7687559 上传时间:2025-01-12 格式:DOC 页数:11 大小:53KB 下载积分:10 金币
下载 相关 举报
s3c2440的一些解释.doc_第1页
第1页 / 共11页
s3c2440的一些解释.doc_第2页
第2页 / 共11页


点击查看更多>>
资源描述
S3c2440启动是从文件vivi/arch/s3c2440/head.S开始的 1. 在这个文件中,做了这样的工作:  (1) 关闭看门狗  (2) 禁止所有中断  (3) 初始化system clock  (4) 初始化串口  (5) 初始化nand flash相关的控制寄存器  (6) 把vivi copy 到 SDRAM上,最后把pc指向ram  (7) 设置堆栈  (8) call 一个叫做main的函数。这个函数是c写的 2. main()这个函数在vivi/init/main.c中  (1) 程序正常跳转到这里后,首先打印一些进本信息  (2) 调用若干个初始化的函数   <1> reset_handler() vivi/lib/reset_handler.c中    (主要做了clear memory的工作)   <2> board_init() (没找到)   <3> mem_map_init()  vivi/arch/mmu.c中    (如果使用nand flash,会在这里使它看起来线性化;清空cache;invalidate I & D tlb)       mmu_init  vivi/arch/mmu.c中    (初始化cache,load页表指针,mmu 使能等等)   <4> heap_init 初始化堆 vivi/lib/heap.c    (这里好像malloc了一段空间,具体的没看懂)   <5> mtd_dev_init vivi/driver/mtd/mtdcore.c中    mtd_init()  在vivi/driver/mtd/maps/s3c2440_flash.c 中,这里根据所使用的flash,做相应的cpu控制初始化,分配内存    add_command(&flash_cmd) 注册了flash这个用户命令   <6> init_priv_data() vivi/lib/priv_data/rw.c中    读出boot的基本参数    <7> misc() (没找到)       init_builtin_cmds() vivi/lib/command.c中    (注册用户的基本命令,包括boot, bon, load, help 等等)   <8> boot_or_vivi() 就在main.c中,等待用户输入,有输入进入vivi_shell,没有输入,超时后启动linux 到这里main就结束喽 好像还有一件事没有记下来,就是vivi是怎么启动到linux的。这是vivi执行了boot命令,调用了 vivi/lib/boot_kernel.c 中的command_boot()函数。这样linux就启动了。 S3C2440启动过程兼示例代码分析     才开始学嵌入式没多久,用得友善之臂的2440板子,前段时间一直在搞linux系统,软件移植,内核裁剪等,最近发现还是应该从最基本的学起,想自己写一个bootloader,然后就研究了友善之臂那个板子上光盘里面配的一个示例程序,哎,搞了一天多才研究出来一点点东西,贴上来,免得忘了! S3C2440启动过程(约略): 1、关闭watch dog 2、屏蔽所有中断 3、屏蔽所有子中断 4、设置时钟更改稳定等待时间(LOCKTIME) 5、设置各部件时钟频率与CPU主频的比例关系(Fclk:Hclk:Pclk) 6、设置USB总线时钟频率(UPLLCON) 7、nap * 7 8、设置主时钟(MPLLCON) 9、判断是否是从睡眠状态唤醒的,如果是,则做出相应处理(具体处理还没看) 10、初始化存储设备、包括外存,内存等(BWSCON,BANKCONn,BANKSIZE,MRSRB6,MRSRB7) 11、初始化处理器各模式的堆栈(还没看懂) 12、Setup IRQ handler(也没咋看懂,似乎是对IRQ终端进行处理) 13、进入C程序(bl Main) 代码分析: ;========================================= ; NAME: 2440INIT.S ; DESC: C start up codes ;       Configure memory, ISR ,stacks ;    Initialize C-variables ; HISTORY: ; 2002.02.25:kwtark: ver 0.0 ; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode ; 2003.03.14:DonGo: Modified for 2440. ; 2009.02.19:PuHao: Comments ;========================================= ;========================= ; ENTRY 这里是关键的入口,正文数量超过最大限制,只有忽略其他我没看懂的了,等下能不能把那个文件传上来,好恶心的规定…… ;========================= ResetHandler     ;WTCON定义在2440addr.inc里面,WTCON     EQU  0x53000000     ;把WTCON地址放到R0里,然后在设置r1为0,最后把r1中的0值     ;拷贝到r0所指向的地址里面,即禁用watch dog     ldr    r0,=WTCON       ;watch dog disable     ldr    r1,=0x0     str    r1,[r0]          ;基本同上,INTMSK 0x4A000008 R/W Interrupt mask control     ldr    r0,=INTMSK     ldr    r1,=0xffffffff  ;all interrupt disable     str    r1,[r0]     ;基本同上     ldr    r0,=INTSUBMSK     ldr    r1,=0x3ff        ;all sub interrupt disable,0x3ff => 0000 0011  1111 1111     str    r1,[r0]     ;由于条件为FALSE,我觉得这段根本就不会执行     [ {FALSE}     ; rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);     ; Led_Display     ldr    r0,=GPFCON     ldr    r1,=0x5500     str    r1,[r0]     ldr    r0,=GPFDAT     ldr    r1,=0x10     str    r1,[r0]     ]     ;由于在更改了主时钟控制器(MPLL)之后,新的频率需要一定时间过后才能稳定     ;所以需要等待一段时间,而这个等待的时间就是使用LOCKTIME寄存器来设置的     ;LOCKTIME[15:00] MPLL lock time count value for FCLK, HCLK, and PCLK     ;LOCKTIME[32:16] UPLL lock time count value for UCLK.     ; FCLK用于CPU核     ; HCLK用于AHB总线的设备(比如SDRAM)     ; PCLK用于APB总线的设备(比如UART)     ; UPLL为USB的控制时钟,根据USB规范,好像是48MHz     ; ARM920T内核使用FCLK     ; 内存控制器,LCD控制器等使用HCLK;     ; 看门狗、串口等使用PCLK     ;To reduce PLL lock time, adjust the LOCKTIME register.     ldr    r0,=LOCKTIME     ldr    r1,=0xffffff ;0000 0000  1111 1111  1111 1111  1111 1111     str    r1,[r0]      ;为什么UPLL的等待时间要少一些呢?     [ PLL_ON_START     ; Added for confirm clock divide. for 2440.     ; Setting value Fclk:Hclk:Pclk     ; 这里设置的 Fclk:Hclk:Pclk = 1:3:6,因为 CLKDIV_VAL = 7     ldr    r0,=CLKDIVN       ldr    r1,=CLKDIV_VAL        ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.     str    r1,[r0]     ;UPLL和MPLL的控制参数     ;PLLCON        Bit        Description             Initial State     ;MDIV        [19:12] Main divider control    0x96 / 0x4d     ;PDIV        [9:4]    Pre-divider control        0x03 / 0x03     ;SDIV        [1:0]    Post divider control    0x0 / 0x0              ;InputFrequency        OutputFrequency        MDIV        PDIV    SDIV     ;12.0000MHz         48.00 MHz(Note)     56(0x38)     2        2     ;12.0000MHz         96.00 MHz(Note)     56(0x38)     2        1     ;12.0000MHz         271.50 MHz             173(0xad)     2        2     ;12.0000MHz         304.00 MHz             68(0x44)     1        1     ;12.0000MHz         405.00 MHz             127(0x7f)     2        1     ;12.0000MHz         532.00 MHz             125(0x7d)     1        1     ;Configure UPLL     ; 根据手册,要对PLL进行设置的话,就需要先设置UPLLCON,再设置MPLLCON     ; 并且中间需要有至少七个指令周期的延时     ; (Needs intervals approximately 7 NOP)     ; U_MDIV        EQU    56        ;Fin=12.0MHz Fout=48MHz     ; U_PDIV        EQU    2     ; U_SDIV        EQU    2     ldr    r0,=UPLLCON     ldr    r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)     str    r1,[r0]          ;(Needs intervals approximately 7 NOP)     nop    ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.     nop     nop     nop     nop     nop     nop     ;Configure MPLL     ; M_MDIV     EQU    68        ; 68 = 0x44 Fin=12.0MHz Fout=304.8MHz     ; M_PDIV     EQU    1     ; M_SDIV     EQU    1        ; 2440A     ; 设为(0x44 << 12)|(0x01 << 4)|(0x01),即0x00044011     ; Fclk:Hclk:Pclk = 1:3:6 =>  Fclk = 300MHz, Hclk = 100MHz, Pclk = 50MHz     ;     ldr    r0,=MPLLCON     ldr    r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)     str    r1,[r0]     ]             ;Check if the boot is caused by the wake-up from SLEEP mode.        ; GSTATUS2        Bit            Description     ; Reserved        [3]            Reserved     ; WDTRST        [2]            Boot is caused by Watch Dog Reset                cleared by writing “1”     ; SLEEPRST        [1]            Boot is caused by wakeup reset in sleep mode    cleared by writing “1”.     ; PWRST            [0]            Boot is caused by power on reset                cleared by writing “1”     ldr    r1,=GSTATUS2     ldr    r0,[r1]     tst    r0,#0x2     ;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.     bne    WAKEUP_SLEEP     ;EXPORT伪指令声明一个全局标号     EXPORT StartPointAfterSleepWakeUp StartPointAfterSleepWakeUp          ;Set memory control registers      ldr    r0,=SMRDATA     ldr    r1,=BWSCON    ;BWSCON Address     add    r2, r0, #52    ;End address of SMRDATA     ;r2 = r0 + 52     ; beq  %F[ ]中,b为跳转指令,eq为相等条件标识,整条语句的意思就是     ; 如果相等,则在此条语句后面的代码中搜索[ ]标号并跳转。     ; 同样的 bcc %B[ ] 其中cc为无符号数小于,%B在此条语句前面的代码中搜索并跳转     ;下面是一个循环     ;首先把r0指向的地址单元的一个字(4字节)的内容复制到r3中,     ;然后r0+4,这样的话下次取的值将会是SMRDATA中的下一个个字     ;     ;将r3中的值写入到r1的地址单元(BWSCON)中,并将r1+1,即     ;下一次将会写入到BWSCON的下一个控制器     ;控制器以此为:BWSCON - BANKCON0 - BANKCON1 - BANKCON2  ……BANKCON7     ;              BANKSIZE - MRSRB6 - MRSRB7 0     ldr    r3, [r0], #4     str    r3, [r1], #4     cmp    r2, r0    ;CPSR = r2 - r0             bne    %B0        ;不等于0时跳转,也就是说一直循环直到将上面所说的控制器全部                 ;设置了值之后才继续执行下一步          ;Initialize stacks     bl    InitStacks       ; Setup IRQ handler     ldr    r0,=HandleIRQ  ;This routine is needed     ldr    r1,=IsrIRQ       ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c     str    r1,[r0]     ;If main() is used, the variable initialization will be done in __main().     [    :LNOT:USE_MAIN             ;Copy and paste RW data/zero initialized data     LDR     r0, =|Image$$RO$$Limit| ; Get pointer to ROM data     LDR     r1, =|Image$$RW$$Base|  ; and RAM copy     LDR     r3, =|Image$$ZI$$Base|            ;Zero init base => top of initialised data     CMP     r0, r1      ; Check that they are different     BEQ     %F2 1            CMP     r1, r3      ; Copy init data     LDRCC   r2, [r0], #4    ;--> LDRCC r2, [r0] + ADD r0, r0, #4              STRCC   r2, [r1], #4    ;--> STRCC r2, [r1] + ADD r1, r1, #4     BCC     %B1 2            LDR     r1, =|Image$$ZI$$Limit| ; Top of zero init segment     MOV     r2, #0 3            CMP     r3, r1      ; Zero init     STRCC   r2, [r3], #4     BCC     %B3     ]             [ :LNOT:THUMBCODE         bl    Main        ;Don't use main() because ......because what?         b    .                            ]     [ THUMBCODE         ;for start-up code for Thumb mode         orr    lr,pc,#1         bx    lr         CODE16         bl    Main        ;Don't use main() because ......because what?         b    .         CODE32     ] ;function initializing stacks ;初始化堆栈的代码还没仔细研究,正文字数超过最大限制,只有不贴下面的了…… 一:地址空间的分配 1:s3c2440是32位的,所以可以寻址4GB空间,内存(SDRAM)和端口(特殊寄存器),还有ROM都映射到同一个4G空间里. 2:开发板上一般都用SDRAM做内存flash(nor、nand)来当做ROM。其中nand flash没有地址线,一次至少要读一页(512B).其他两个有地址线 3:norflash不用来运行代码,只用来存储代码,NORflash,SDRAM可以直接运行代码) 4:s3c2440总共有8个内存banks 6个内存bank可以当作ROM或者SRAM来使用 留下的2个bank除了当作ROM 或者SRAM,还可以用SDRAM(各种内存的读写方式不一样) 7个bank的起始地址是固定的 还有一个灵活的bank的内存地址,并且bank大小也可以改变 5:s3c2440支持两种启动模式:NAND和非NAND(这里是nor flash)。 具体采用的方式取决于OM0、OM1两个引脚 OM[1:0所决定的启动方式 OM[1:0]=00时,处理器从NAND Flash启动 OM[1:0]=01时,处理器从16位宽度的ROM启动 OM[1:0]=10时,处理器从32位宽度的ROM启动。 OM[1:0]=11时,处理器从Test Mode启动。 当从NAND启动时 cpu会自动从NAND flash中读取前4KB的数据放置在片内SRAM里(s3c2440是soc),同时把这段片内SRAM映射到nGCS0片选的空间(即0x00000000)。cpu是从0x00000000开始执行,也就是NAND flash里的前4KB内容。因为NAND FLASH连地址线都没有,不能直接把NAND映射到0x00000000,只好使用片内SRAM做一个载体。通过这个载体把nandflash中大代码复制到RAM(一般是SDRAM)中去执行 当从非NAND flash启动时 nor flash被映射到0x00000000地址(就是nGCS0,这里就不需要片内SRAM来辅助了,所以片内SRAM的起始地址还是0x40000000). 然后cpu从0x00000000开始执行(也就是在Norfalsh中执行)。 总结: Arm的启动都是从0地址开始,所不同的是地址的映射不一样。在arm开电的时候,要想让arm知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候arm会通过引脚的电平来判断。 1当引脚OM0跟OM1有一个是高电平时,这时地址0会映射到外部nGCS0片选的空间,也就是Norflash,程序就会从Norflash中启动,arm直接取Norflash中的指令运行。 2当OM0跟OM1都为低电平,则0地址内部bootbuf(一段4k的SRAM)开始。系统上电,arm会自动把NANDflash中的前4K内容考到bootbuf(也就是0地址),然后从0地址运行。 这时NANDFlash中的前4K就是启动代码(他的功能就是初始化硬件然后在把NANDFlash中的代码复制到RAM中,再把相应的指针指向该运行的地方) 为什么会有这两种启动方式,关键还是两种flash的不同特点造成,NOR FLASH容量小,速度快,稳定性好,输入地址,然后给出读写信号即可从数据口得到数据,适合做程序存储器。NAND FLASH 总容量大,但是读写都需要复杂的时序,更适合做数据存储器。这种不同就造成了NORflash可以直接连接到arm的总线并且可以运行程序,而NANDflash必须搬移到内存(SDRAM)中运行。 在实际的开发中,一般可以把bootloader烧入到Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。这样就很可以很方便的调试你的一些代码。Norflash中的Bootloader还可以烧录内核到Norflash等等功能。 我也在用这块板子. 说下我的看法吧. 主流的s3c2440A处理器,arm9内核 接口齐全,文档也比较丰富.利用板载资源可以学习不少东西.完整的嵌入式wince和linux都可以开发.还可以移植其它系统,当然这方面用的就少了. 目前来看是做学习板较好的厂商.售后没接触过,因为我还没遇到什么问题需要联系售后的. 有专门的交流论坛. 烧程序需要串口,jtag调试需要并口.一般笔记本都不带这些接口了.所以需要买个转接的,usb转串口的统统不好用,我试过N多的了,不好用.买个了华塑pc卡转串口的,可卡好像有毛病,有时超级终端输不进去.也许我买到假货了.后来我买了个OpenJtag,这个东西可以转串口,可以转Jtag,烧写速度也快.但是我不习惯在Eclipse下搞.所以只把它当串口用了. 有点扯远了,友善的板子不错.性价比高.推荐. micro2440和mini2440相比,micro是做的核心版和底板是分开的,所以用jtag调试时可以不用底板,micro多了点硬件资源,串口也多了.其它没什么区别. 性价比高的是mini2440,不用在这上面过多考虑了.用mini的人很多. 不管怎样,选个开发板后好好研究下,肯定有成果的.
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服