天天看點

給S5PV210裸機程式添加啟動代碼

(說明:本貼适用于tiny210v2且NandFlash型号為:K9GAG08U0F,其他暫不支援_不知道這算不算标題黨:) )

友善提供了全套的210裸機代碼的确很好,代碼編寫風格也是值得學習的。不過裸機代碼是用不開源的Superboot引導的,這樣學習裸機 總有一種穿着棉褲洗澡的感覺,很不爽。還好了解了S5PV210的啟動方式後,對于小于16k的裸機代碼都可以将連結位址改為 0xd0020010,sp指針設定到 0xD0037D80,然後用 mkv210_image.c将bin檔案制作成 210.bin。再用Minitools下載下傳u-boot的方式下載下傳這個裸機程式。S5PV210的IROM中的BL0程式會從NandFlash拷貝代碼到iram中的0xd0020000處,然後跳到0xd0020010處運作。裸機就可以跑起來了。

但是對于大于16k的代碼,就不能完全靠IROM中BL0程式拷貝了。就要自己寫一下BL1的啟動代碼了,自己拷貝。 經過《 分析一下tiny210v2的16bitECC校驗(已經實作u-boot for tiny210v2)》和《 u-boot for tiny210v2 (NandFlash:K9GAG08U0F)》其實“BL1”代碼已經做好了,并且經過引導u-boot的驗證的。下面就說說怎麼添加到友善的裸機代碼中,完全整個裸機代碼的開源。下面以13.uart_stdio這個裸機代碼添加“BL1”啟動的過程說明一下。(燒寫方式同上)

1.添加“BL1”目錄(目錄中包含了Makefile和mkv210_image.c) 2.添加nand_cp.c memory.S s5pv210.h 3.修改原工程的Makefile添加如下紅色内容 CC      = arm-linux-gcc LD      = arm-linux-ld AR      = arm-linux-ar OBJCOPY = arm-linux-objcopy OBJDUMP = arm-linux-objdump

CONFIG_SYS_TEXT_BASE :=0X20000000 COPY_BL2_SIZE :=0x80000

INCLUDEDIR := $(shell pwd)/include CFLAGS :=-g -Wall -O2 -fno-builtin  -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \ -DCOPY_BL2_SIZE=$(COPY_BL2_SIZE) CPPFLAGS   :=-g -nostdinc -I$(INCLUDEDIR)  -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \ -DCOPY_BL2_SIZE=$(COPY_BL2_SIZE) export CC AR LD OBJCOPY OBJDUMP INCLUDEDIR CFLAGS CPPFLAGS 

objs := start.o  memory.o nand_cp.o main.o uart.o clock.o lib/libc.a

all: stdio.bin make -C ./BL1 cat ./BL1/BL1.bin stdio.bin > 210.bin stdio.bin: $(objs) ${LD} -Ttext  ${CONFIG_SYS_TEXT_BASE} -Tstdio.lds -o stdio.elf $^ ${OBJCOPY} -O binary -S stdio.elf $@ ${OBJDUMP} -D stdio.elf > stdio.dis

.PHONY : lib/libc.a lib/libc.a: cd lib; make; cd .. %.o:%.c ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

%.o:%.S ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

clean: make  clean -C lib make clean -C ./BL1/ rm -f *.bin *.elf *.dis *.o 

4.保證工程目錄已經實作uart.c 和 start.S,并在start.S中添加如下紅色内容:

@****************************************************************************** @ File:start.S @ 功能:啟動代碼,設定棧,拷貝代碼到CONFIG_SYS_TEXT_BASE處 @******************************************************************************   .text .global _start _start: mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr,r0 mov r0, #0 @ set up for MCR mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs mcr p15, 0, r0, c7, c5, 0 @ invalidate icache mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache mcr p15, 0, r0, c1, c0, 0

ldr sp, =0xD0037D80       @ 設定棧,以便調用c函數 adr r0, _start                    @ 重定位                                       @ _start目前所位于的位址 ldr r1, =_start                  @ _start的連結位址:CONFIG_SYS_TEXT_BASE cmp r0, r1 beq run_on_dram             @ 如果在是連結位址處,則直接運作

