日历
网志分类
· 所有网志 (28)
· english (0)
· film (1)
· work (2)
· life (3)
· example (0)
· linux (20)
· vxworks (1)
· 未分类 (1)
站内搜索
友情链接
· 我的歪酷
· 氧气的小木屋

订阅 RSS

0008335

歪酷博客

A Beautiful Mind

learning english & linux everyday.


« 上一篇: Program Library HOWTO 下一篇: [转载] 长篇连载--arm linux演艺 »
snow @ 2006-06-09 14:29

0 概述
本文主要分析PXA255开发板带的linux系统中的bootloader
 
1 BootLoader流程框架
1.1 lds文件(Ld-xscale
链接文件:描述了bootloader链接的规则。
 
ENTRY(_start)
SECTIONS
{
   . = ALIGN(4);
   .text 0xA4000000 - 0x80000:
   {
      _ld_text_start = .;
      *(.text)
      *(.got)
      *(.got.pld)
      *(.rodata)
      _ld_text_end = .;
   }
   _ld_text_size = SIZEOF(.text);
 
   _ld_stack_address = _ld_text_start + 0x80000;
}
这里定义了入口:_start
定义了各个段的属性:
   .text 0xA4000000 - 0x80000:
 
1.2 总入口函数(start_xscale.S
入口点:
_start:
        b       reset
跳转到reset处执行
reset:
       // Mask All interrupt       ICMR/ ICLR清零
        ldr     r12, =INTERRUPT_CONTROL_BASE
        ldr     r0, =0x00000000
        str     r0, [r12, #ICMR]
        str     r0, [r12, #ICLR]
       // Initialize GPIO         初始化GPIO
       bl      gpio_init
       // Initialize SDRAM       初始化SDRAM
        bl      init_sdram  
       // Copy Bootloader from Flash to SDRAM   bootloader代码搬移到SDRAM
       bl     copy_to_ram
      
       // Loading kernel image                  
        ldr   r4, =KERNEL_SRAM_BASE
        ldr   r5, =KERNEL_DRAM_BASE
        ldr   r6, =KERNEL_MAX_SIZE
        add r6, r6, r4
repeat:
        ldmia   r4!, {r0-r3, r7-r10}
        stmia   r5!, {r0-r3, r7-r10}
        cmp             r4, r6
        blt             repeat
 
       ldr   sp, =_ld_stack_address
 
       // Jump to c_main                     bootloaderc代码的主程序
       ldr   r0, =c_main
       mov pc, r0
 
die:                    //死循环,无其他意义,起保护作用。
       b     die
 
1.3初始化GPIO
这段代码很简单,就是把GPIO的初始值设置好。这里需要做的一个工作是结合具体的资料分析其初始值的含义。
gpio_init:
       ldr     r12, =GPIO_BASE
 
    ldr     r0, =GAFR0L_VALUE
    str     r0, [r12, #GAFR0_L]
    ldr     r0, =GAFR0U_VALUE
    str     r0, [r12, #GAFR0_U]
 
    ldr     r0, =GAFR1L_VALUE
    str     r0, [r12, #GAFR1_L]
    ldr     r0, =GAFR1U_VALUE
    str     r0, [r12, #GAFR1_U]
 
    ldr     r0, =GAFR2L_VALUE
    str     r0, [r12, #GAFR2_L]
    ldr     r0, =GAFR2U_VALUE
    str     r0, [r12, #GAFR2_U]
 
    ldr     r0, =GPSR0_VALUE
    str     r0, [r12, #GPSR0]
    ldr     r0, =GPSR1_VALUE
    str     r0, [r12, #GPSR1]
    ldr     r0, =GPSR2_VALUE
    str     r0, [r12, #GPSR2]
 
    ldr     r0, =GPCR0_VALUE
    str     r0, [r12, #GPCR0]
    ldr     r0, =GPCR1_VALUE
    str     r0, [r12, #GPCR1]
    ldr     r0, =GPCR2_VALUE
    str     r0, [r12, #GPCR2]
 
    ldr     r0, =GPDR0_VALUE
    str     r0, [r12, #GPDR0]
    ldr     r0, =GPDR1_VALUE
    str     r0, [r12, #GPDR1]
    ldr     r0, =GPDR2_VALUE
    str     r0, [r12, #GPDR2]
 
        // Clear the peripheral control register bits
       ldr     r1, =PSSR
       ldr     r2, =(PSSR_RDH | PSSR_PH)
       str     r2, [r1]
       
       mov     pc, lr
 
1.4 初始化SDRAM
关于处理器复位后内存相关的初始化过程在开发手册上有详细说明。
Software performs the following procedures when the processor comes out of a reset:
1. After hardware reset, complete a power-on wait period of 200 µs, which allows the internal clocks that generate SDCLK to stabilize. Enable MDREFR:K0RUN and E0PIN for Synchronous Static memory. When MDREFR is written, a refresh interval value (MDREFR:DRI) must also be written. The following writes are allowed:
a. Write MSC0, MSC1, MSC2
b. Write MECR, MCMEM0, MCMEM1, MCATT0, MCATT1, MCIO0, MCIO1
c. Write MDREFR:K0RUN and MDREFR:E0PIN. Configure MDREFR:K0DB2. Retain the current values of MDREFR:APD and MDREFR:SLFRSH. MDREFR:DRI must contain a valid value. Deassert MDREFR:KxFREE.
2. In systems that contain Synchronous Static memory, write to the SXCNFG to configure all appropriate bits, including the enable bits. Software must perform a sequence that involves a subsequent write to SXCNFG to change the RAS latencies. While any SMROM banks are being configured, the SDRAM banks must be disabled and MDREFR:APD must be deasserted (auto-power-down disabled).
a. Write SXCNFG (with enable bits asserted).
b. Write to SXMRS to trigger an MRS command to all enabled banks of synchronous static memory.
c. SXLCR must only be written when it is required by the SDRAM-like synchronous flash device for command encoding.
3. In systems that contain SDRAM, transition the SDRAM controller through the following state sequence:
a. self-refresh and clock-stop
b. self-refresh
c. power-down
d. PWRDNX
e. NOP
4. The SDRAM clock run and enable bits (MDREFR:K1RUN, K2RUN, and E1PIN), described in Section 6.5.3. MDREFR:SLFRSH must not be asserted.
a. Write MDREFR:K1RUN, K2RUN (self-refresh and clock-stop -> self-refresh). Configure MDREFR:K1DB2,K2DB2.
b. Write MDREFR:SLFRSH (self-refresh -> power-down).
c. Write MDREFR:E1PIN (power-down -> PWRDNX).
d. a write is not required for this state transition (PWRDNX -> NOP).
e. Configure, but do not enable, each SDRAM partition pair.
f. Write MDCNFG (with enable bits deasserted), MDCNFG:DE3:2,1:0 set to ‘0’.
5. For systems that contain SDRAM, wait a specified NOP power-up waiting period required by the SDRAMs to ensure the SDRAMs receive a stable clock with a NOP condition
6. Ensure the Data Cache bit (DCACHE) is disabled. If this bit is enabled, the refreshes triggered by the next step may not pass through to the Memory Controller properly.
7. On a hardware reset in systems that contain SDRAM, trigger the specified number (typically eight) of refresh cycles by attempting non-burst read or write accesses to any disabled SDRAM bank. Each such access causes a simultaneous CBR refresh cycles for all four banks, which causes a pass through the CBR state and back to NOP. On the first pass, the PALL state occurs before the CBR state.
8. Re-enable the DCACHE bit if it is disabled.
9. In systems that contain SDRAM, enable SDRAM partitions by setting MDCNFG:DE3:2,DE1:0.
10. In systems containing SDRAM, write the MDMRS register to trigger an MRS command to all enabled banks of SDRAM. For each SDRAM partition pair that has one or both partitions enabled, this forces a pass through the MRS state and back to NOP. The CAS latency must be the only variable option and is derived from the value programmed in the MDCNFG:MDTC0,2 fields. The burst type is programmed to sequential and the length is set to four.
 
 
 
 
寄存器说明:
CKEN
0x00000040CKEN6 =1 (FFUART Unit Clock Enable)
 
CCCR
0x00000161 |010|11|00001):
N: 010  ( Turbo mode Freq. = Run mode frequency * N)
M:11 
L: 00001
(Crystal Frequency to Memory Frequency Multiplier)
PXA255晶震频率:                      内存频率:    
运行频率:                              Turbo模式频率:
 
OSCC:
0x0000000232.768 KHz oscillator is enabled.
 
OSCRThe current value of the OS timer counter.
先给OSCR0,然后等到该值增长到 300
 
MSC0/1/2
0x7ff812B8
RBUFF1=0   “Slower device”      RRR1=7 “ROM/SRAM recovery time.” ?  
RDN1 = F    “ROM delay next access
RDF1 = F     “ROM delay first access. ”
RBW1 =1    “ROM bus width ” 0: 32bit   1: 16bit
RT1 = 000        “ROM type”    000 - Nonburst ROM or Flash Memory
 
RBUFF0=0   “Slower device”      RRR0=1 “ROM/SRAM recovery time.” ?  
RDN0 = 2    “ROM delay next access
RDF0 = B     “ROM delay first access. ”
RBW0 =1    “ROM bus width ” 0: 32bit   1: 16bit
RT0 = 000        “ROM type”    000 - Nonburst ROM or Flash Memory
 
0x7ff87FF0: 就是RBW0=0 32bit
 
0x12BC5554
RBUFF3=0   “Slower device”      RRR3=1 “ROM/SRAM recovery time.” ?  
RDN3 = 2    “ROM delay next access
RDF3 = b     “ROM delay first access. ”
RBW3 =1    “ROM bus width ” 0: 32bit   1: 16bit
RT3 = 100        “ROM type”    100 - Variable Latency I/O (VLIO)
 
RBUFF2=0   “Slower device”      RRR2=5 “ROM/SRAM recovery time.” ?  
RDN0 = 5    “ROM delay next access
RDF0 = 5     “ROM delay first access. ”
RBW0 =0    “ROM bus width ” 0: 32bit   1: 16bit
RT0 = 100      “ROM type”    100 - Variable Latency I/O (VLIO)
 
0x7FF87FF1: 同前,就是RT4 = 001    001 - SRAM
 
MECR: (Expansion Memory Configuration Register)
0x00000000: 表示 0 – No card inserted
0x00000002:表示有卡,且一个socket
 
MCMEM0/1, MCATT0/1, MCIO0/1:(contain control bits for configuring the timing of the 16-bit PC Card/Compact Flash interface.
新开发板上没有,不考虑。
 
MDREFR
0x000BC018
DRI = 0x018    SDRAM refresh interval, all partitions.
E0PIN = 0      Synchronous Static Memory Clock Enable Pin 0
K0RUN=0      Synchronous Static Memory Clock Run Pin 0
K0DB2=1      Synchronous Static Memory Clock Pin 0 (SDCLK<0>)
 SDCLK0 runs at one-half the memory clock frequency.
E1PIN=1      SDRAM Clock Enable Pin 1 (SDCKE1)
K1RUN=1     SDRAM Clock Pin 1 (SDCLK<1>) enable
K1DB2=1      SDCLK1 runs at one-half the MEMCLK frequency
K2RUN=0      SDRAM Clock Pin 2 (SDCLK<2>) disable
K2DB2=1       SDCLK2 runs at one-half the MEMCLK frequency
APD=0  
SLFRSH=0
K0/1/2FREERUN =0
 
MDCNFG:
0x00001AC9
DE0=1    SDRAM enable for partition 0                    DE1=0
DWID0=0   SDRAM data bus width for partition pair 0/1 (0 – 32 bits)
DCAC0=01 Number of Column Address bits for partition pair 0/1 (01 - 9 column address bits)
DRAC0=10  13 row address bits
DNB0 = 1    4 internal SDRAM banks
DTC0=10    tRP = 3 clks, CL = 3, tRCD = 3 clks, tRAS(min) =7 clks, tRC=10 clks
DADDR0=0 
DLATCH0=1   Latch return data with return clock
DSA1111_0=1  Use SA1111 Addressing Muxing Mode for pair 0/1.
 
MDMRSMode Register Set Configuration Register
 
 
 
 
init_sdram:
       mov r10, lr
 
        ldr     r12, =CLOCK_MANAGER_BASE
 
        ldr     r0, =CKEN_VALUE
        str     r0, [r12, #CKEN]
        ldr     r0, =OSCC_VALUE
        str     r0, [r12, #OSCC]
 
#if 1
//TODO: Issuing a FCS on a B1 seems to make it crash
//shortly after. Figure out why...
        ldr     r0, =CCCR_VALUE
        str     r0, [r12, #CCCR]
        mov     r1, #3
        mcr     p14, 0, r1, c6, c0, 0
 
       ldr   r1, =OSCR
       ldr   r0, =0
       str   r0, [r1]
 
        ldr     r0, =0x300
wait_for_clock:
        ldr   r2, [r1]
        cmp     r0, r2
        bne     wait_for_clock
#endif
 
        //Step 1 in Intel's code
        ldr     r12, =MEM_CTL_BASE
 
        ldr     r0, =MSC0_VALUE
        str     r0, [r12, #MSC0]
        //Intel's code reads it back to make sure it works...
    //    ldr     r0, [r12, #MSC0]
 
        ldr     r0, =MSC1_VALUE
        str     r0, [r12, #MSC1]
        ldr     r0, [r12, #MSC1]
 
        ldr     r0, =MSC2_VALUE
        str     r0, [r12, #MSC2]
        ldr     r0, [r12, #MSC2]
 
        ldr     r0, =MECR_VALUE
        str     r0, [r12, #MECR]
 
        ldr     r0, =MCMEM0_VALUE
        str     r0, [r12, #MCMEM0]
 
        ldr     r0, =MCMEM1_VALUE
        str     r0, [r12, #MCMEM1]
 
        ldr     r0, =MCATT0_VALUE
        str     r0, [r12, #MCATT0]
 
        ldr     r0, =MCATT1_VALUE
        str     r0, [r12, #MCATT1]
 
        ldr     r0, =MCIO0_VALUE
        str     r0, [r12, #MCIO0]
 
        ldr     r0, =MCIO1_VALUE
        str     r0, [r12, #MCIO1]
 
        //according to Intel's comments, we're extracting the DRI
 
       // Loading the MDREFR in a way that will make it configure
       // correctly is a multi-step process. Please read Section
       // 6.12 of the PXA Developers Manual For more Details
 
       // 1.
       // The first step requires that we set K0RUN and E0PIN while
       // configuring DRI and clearing KXFREE. All other values
       // MUST be left alone
        ldr     r0, =MDREFR_VALUE
        ldr     r3, [r12, #MDREFR]
        ldr     r1, =0xFFF
        and     r0, r0, r1
 
       // Make the DRI we read from MDREFR what MDREFR_VALUE says it is.
       // We also Free KXFREE the free running bits.
        bic     r3, r3, r1
       bic   r3, r3, #0x03800000
        orr     r3, r3, r0
 
        //Write it back
        str     r3, [r12, #MDREFR]
 
 
       // 2.
       // We don't have Synchronous Static Memory and don't want to
       // mess with SXCNFG or the like so we are leaving out this
       // step.
 
       // 3.
       // We don't bother to do this step as it does not seem to have
       // been done previously (actually maybe Self-Refresh Disable should
       // be here.)
 
        // 4.
       // Here we will setup the SDCLK's but WILL NOT enable them. We
       // need to reload MDREFR for this.
        ldr     r0, =MDREFR_VALUE
       ldr   r1, =0xF6000 // Mask of SDCLK's settings minus EXPIN
       and r0, r0, r1
        bic     r3, r3, r1
       orr   r3, r3, r0
 
        str     r3, [r12, #MDREFR]
       ldr   r3, [r12, #MDREFR]
 
       // 4.
        // Although I think that this should be at #3 It is here cause this
       // is where it was originally. This will turn off Self-Refresh.
        bic     r3, r3, #0x00400000
        str     r3, [r12, #MDREFR]
 
       // 5.
       // Finally, we Enable the Various SDCLK's and let it run.
       // Also, enable the free-running clocks (not mentioned in the manual).
       ldr   r0, =MDREFR_VALUE
       ldr   r1, =0x03809000
       and r0, r0, r1
       orr   r3, r3, r0
        str     r3, [r12, #MDREFR]
        nop
        nop
 
        //Step 4 in Intel's code
        ldr     r0, =MDCNFG_VALUE
 
        //disable all sdram banks
        bic     r0, r0, #0x00000003
        bic     r0, r0, #0x00030000
 
        //program banks 0/1 for 32 bit bus width
        bic     r0, r0, #0x00000004
 
       //test with 16 bit bus width
//     orr   r0, r0, #0x00000004
 
        //write MDCNFG, without enabling SDRAM banks
        str     r0, [r12, #MDCNFG]
 
        //Step 5 in Intel's code
        ldr     r0, =OSCR
       mov r1, #0
       str   r1, [r0]
 
        //pause for approx 200 usecs
        ldr     r4, =0x300
sdram_dly:
        ldr     r1, [r0]
        cmp     r4, r1
        bgt     sdram_dly
 
        //Step 6 in Intel's code
        //turn everything off
        mov     r0, #0x78
        mcr     p15, 0, r0, c1, c0, 0
 
 
        //Step 7 in Intel's code
        //Access memory that has not been enabled for CBR refresh cycles (8)
       ldr   r0, =SDRAM_BASE
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
        str     r0, [r0]
 
        //Step 8 is blank in Intel's code, though they mention dcache should
        //be enabled here if it is desired (we don't care)
 
 
        //Step 9
        ldr     r0, [r12, #MDCNFG]
 
        //enable bank 0 (what about bank 1?)
        orr     r0, r0, #0x00000001
        str     r0, [r12, #MDCNFG]
 
        //Step 10
        //write MDMRS again
        ldr     r0, =MDMRS_VALUE
        str     r0, [r12, #MDMRS]
 
 
        //Step 11
        //are we A1_Cotulla?
        ldr     r0, [r12, #MDREFR]
 
       ldr   r11, =0xFFEFFFFF
       and r0, r0, r11
 
        str     r0, [r12, #MDREFR]
 
        mov     pc, r10
 
1.    5bootloader代码搬移到SDRAM
把从地址0开始,长度为_ld_text_and_data_size的代码数据copy_ld_text_start位置中去。
1.1可以知道,_ld_text_start 应该为:0xA4000000
copy_to_ram:
       mov r8, lr
 
       ldr   r0, =0
       ldr   r1, =_ld_text_start
       ldr   r2, =_ld_text_and_data_size
 
copy_loop:
       ldr   r3, [r0]
       str   r3, [r1]
       add r0, r0, #4
       add r1, r1, #4
       subs r2, r2, #4
       bne copy_loop
 
       mov pc, r8
 
 
1.6装载内核
把操作系统内核代码从flash空间的0x000C0000位置搬移到内存空间:0xA0008000中去。最大不超过2M左右。
       // Loading kernel image
        ldr   r4, =KERNEL_SRAM_BASE
        ldr   r5, =KERNEL_DRAM_BASE
        ldr   r6, =KERNEL_MAX_SIZE
        add r6, r6, r4
repeat:
        ldmia   r4!, {r0-r3, r7-r10}
        stmia   r5!, {r0-r3, r7-r10}
        cmp             r4, r6
        blt             repeat
 
 
       ldr   sp, =_ld_stack_address
 
 主要就是几个初始化函数,然后判断是进入操作系统,还是进而交互界面。
 (*((volatile unsigned short *)( 0x16000000)))=~0x4;
 
// serial and timer init.
SerialInit(status.terminalSpeed);
TimerInit();
 
EthInit();
 
1.8 串口初始化
用到的寄存器说明:
GAFR1_L
0x000A8000:表示AF39AF40AF410x10 used for its alternate function 2
 
GPDR1:
0x00000380:表示PD39PD40PD41都为1。(configured as output.
 
FFLCR:
0x00000003:表示字节长度为8,停止位为1,无奇偶检验,
 
FFFCR
0x00000007:表示FIFOs are enabledThe receiver FIFO is clearedThe transmitter FIFO is cleared
 
FFIER
0x00000040:表示UUE=1 the unit is enable 
 
DLL:在设置DLL的值之前,需要先设置LCR的对应位。设置完DLL的值之后,还需要清除LCR中的对应位。DLLDLH设置的是分频值。这里取值为8,得到波特率为115200
 
LSR
0x00000040:表示检查TEMT,等该条件为1满足退出。
All the data in the transmitter has been shifted out
 
void SerialInit(ulong baud){
 
   // GP39, GP40, GP41
   GAFR1_L |= 0x000A8000;     
   GPDR1   |= 0x00000380;
 
   // 8-bit, 1 stop, no parity
   FFLCR = 0x00000003;
 
   // Reset tx, rx FIFO. clear. FIFO enable
   FFFCR = 0x00000007;
 
   // UART Enable Interrupt
   FFIER = 0x00000040;
 
   // DLAB set=latch registers, DLAB clear=
   FFLCR |= 0x00000080;
 
   // baud rate
   FFDLL = baud;
 
   // DLAB clear,
   FFLCR &= 0xFFFFFF7F;
 
   // Transmit Shift Register, Transmit Holding Register, FIFO
   //
   while(! FFLSR & 0x00000040 );
 
   return;
}
 
1.9 以太网初始化
寄存器的详细信息如下:
lineCTL
0x0000:表示Rx, Tx disable
 
ISAINT
 
ISADMA
 
 
RXCNF:能使能各种中断
RxCTL:配置什么特征的报文可以接收
RX_OK_ACCEPT:接收正确的报文(长度和CRC
RX_IA_ACCEPT:接收目标地址匹配的报文。
 
TxCFG:能使能各种中断
TX_LOST_CRS_ENBL
TX_SQE_ERROR_ENBL
TX_OK_ENBL
TX_LATE_COL_ENBL
TX_JBR_ENBL
TX_ANY_COL_ENBL
 
TxCMD:包含着最后的传输命令,指明下一个报文如何发送。
 
 
0x00C0TxStart等于
 
BufCFG
0x0000:禁止各种buf相关的中断。
 
BusCTL
ENABLE_IRQ:使能网卡中断
IO_CHANNEL_READY_ON
 
TestCTL:可以用来设置各种测试功能。
0x0000:禁止掉各种测试功能。
 
TxCommand:指明下一个报文如何传输 (TXCMD一样,但地址不一样?)
0x00c0txstart为:
 
Hash Table:(LAF
 
Physical Address RegisterIA
 
 
 
bool EthInit(){
       int           i;
 
       // 1. check memory mapping (read IOBase Address).
       // check value of IO_PPPTR is 0x3000.
       // 1~3 bit(011b) is read only. so clear others.
 
       MemSet((char *)0x04000000, 0x0, 2);        // Test Code
      
       if ((IO_PPPTR&0x7000) != 0x3000){
              printf("Can't access to Memory of CS8900A.\n");
              return false;
       }
      
       // 2. check CS8900A Chip ID (read packet page 0x0000~0x0003).
       if (ReadFromPPR(PP_ChipID)!=0x630E){
              printf("\nEthernet Chip is not CS8900A. Are you use CS8900A.\n");
              return false;
       }
 
       // 3. Rx, Tx disable.
       WriteToPPR(PP_LineCTL,          0x0000);
 
       // 4. if needs, set Bus Interface Registers(view CS8900 Manual 4.2 p40).
       WriteToPPR(PP_CS8900_ISAINT,      INTRQ_HIGH_IMPEDENCE);
       WriteToPPR(PP_CS8900_ISADMA,    DMRQ_HIGH_IMPEDENCE);
 
       // 5. set Status and Control Registers.
       WriteToPPR(PP_RxCFG,      RX_OK_ENBL | RX_CRC_ERROR_ENBL);
       WriteToPPR(PP_RxCTL,      RX_OK_ACCEPT | RX_IA_ACCEPT);
      
       WriteToPPR(PP_TxCFG,      TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
                                                 TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL);
       WriteToPPR(PP_TxCMD,     TX_START_ALL_BYTES);
       WriteToPPR(PP_BufCFG,     0x0000);
       WriteToPPR(PP_BusCTL,     ENABLE_IRQ | IO_CHANNEL_READY_ON);
       WriteToPPR(PP_TestCTL,    0x0000);
      
 
       ///// Initiate Transmit Registers. ////////////////////////////////////////
       WriteToPPR(PP_TxCommand,0x00c0);      // start Tx after the entire frame is in the CS8900A.
 
       // 6. set Address Filter Registers.
       // set Logical Address Filter.
       for (i=0; i<4; i++){
              WriteToPPR(PP_LAF+i*2, 0xffff);
       }
 
       for (i=0; i<3; i++){
              WriteToPPR(PP_IA+i*2, *((ushort *)&(clientEther[i*2])));
       }
 
    // 7. Rx, Tx enable.
       WriteToPPR(PP_LineCTL,    SERIAL_RX_ON | SERIAL_TX_ON);
       return true;
}     // EthInit.
 
1.10 进入linux内核
程序跳转到0xA0008000,并且传递了两个参数:0,200
参数的含义:0ARM启动需要的一个值,没有特殊用途。
            200是指系统的系统结构。具体类型在ARM的启动代码中有定义。
 
 
#define KERNEL_DRAM_BASE          (0xA0008000)
theKernel = (void (*)(int, int))KERNEL_DRAM_BASE;
theKernel(0, 200);
 
 
2 FLASH操作接口
2.1 擦除块
擦除某一段FLASH地址空间。
bool EraseFlashBlocks(FUNIT *addr, ulong len) 
FLASH中,内核,bootloaderroot各自的位置都已经固定。
BOOT0x00000000        最大:0x00040000  
内核: 0x000C0000         最大:0x00200000  
root 0x002C0000          最大: 0x00E00000 / 0x01D00000
 
 
擦除具体某一block FLASH.
static bool EraseOneFlashBlock(FUNIT *addr)
 
2.2 FLASH
FLASH之前需要先对该区域进行擦除。
 
bool WriteToFlashBuffer(void *dest, void *src)
一次写一块大小。
3.1 串口输出
LSR:
TDRQIndicates that the UART is ready to accept a new character for transmission.
 
THR: In FIFO mode, a write to the THR puts data into the end of the FIFO. The data at the front of the FIFO is loaded to the TSR when that register is empty.
 
void SerialOutputByte(const char c){
       while ((FFLSR & 0x00000020) == 0 );
 
       FFTHR = ((ulong)c & 0xFF);
       if (c=='\n') SerialOutputByte('\r');
}
 
 
3.2 串口输入
LSR寄存器中的DR=1: DATA is ready. Data is available in RBR or the FIFO
 
RBR: In FIFO mode, the RBR latches the value of the data byte at the front of the FIFO.
 
int SerialInputByte(char *c){
 
       if((FFLSR & 0x00000001)==0){
              return 0;
       } else {
 
              (volatile char)*c = FFRBR;
              return 1;
       }
}
 
 


评论 / 个人网页 / 扔小纸条
*昵称

已经注册过? 请登录

Email
网址
*评论