我這裏是參考江西理工大學09級-朱兆祺同窗,以及如下博客的資料,通過幾天的痛苦修改後最終移植成功的筆記,在這裏感謝他們html
參考博客:
http://www.linuxidc.com/Linux/2012-09/69918.htm
http://blog.csdn.net/wletv/article/details/7196206linux
http://www.360doc.com/content/12/0720/20/7832126_225499671.shtml 架構
http://blog.163.com/tianjunqiang666@126/blog/static/87259119201243034639891/ide
前提環境:Win7+VirsualBox+ok6410+u-boot-2010.03ui
一,下載u-boot-2010.03源碼spa
ftp://ftp.denx.de/pub/u-boot
解壓,我這裏爲了不麻煩,更改了全部文件的權限.net
tar jxvf u-boot-2010.03.tar.bz2
sudo chmod -R 777 u-boot-2010.03/*
二,修改源碼code
爲了方便修改,查找代碼,你看到u-boot下包含了支持衆多CPU和不一樣架構的代碼,這裏我根據Ok6410開發板的自身狀況,將u-boot下代碼進行精簡:htm
1,進入u-boot-2010.03/board,把除samsung之外的文件夾刪除blog
2,進入u-boot-2010.03/cpu,把除arm1176之外的文件夾刪除
3,進入u-boot-2010.03/include,把asm-*(注意,僅僅是asm-開頭的文件夾)中的,除了asm-arm和asm-generic之外的文件夾刪除。
4,進入u-boot-2010.03/include/configs,只要留下smdk6400.h,其餘的東西刪除
5,進入u-boot-2010.03,把lib_*開頭的文件夾(注意,僅僅是lib-開頭的文件夾),除了lib_arm和lib_generic之外的文件夾刪除
6,進入u-boot-2010.03/nand_spl/board,除了samsung之外的文件夾刪除
進行這六步操做後:嘗試一下編譯,僅僅是嘗試。
make smdk6400_config
make
7,進入u-boot-2010.03/board/samsung,除了smdk6400的文件夾都刪除,創建一個新目錄smdk6410,並將smdk6400裏面的文件給smdk6410拷貝一份過去。
mkdir smdk6410
cp -R smdk6400/* smdk6410/
8,進入u-boot-2010.03/board/samsung/smdk6410文件夾將smdk6400.c改名爲smdk6410.c
a)將smdk6410.c裏面的6400所有改成6410。
b)將lowlevel_init.S,將裏面的6400改成6410。
c)將Makfile,將裏面的6400改成6410。
9,進入u-boot-2010.03\include\asm-arm , 把除了arch-s3c64xx 和proc-armv 以外的文件夾刪除。進入arch-s3c64xx,創建s3c6410.h,
將s3c6400.h 內容複製到s3c6410.h。
cp s3c6400.h s3c6410.h
將s3c6410.h,將裏面的6400改成6410。
10,進入到 include/configs/ 複製smdk6400.h,並將副本改成smdk6410.h。
cp smdk6400.h smdk6410.h
將s3c6410.h,將裏面的6400改成6410。
11,進入u-boot-2010.03/nand_spl/board/samsung/,創建一個新目錄smdk6410,並將smdk6400裏面的文件給smdk6410拷貝一份過去。
mkdir smdk6410
cp -R smdk6400/* smdk6410/
a)將Makefile,裏面的6400改成6410。
12,進入u-boot-2010.03/cpu/arm1176內全部文件以及u-boot-2010.03/cpu/arm1176/s3c64xx/內全部文件中的6400改成6410。
13,進入根目錄下的Makefile,將CROSS_COMPILE ?=改爲爲CROSS_COMPILE ?=arm-linux-
而後搜索6400找到smdk6400的配置代碼:
#########################################################################
## ARM1176 Systems
#########################################################################
smdk6400_noUSB_config \
smdk6400_config : unconfig
@mkdir -p $(obj)include $(obj)board/samsung/smdk6400
@mkdir -p $(obj)nand_spl/board/samsung/smdk6400
@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
@if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \
echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx; \
else \
echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx; \
fi
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
將上面藍色標註的6400,改爲6410
14,進入u-boot-2010.03/cpu/arm1176打開start.S,修改第一處代碼:
//#ifndef CONFIG_NAND_SPL /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache /* Prepare to disable the MMU */ //adr r1, mmu_disable_phys /* We presume we're within the first 1024 bytes */ //and r1, r1, #0x3fc //ldr r2, _TEXT_PHY_BASE //ldr r3, =0xfff00000 //and r2, r2, r3 //orr r2, r2, r1 //b mmu_disable //.align 5 /* Run in a single cache-line */ //mmu_disable: mcr p15, 0, r0, c1, c0, 0 //nop //nop //mov pc, r2 //#endif
藍色部分進行了註釋操做。
15,繼續。仍是u-boot-2010.03/cpu/arm1176/start.S文件,修改第二處代碼:搜索找到 bl lowlevel_init這行代碼:
/********************************** 若是是從nandflash 中啓動,那麼PC 的值必定在4K 以內。那麼執 行完bic r1, pc, r0 以後,r1 爲0。_TEXT_BASE 要麼等於0x57e0 0000,
要麼等於0xC7e0 0000.那麼執行完bic r2, r2, r0 以後,r2 爲0x00e0 0000,那麼不相等,則不跳轉,下面應該就是copy_from_nand。 若是是從ram 中啓動,那麼PC 的值爲0x x7e0 0000。那麼執行完 bic r1, pc, r0 以後,r1 爲0x00e0 0000。_TEXT_BASE 要麼等於0x57e0 0000,要麼等於0xC7e0 0000.那麼執行完bic r2, r2, r0 以後,r2 爲 0x00e0 0000,那麼相等,跳轉到after_copy,也就是不須要copy。 承接上面分析,若是沒有完成copy,則接下來就是copy_from_nand。 那麼在beq after_copy 後面添加: #ifdef CONFIG_BOOT_NAND mov r0, #0x1000 bl copy_from_nand #endif 若是完成則會跳過這段代碼,直接進入after_copy。 **********************************/ /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */ ldr r0,=0xff000fff bic r1,pc,r0 ldr r2,_TEXT_BASE bic r2,r2,r0 cmp r1,r2 beq after_copy #ifdef CONFIG_BOOT_NAND mov r0,#0x1000 bl copy_from_nand #endif
什麼意思暫時沒弄清楚,不過參考的文章上說是:判斷是從nandflash啓動仍是從ram啓動。
16,繼續start.S文件,修改第三處代碼:在
#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word mmu_table
#endif
這段代碼以後加上以下代碼:
/* * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND) * r0: size to be compared * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size */ .globl copy_from_nand copy_from_nand: mov r10, lr /* save return address */ mov r9, r0 /* get ready to call C functions */ ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */ sub sp, sp, #12 mov fp, #0 /* no previous frame, so fp=0 */ mov r9, #0x1000 bl copy_uboot_to_ram 3: tst r0, #0x0 bne copy_failed ldr r0, =0x0c000000 ldr r1, _TEXT_PHY_BASE 1: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne compare_failed /* not matched */ subs r9, r9, #4 bne 1b 4: mov lr, r10 /* all is OK */ mov pc, lr copy_failed: nop /* copy from nand failed */ b copy_failed compare_failed: nop /* compare failed */ b compare_failed
17,u-boot-2010.03/cpu/arm1176/下新建nand_cp.c文件,代碼以下:
#include <common.h> #ifdef CONFIG_S3C64XX #include <asm/io.h> #include <linux/mtd/nand.h> #include <asm/arch/s3c6410.h> static int nandll_read_page (uchar *buf, ulong addr, int large_block) { int i; int page_size = 512; /* 2K */ if (large_block==1) page_size = 2048; /* 4K */ if (large_block==2) page_size = 4096; NAND_ENABLE_CE(); NFCMD_REG = NAND_CMD_READ0; /* Write Address */ NFADDR_REG = 0; if (large_block) NFADDR_REG = 0; NFADDR_REG = (addr) & 0xff; NFADDR_REG = (addr >> 8) & 0xff; NFADDR_REG = (addr >> 16) & 0xff; /* #define NFCMD_REG __REG(ELFIN_NAND_BASE + NFCMMD_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET 0x08 NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008 NAND Flash ÃüÁîÉèÖÌĎæÆ÷0 #define NAND_CMD_READSTART 0x30 */ if (large_block) NFCMD_REG = NAND_CMD_READSTART; /* define NF_TRANSRnB() do { while( !( NFSTAT_REG & (1 << 0) ) ); } while(0) #define NFSTAT_REG __REG(ELFIN_NAND_BASE + NFSTAT_OFFSET) NFSTAT_REG = ( *( (volatile u32 *) (0x70200028) ) ) NFSTAT 0x70200028 NAND Flash ²Ù×÷׎̬ŒÄŽæÆ÷ */ NF_TRANSRnB(); /* for compatibility(2460). u32 cannot be used. by scsuh */ for(i=0; i < page_size; i++) { *buf++ = NFDATA8_REG; } /* #define NAND_DISABLE_CE() (NFCONT_REG |= (1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE + NFCONT_OFFSET) #define __REG(x) (*((volatile u32 *)(x))) #define ELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET 0x04 */ NAND_DISABLE_CE(); return 0; } static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block) { uchar *buf = (uchar *)dst_addr; int i; uint page_shift = 9; if (large_block==1) page_shift = 11; /* Read pages */ if(large_block==2) page_shift = 12; if(large_block == 2) { /* Read pages */ for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1))) { nandll_read_page(buf, i, large_block); } /* Read pages */ /* 0x3c000 = 11 1100 0000 0000 0000 */ for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) { nandll_read_page(buf, i, large_block); } } else { for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) { nandll_read_page(buf, i, large_block); } } return 0; } int copy_uboot_to_ram(void) { int large_block = 0; int i; vu_char id; /* #define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE + NFCONT_OFFSET) #define __REG(x) (*((volatile u32 *)(x))) #define ELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET 0x04 NFCONT_REG = ( *( (volatile u32 *) (0x70200004) ) ) NFCONT 0x70200004 ¶Á/ÐŽNAND Flash ¿ØÖƌĎæÆ÷ [0]1£ºNAND Flash ¿ØÖÆÆ÷ʹÄÜ */ NAND_ENABLE_CE(); /* #define NFCMD_REG __REG(ELFIN_NAND_BASE + NFCMMD_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET 0x08 NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008 NAND Flash ÃüÁîÉèÖÌĎæÆ÷0 #define NAND_CMD_READID 0x90 */ NFCMD_REG = NAND_CMD_READID; /* #define NFADDR_REG __REG(ELFIN_NAND_BASE + NFADDR_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFADDR_OFFSET 0x0C NFADDR_REG = ( *( (volatile u32 *) (0x7020000C) ) ) NFADDR 0x7020000C NAND Flash µØÖ·ÉèÖÌĎæÆ÷ */ NFADDR_REG = 0x00; /* #define NFDATA8_REG __REGb(ELFIN_NAND_BASE + NFDATA_OFFSET) #define __REGb(x) (*(vu_char *)(x)) NFDATA8_REG = ( *( (vu_char *) (0x70200010) ) ) NFDATA 0x70200010 ¶Á/ÐŽNAND Flash ÊýŸÝŒÄŽæÆ÷ NAND Flash ¶Á/ÉÕÐŽÊýŸÝÖµÓÃÓÚI/O */ /* wait for a while */ for (i=0; i<200; i++); id = NFDATA8_REG; id = NFDATA8_REG; if (id > 0x80) large_block = 1; if(id == 0xd5) large_block = 2; /* read NAND Block. * 128KB ->240KB because of U-Boot size increase. by scsuh * So, read 0x3c000 bytes not 0x20000(128KB). */ /* #define CONFIG_SYS_PHY_UBOOT_BASE (CONFIG_SYS_SDRAM_BASE + 0x07e00000) #define CONFIG_SYS_SDRAM_BASE 0x50000000 CONFIG_SYS_PHY_UBOOT_BASE = 0x57e0 0000 0x3 c000 = 1M */ return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block); } #endif
18,u-boot-2010.03/cpu/arm1176/Makefile文件:
COBJS =cpu.o nand_cp.o
如上加入nand_cp.o
19,u-boot-2010.03/include/configs/smdk6410.h文件:
加上這個定義:
#define virt_to_phys(x) virt_to_phy_smdk6410(x)
20:繼續smdk6410.h文件,找到/* NAND configuration */
/* NAND configuration */ #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x70200010 #define CONFIG_SYS_S3C_NAND_HWECC
/* 加上下面三個定義 */ #define NAND_DISABLE_CE()(NFCONT_REG|=(1<<1)) #define NAND_ENABLE_CE()(NFCONT_REG&=~(1<<1)) #define NF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
21:繼續smdk6410.h文件,個人ok6410,內存爲256MB,則須要修改下面(NandFlash每一個塊的大小)
//#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128MB in Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB in Bank #1 */
22:繼續smdk6410.h文件,分配smdk6410的ID號:
//#define MACH_TYPE 1270 #define MACH_TYPE 1626
23,繼續smdk6410.h文件,更改內存的分配大小:
//#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 1024 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 512 * 1024) #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes for initial data */
24,繼續smdk6410.h文件,更改bootdelay時間:
//#define CONFIG_BOOTDELAY 3 #define CONFIG_BOOTDELAY 10
25,繼續smdk6410.h文件,更改SDROM大小:
#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE /* memtest works on */ //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */ #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x9e00000) /* 256MB in DRAM */
26,繼續smdk6410.h文件,修改時間:
//#define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_HZ 1562500
27,繼續smdk6410.h文件,修改堆棧大小:
//#define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */ #define CONFIG_STACKSIZE 0x80000 /* regular stack 512KB */
28,繼續smdk6410.h文件,修改:
//#define CONFIG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE 0x80000 /* Total Size of Environment Sector */
29,繼續smdk6410.h文件,修改CONFIG_BOOTCOMMAND:
//#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \ "bootm 0xc0018000" #define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;" \ "bootm 0x50018000"
30,繼續smdk6410.h文件,修改:
//#define CONFIG_ENV_OFFSET 0x0040000 #define CONFIG_ENV_OFFSET 0x0080000
31,繼續smdk6410.h文件,修改NandFlash每一頁的大小:
//#define CONFIG_SYS_NAND_PAGE_SIZE 2048 #define CONFIG_SYS_NAND_PAGE_SIZE 4096
32,繼續smdk6410.h文件,修改NandFlash每一塊的大小:
//#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) #define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)
33,繼續/smdk6410.h文件,修改校驗位:
//#define CONFIG_SYS_NAND_PAGE_COUNT 64 #define CONFIG_SYS_NAND_PAGE_COUNT 128
34,修改u-boot-2010.03/board/samsung/smdk6410下u-boot-nand.lds,添加藍色部分:
SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/arm1176/start.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/nand_cp.o (.text) lib_arm/board.o (.text) *(.text) } .... }
35,修改u-boot-2010.03/cpu/arm1176下u-boot.lds,添加藍色部分:
SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/arm1176/start.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) cpu/arm1176/nand_cp.o (.text) *(.text) } .... }
36,進入u-boot-2010.03/nand_spl/board/samsung/smdk6410/,修改Makefile文件:
1,在$(obj)cpu_init.S:
@rm -f $@
@ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@
以後添加:
$(obj)nand_cp.c:
@rm -f $@
@ln -s $(TOPDIR)/cpu/arm1176/nand_cp.c $@
2,在COBJS後面加上 nand_cp.o
SOBJS = start.o cpu_init.o lowlevel_init.o COBJS = nand_boot.o nand_ecc.o s3c64xx.o nand_cp.o
如上加入nand_cp.o
三,編譯
編譯以後,能夠在開發板上運行成功,後面有補充,會及時更新。
make smdk6410_config
make