bl  uart_init                     @ 初始化序列槽  bl  nand_asm_init            @ NandFlash初始化  bl  mem_init                   @ dram初始化

bl  board_init_f_nand     @ 拷貝bl2代碼到dram中,并運作

run_on_dram:   bl  main                  @ 跳轉 nand_asm_init:   #define ELFIN_GPIO_BASE 0xE0200000  #define ELFIN_NAND_BASE 0xB0E00000 #define NFCONF_VAL    (2<<23)|(7<<12)|(7<<8)|(7<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0) #define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)

//#define  NFCONF_VAL     (0<<25)|(0x3<<23)|(7<<12)|(7<<8)|(7<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0) //#define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(1<<5)|(0x2<<1)|(1<<0)

#define MP01CON_OFFSET 0x2E0 #define MP01PUD_OFFSET 0x2E8 #define MP03CON_OFFSET      0x320 #define MP03PUD_OFFSET      0x328 #define NFCONF_OFFSET       0x00 #define NFCONT_OFFSET       0x04  

ldr r0, =ELFIN_GPIO_BASE

ldr r1, [r0, #MP01CON_OFFSET] bic r1, r1, #(0xf<<8) orr r1, r1, #(0x3<<8) str r1, [r0, #MP01CON_OFFSET]

ldr r1, [r0, #MP01PUD_OFFSET] bic r1, r1, #(0x3<<4) str r1, [r0, #MP01PUD_OFFSET]

ldr r1, [r0, #MP03CON_OFFSET] bic r1, r1, #0xFFFFFF ldr r2, =0x22222222 orr r1, r1, r2 str r1, [r0, #MP03CON_OFFSET]

ldr r1, [r0, #MP03PUD_OFFSET] ldr r2, =0x3fff bic r1, r1, r2 str r1, [r0, #MP03PUD_OFFSET]

ldr r0, =ELFIN_NAND_BASE

ldr r1, [r0, #NFCONF_OFFSET] ldr r2, =0x777F bic r1, r1, r2 ldr r2, =NFCONF_VAL orr r1, r1, r2 str r1, [r0, #NFCONF_OFFSET]

ldr r1, [r0, #NFCONT_OFFSET] ldr r2, =0x707C7 bic r1, r1, r2 ldr r2, =NFCONT_VAL orr r1, r1, r2 str r1, [r0, #NFCONT_OFFSET]

ldr r1, [r0, #NFCONF_OFFSET] orr r1, r1, #0x70 orr r1, r1, #0x7700 str     r1, [r0, #NFCONF_OFFSET]

ldr r1, [r0, #NFCONT_OFFSET] orr r1, r1, #0x03 str     r1, [r0, #NFCONT_OFFSET]

mov pc, lr

例子源代碼: http://arm9home.net/read.php?tid-80458.html

運作截圖:

給S5PV210裸機程式添加啟動代碼

=============================================================================================================

13-06-26更新:

1.在start.S中添加了啟動方式的判斷,可以判斷是從NandFlash啟動還是SD卡啟動:

//判斷啟動方式

#define PRO_ID_BASE            0xE0000000

#define PRO_ID_OFFSET            0x00

#define OMR_OFFSET            0x04

#define BOOT_ONENAND        0x1

#define BOOT_NAND        0x2

#define BOOT_MMCSD        0x3

#define BOOT_NOR        0x4

#define BOOT_SEC_DEV        0x5

#define INF_REG_BASE            0xE010F000

#define INF_REG3_OFFSET            0x0c

        ldr    r0, =PRO_ID_BASE

        ldr    r1, [r0,#OMR_OFFSET]

        bic    r2, r1, #0xffffffc1

        cmp    r2, #0x0        @ 512B 4-cycle

        moveq    r3, #BOOT_NAND

        cmp    r2, #0x2        @ 2KB 5-cycle

        moveq    r3, #BOOT_NAND

        cmp    r2, #0x4        @ 4KB 5-cycle    8-bit ECC

        moveq    r3, #BOOT_NAND

        cmp    r2, #0x6        @ 4KB 5-cycle    16-bit ECC

        moveq    r3, #BOOT_NAND

        cmp    r2, #0x8        @ OneNAND Mux

        moveq    r3, #BOOT_ONENAND

        cmp     r2, #0xc

        moveq   r3, #BOOT_MMCSD    

        cmp     r2, #0x14

        moveq   r3, #BOOT_NOR    

        cmp     r2, #(0x1<<4)

        moveq   r3, #BOOT_SEC_DEV

        ldr    r0, =INF_REG_BASE

        str    r3, [r0, #INF_REG3_OFFSET]

        ldr    r1, [r0, #INF_REG3_OFFSET]

        cmp    r1, #BOOT_NAND        

        beq    nand_boot_210

        cmp     r1, #BOOT_MMCSD

        beq     mmcsd_boot_210

nand_boot_210:

        mov r0, #'N'

        bl  putc

        bl  board_init_f_nand     @ 拷貝bl2代碼到dram中,并運作

mmcsd_boot_210:

        mov r0, #'S'

        bl  putc

        bl  board_init_f_mmc

2.添加了mmc_cp.c其中有從SD卡copy到dram中的程式:

typedef unsigned int (*copy_sd_mmc_to_mem) (\

            unsigned int  channel, \

            unsigned int  start_block, \

             unsigned short block_size, \

            unsigned int  *trg, \

            unsigned int  init);

void copy_code_to_dram(void)

{

    unsigned long ch;

    void (*BL2)(void);

    ch = *(volatile unsigned int *)(0xD0037488);

    unsigned char channel = 0;

    putc('\n');putc('\r');

    putc('B');putc('L');putc('1');putc(' ');putc('V');putc('e');putc('r');putc(':');

    putc('1');putc('3');putc('0');putc('6');putc('2');putc('6');

    putc('\n');putc('\r');

    putc('S');putc('t');putc('a');putc('r');putc('t');putc(' ');putc('c');putc('p');putc(' ');

    putc('\n');putc('\r');

    // 函數指針

    copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem) (*(unsigned int *) (0xD0037F98));

    unsigned int ret;

    // 通道0

    if (ch == 0xEB000000)

        channel = 0;

    // 通道2

    else if (ch == 0xEB200000)

        channel = 2;

    else

        return;

    // 0:channel 0

    // 33:源,代碼位于扇區33,1 sector = 512 bytes

    // COPY_BL2_SIZE/512:長度,拷貝COPY_BL2_SIZE/512 sector,即COPY_BL2_SIZE K

    // CONFIG_SYS_TEXT_BASE:目的,連結位址CONFIG_SYS_TEXT_BASE    

    ret = copy_bl2(channel, 33, COPY_BL2_SIZE/512,(unsigned int *)CONFIG_SYS_TEXT_BASE, 0);

    putc('R');putc('u');putc('n');putc('n');putc('i');putc('n');putc('g');putc('!');putc(' ');

    putc('\n');putc('\r');

    // 跳轉到DRAM

    BL2 = (void *)CONFIG_SYS_TEXT_BASE;

    (*BL2)();

}

void board_init_f_mmc()

{

    copy_code_to_dram();    

}

這個程式來自210的裸機中,紅色的地方原來是unsigned char型的改為了unsigned short型的。

從NandFlash啟動: 

給S5PV210裸機程式添加啟動代碼

從SD卡啟動:(SD卡燒寫可以用dd指令或者用這個“ SD-Flasher for Linux v1.0(210版本) ”) 

給S5PV210裸機程式添加啟動代碼

這次的代碼: 本部分設定了隐藏,您已回複過了,以下是隐藏的内容

給S5PV210裸機程式添加啟動代碼
 13.uart_stdio.tar.gz (280 K) 下載下傳次數:0