移植屬於自己的6410開發板的U-Boot


學習了幾個月的關於嵌入式相關的知識,之前一直覺得自己能力不夠,去研究uboot很有難度,現在通過幾個月的學習,再去研究uboot應該可以理解了,於是就開始自己的移植之旅!

       首先在網上搜索關於6410uboot的移植的相關信息,資料有點少,都是關於2410的,偶然看到一篇關於《基於OK6410的u-boot2010.03移植過程》的文章,原來已經有朋友移植成功了的,我們就得參照一下,站在巨人的肩膀上嘛。我就詳細的把我移植的過程及其中遇到的問題說說:

准備階段:

      主機環境:Ubuntu11.10

      目標機:  飛凌-OK6410-A

      編譯環境:arm-linux-gcc-4.3.2

 

      源碼下載:ftp://ftp.denx.de/pub/u-boot/

       下載u-boot-2010.03(本來想追求最新的,但這以后的版本跟這以前的就不同了,所以先把老版本弄清楚吧),我下載到桌面;

#tar xvf u-boot-2010.03.tar.bz2

#ls

       你看到大多目錄跟Linux源碼結構很像,分析步驟跟分析linux源碼差不多,我們先編譯體驗一下,同時驗證一下能否編譯通過;

#cd u-boot-2010.03

#make smdk6400_config

#make

#ls

在文件夾根目錄下生成u-boot.bin文件,這就是我們要下載到開發板上的可執行文件。

 

源碼修改階段:

      進入u-boot-2010.03/board/samsung,建立smdk6410文件夾,把smdk6400內的所有文件復制到smdk6410中,進smdk6410中將smdk6400.c改為smdk6410.c。(6400與6410大體是一樣的);

#cd board/samsung

#mkdir smdk6410

#cp smdk6400/* smdk6410/

#mv smdk6410/smdk6400.c smdk6410/smdk6410.c

     進入u-boot-2010.03/include/asm-arm/arch-s3c64xx,復制s3c6400.h並改為s3c6410.h

#cd ../../include/asm-arm/arch-s3c64xx

#cp s3c6400.h s3c6410.h

     進入根目錄,打開Makefile,找到下面的代碼:

smdk6400_noUSB_config \
smdk6400_config : unconfig
@mkdir-p$(obj)include$(obj)board/samsung/smdk6400
@mkdir-p$(obj)nand_spl/board/samsung/smdk6400
@echo"#defineCONFIG_NAND_U_BOOT">$(obj)include/config.h
@if[-z"$(findstringsmdk6400_noUSB_config,$@)"];then \
echo"RAM_TEXT=0x57e00000">>$(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG)$(@:_config=)armarm1176smdk6400samsungs3c64xx; \
else \
echo"RAM_TEXT=0xc7e00000">>$(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG)$(@:_noUSB_config=)armarm1176smdk6400samsungs3c64xx;\
fi
@echo"CONFIG_NAND_U_BOOT=y">>$(obj)include/config.mk

     上面是6400的配置文件,將里面的6400都改為6410;

smdk6410_noUSB_config \
smdk6410_config : unconfig
@mkdir-p$(obj)include$(obj)board/samsung/smdk6410
@mkdir-p$(obj)nand_spl/board/samsung/smdk6410
@echo"#defineCONFIG_NAND_U_BOOT">$(obj)include/config.h
@if[-z"$(findstringsmdk6410_noUSB_config,$@)"];then \
echo"RAM_TEXT=0x57e00000">>$(obj)board/samsung/smdk6410/config.tmp;\
$(MKCONFIG)$(@:_config=)armarm1176smdk6410samsungs3c64xx; \
else \
echo"RAM_TEXT=0xc7e00000">>$(obj)board/samsung/smdk6410/config.tmp;\
$(MKCONFIG)$(@:_noUSB_config=)armarm1176smdk6410samsungs3c64xx;\

     進入u-boot-2010.03/board/samsung/smdk6410,編輯smdk6410,把#include <asm/arch/s3c6400.h> 改為 #include <asm/arch/s3c6410.h

     下面就要修改啟動代碼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
mcr p15, 0, r0, c1, c0, 0//從后面拷貝過來的
///////////////////////////////以下的注釋掉

/* 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
/////////////////////////////////////////////////////////////////////////////////////////////////////  

第二處修改:

bl lowlevel_init /* go setup pll,mux,memory */  之后


/* when we already run in ram, we don't need to relocate U-Boot.////////////////////////////////////////////////////////////////////
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
 ldr r0, =0xff000fff
 bic r1, pc, r0  /* r0 <- current base addr of code */
 ldr r2, _TEXT_BASE  /* r1 <- original base addr in ram */
 bic r2, r2, r0  /* r0 <- current base addr of code */
 cmp     r1, r2                  /* compare r0, r1                  */
 beq      after_copy  /* r0 == r1 then skip flash copy   */
#ifdef CONFIG_BOOT_NAND
  mov r0, #0x1000
 bl copy_from_nand
#endif 
after_copy://///////////////////////////////////////////////////////////////////////////////////////////////
#ifdef CONFIG_ENABLE_MMU   

上面的修改是判斷到底是從Nand Flash啟動還是RAM啟動;

1.如果是從nandflash中啟動,那么PC的值一定在4K之內。那么執行完bicr1,pc,r0 之后,r1為0。_TEXT_BASE要么等於0x57e00000,要么等於0xC7e00000.那么執行完bicr2,r2,r0 之后,r2為0x00e00000,那么不相等,則不跳轉,下面應該就是copy_from_nand。
2.如果是從ram中啟動,那么PC的值為0xx7e00000。那么執行完bicr1,pc,r0 之后,r1為0x00e00000。_TEXT_BASE要么等於0x57e00000,要么等於0xC7e00000.那么執行完bicr2,r2,r0 之后,r2為0x00e00000,那么相等,跳轉到after_copy,也就是不需要copy。承接上面分析,如果沒有完成copy,則接下來就是copy_from_nand。

第三處修改:

#ifndef CONFIG_NAND_SPL
/*
 * we assume that cache operation is done before. (eg. cleanup_before_linux())
 * actually, we don't need to do anything about cache if not use d-cache in
 * U-Boot. So, in this function we clean only MMU. by scsuh
 *
 * void theLastJump(void *kernel, int arch_num, uint boot_params);
 */
#ifdef CONFIG_ENABLE_MMU
 .globl theLastJump
theLastJump:  
之前加上以下語句

/*
 * 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   

      接着進入u-boot-2010.03/include/configs編輯smdk6410.h,添加下面的宏定義;

1.

#definevirt_to_phys(x) virt_to_phy_smdk6410(x)

2.

#defineCONFIG_SYS_PROMPT "SMDK6410#" /*MonitorCommandPrompt */
這里的”SMDK6410”可以自己修改,這就是你進入uboot的命令模式的#前面的文字。
3.
//#definePHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
#definePHYS_SDRAM_1_SIZE 0x10000000 /*256MBinBank#1 */
修改SDRAM內存為256M的。
4.
/*NANDconfiguration*/
#defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
#defineNAND_ENABLE_CE()(NFCONT_REG&=~(1<<1))
#defineNF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
這里的定義是后面寫nand_cp.c要用到的宏定義
5.
/*
*Architecturemagicandmachinetype
*/
//#define MACH_TYPE 1270/*smdk6400ID*/
#defineMACH_TYPE 1626/*smdk6410ID*/
6410的ID號;
6.
/*
*Sizeofmalloc()pool
*/
//#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+1024*1024)
#defineCONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+512*1024)
#defineCONFIG_SYS_GBL_DATA_SIZE 128 /*sizeinbytesforinitialdata*/
修改內存大小;
7.
#defineCONFIG_BOOTDELAY 3
修改bootdelay延遲時間
8.
//#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x7e00000)
/*126MBinDRAM*/
#defineCONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x9e00000)
/*256MBinDRAM*/
修改SDROM大小;
9.
/*the PWMTImer4usesacounterof15625for10ms,soweneed*/
/*ittowrap100times (total1562500)toget1sec.*/
//#define CONFIG_SYS_HZ 1000 //atPCLK50MHz
#defineCONFIG_SYS_HZ 1562500
時鍾修改;
10.
//#define CONFIG_STACKSIZE 0x40000 /*regularstack256KB*/
#defineCONFIG_STACKSIZE 0x80000 /*regularstack512KB*/
堆棧大小修改;
11.
//#define PHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
#definePHYS_SDRAM_1_SIZE0x10000000 /*256MBinBank#1 */
Nand Flash每塊大小修改;
12.
//#define CONFIG_ENV_SIZE 0x4000 /*TotalSizeofEnvironmentSector*/
#defineCONFIG_ENV_SIZE 0x80000 /*TotalSizeofEnvironmentSector*/
Total Size of Environment Sector修改;
13.
//#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x60000 0x1c0000;"\
//"bootm0x50018000"
#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;"\
"bootm0x50018000"
CONFIG_BOOTCOMMAND修改
14.
#defineCONFIG_ENV_OFFSET 0x0080000
CONFIG_ENV_OFFSET修改
15.
//#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#defineCONFIG_SYS_NAND_PAGE_SIZE 4096
Nand Flash每一頁大小的修改
16.
/*NANDchipblocksize */
//#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
#defineCONFIG_SYS_NAND_BLOCK_SIZE (512*1024)
Nand Flash每一塊大小的修改
17.
/*NANDchippageperblockcount */
//#define CONFIG_SYS_NAND_PAGE_COUNT 64
#defineCONFIG_SYS_NAND_PAGE_COUNT 128
校驗位修改
並將里面的所有6400替換為6410
 
   接下來在u-boot-2010.03/cpu/arm1176/下面新建一個nand_cp.c文件,代碼如下:
#include<common.h>
#ifdefCONFIG_S3C64XX
#include<asm/io.h>
#include<linux/mtd/nand.h>
#include<asm/arch/s3c6410.h>
staticintnandll_read_page(uchar*buf,ulongaddr,intlarge_block)
{
inti;
intpage_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;
/*WriteAddress*/
NFADDR_REG=0;
if(large_block)
NFADDR_REG=0;
NFADDR_REG=(addr)&0xff;
NFADDR_REG=(addr>>8)&0xff;
NFADDR_REG=(addr>>16)&0xff;
/*
#defineNFCMD_REG
__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFCMMD_OFFSET 0x08
NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
NFCMMD 0x70200008 NANDFlash命令設置寄存器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=(*( (volatileu32*) (0x70200028) ))
NFSTAT 0x70200028 NANDFlash操作狀態寄存器
*/
NF_TRANSRnB();
/*forcompatibility(2460).u32cannotbeused.byscsuh*/
for(i=0;i<page_size;i++)
{
*buf++=NFDATA8_REG;
}
/*
#defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
#defineNFCONT_REG
__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
#define__REG(x) (*((volatileu32*)(x)))
#defineELFIN_NAND_BASE 0x70200000
#defineNFCONT_OFFSET 0x04
*/
NAND_DISABLE_CE();
return0;
}
staticintnandll_read_blocks(ulongdst_addr,ulongsize,int large_block)
{
uchar*buf=(uchar*)dst_addr;
inti;
uintpage_shift=9;
if(large_block==1)
page_shift=11;
/*Readpages*/
if(large_block==2)
page_shift=12;
if(large_block==2)
{
/*Readpages*/
for(i=0;i<4;i++,buf+=(1<<(page_shift-1)))
{
nandll_read_page(buf,i,large_block);
}
/*Readpages*/
/* 0x3c000 = 111100000000000000 */
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);
}
}
return0;
}
intcopy_uboot_to_ram(void)
{
intlarge_block =0;
inti;
vu_charid;
/*
#defineNAND_ENABLE_CE() (NFCONT_REG&=~(1<<1))
#defineNFCONT_REG
__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
#define__REG(x) (*((volatileu32*)(x)))
#defineELFIN_NAND_BASE 0x70200000
#defineNFCONT_OFFSET 0x04
NFCONT_REG=(*( (volatileu32*) (0x70200004) ))
NFCONT0x70200004 讀/寫NANDFlash控制寄存器
[0]1:NANDFlash控制器使能
*/
NAND_ENABLE_CE();
/*
#defineNFCMD_REG
__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFCMMD_OFFSET 0x08
NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
NFCMMD 0x70200008 NANDFlash命令設置寄存器0
#defineNAND_CMD_READID 0x90
*/
NFCMD_REG=NAND_CMD_READID;
*
#defineNFADDR_REG
__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFADDR_OFFSET 0x0C
NFADDR_REG =(*( (volatileu32*) (0x7020000C) ))
NFADDR0x7020000C NANDFlash地址設置寄存器
*/
NFADDR_REG= 0x00;
/*
#define NFDATA8_REG
__REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
#define__REGb(x) (*(vu_char*)(x))
NFDATA8_REG = (*( (vu_char*) (0x70200010) ))
NFDATA0x70200010 讀/寫NANDFlash數據寄存器
NANDFlash 讀/燒寫數據值用於I/O
*/
/*waitforawhile*/
for(i=0;i<200;i++);
id=NFDATA8_REG;
id=NFDATA8_REG;
if(id>0x80)
large_block=1;
if(id ==0xd5)
large_block=2;
/*readNANDBlock.
*128KB->240KBbecauseofU-Bootsizeincrease.byscsuh
*So,read0x3c000bytesnot0x20000(128KB).
*/
/*
#define CONFIG_SYS_PHY_UBOOT_BASE
(CONFIG_SYS_SDRAM_BASE+0x07e00000)
#define CONFIG_SYS_SDRAM_BASE 0x50000000
CONFIG_SYS_PHY_UBOOT_BASE= 0x57e00000
0x3c000 = 1M
*/
returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,0x3c000,large_block);
}
#endif
 
   修改u-boot-2010.03/cpu/arm1176/Makefile,在COBJS = cpu.o后面加nand_cp.o
COBJS	= cpu.o nand_cp.o
   修改u-boot-2010.03/board/samsung/smdk6410/u-boot-nand.lds,添加nand_cp.o 如下:
{
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)
}
   修改u-boot-2010.03/cpu/arm1176/u-boot.lds,添加nand_cp.o,如下:
{
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)
}
   進入u-boot-2010.03/nand_spl/board/samsung,復制一個smdk6410,修改Makefile,作如下修改:
COBJS =nand_boot.onand_ecc.os3c64xx.onand_cp.o
在下面代碼
#fromSoCdirectory
$(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$@
   修改u-boot-2010.03/board/samsung/smdk6410/lowlevel_init.S,修改/*LEDononly#8*/LED燈的測試代碼,將所有燈點亮,修改為:
/* LED on only #8 */
	
ldr	r0, =ELFIN_GPIO_BASE
	
ldr	r1, =0x0001111
	
str	r1, [r0, #GPMCON_OFFSET]


	
ldr	r1, 0x000aaa
	
str	r1, [r0, #GPNPUD_OFFSET]


	
ldr	r1, =0x0000	
str	r1, [r0, #GPNDAT_OFFSET]
配置,編譯,生成u-boot.bin,下到開發板上如下所示:
U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410



CPU:     S3C6400@533MHz
         
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 

Board:   SMDK6410

DRAM:  256 MB

Flash:  0 kB

NAND:  No oob scheme define for oobsize 32
 
2048 MiB

*** Warning - bad CRC, using default environment                                
                                                                
In:serial 
                                                          
Out:serial  
                                                         
Err:serial 
                                                          
Net:cs8900  
                                                        
Hit any key to stop autoboot:  0 

板子上的4盞LED全亮!
這就完成了u-boot移植的第一步。
 
網卡DM9000移植:
   在u-boot-2010.03/include/configs/smdk6410.h中將CS8900的宏定義注釋掉:
//#define CONFIG_NET_MULTI
//#define CONFIG_CS8900 /*wehaveaCS8900on-board*/
//#define CONFIG_CS8900_BASE 0x18800300
//#define CONFIG_CS8900_BUS16 /*followthe Linuxdriver*/
然后添加DM9000網卡的宏定義:
#defineCONFIG_NET_MULTI 1
#defineCONFIG_DM9000_NO_SROM 1
#defineCONFIG_dm9000
#defineCONFIG_DRIVER_DM9000 1
#defineCONFIG_DM9000_BASE 0x18800300
#defineDM9000_IO CONFIG_DM9000_BASE
#defineDM9000_DATA (CONFIG_DM9000_BASE+4)
#defineCONFIG_DM9000_USE_16BIT
#defineCONFIG_ETHADDR 00:40:5c:26:0a:5b
#defineCONFIG_NETMASK 255.255.255.0
#defineCONFIG_IPADDR 192.168.1.20
#defineCONFIG_SERVERIP 192.168.1.10
#defineCONFIG_GATEWAYIP 192.168.1.1
//#define CONFIG_DM9000_DEBUG
上面的IP和網關、子網掩碼等根據自己的具體情況進行修改。接着打開u-boot-2010.03/net/eth.c,並且進入到函數inteth_initialize(bd_t*bis)中,在:
#ifdefined(CONFIG_DB64460)|| defined(CONFIG_P3Mx)
mv6446x_eth_initialize(bis);
#endif

后面添加:

 

同樣在u-boot-2010.03/net/net.c,
1.將
#defineARP_TIMEOUT 5000UL /*MillisecondsbeforetryingARPagain*/
修改為
#defineARP_TIMEOUT 5 /*MillisecondsbeforetryingARPagain*/

2. 將

if((t-NetArpWaitTimerStart)>ARP_TIMEOUT)

修改為

if((t-NetArpWaitTimerStart)>ARP_TIMEOUT*CONFIG_SYS_HZ

3. 將

NetSetTimeout(10000UL,PingTimeout);

修改為

NetSetTimeout(10*CONFIG_SYS_HZ,PingTimeout);

接着進入u-boot-2010.03/net/tftp.c,找到void TftpStart(void)函數,用#if0 #endif注釋掉下面的程序:

#if0
/*
*Allowthe usertochooseTFTPblocksizeandtimeout
*TFTPprotocolhasaminimaltimeoutof1second.
*/
if((ep=getenv("tftpblocksize"))!=NULL)
TftpBlkSizeOption=simple_strtol(ep,NULL,10);
if((ep=getenv("tftptimeout"))!=NULL)
TftpTimeoutMSecs=simple_strtol(ep,NULL,10);
if(TftpTimeoutMSecs<1000){
printf("TFTPtimeout(%ldms)toolow,"
"setminimum=1000ms\n",
TftpTimeoutMSecs);
TftpTimeoutMSecs=1000;
}
debug("TFTPblocksize=%i,timeout=%ldms\n",
TftpBlkSizeOption,TftpTimeoutMSecs);
#endif

再編譯,下載,運行情況如下:

U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410



CPU:     S3C6400@533MHz
         
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 

Board:   SMDK6410

DRAM:  256 MB

Flash:  0 kB

NAND:  No oob scheme define for oobsize 32
 
2048 MiB

*** Warning - bad CRC, using default environment                                
                                                                                

In:    serial                                                                   

Out:   serial                                                                   

Err:   serial   
                                                                
Net:   dm9000                                                                  
 

Hit any key to stop autoboot:  0 

 

Nandflash讀寫:

nandflash的控制都是這個套路,因為這就是硬件協議,先使能芯片->發送命令->發送地址序列->讀或寫數據寄存器->判斷准備就緒狀態->禁止芯片,這是對nand flash操作的大體過程,根據發送命令的不同還有些區別。

 

   進入u-boot-2010.03/driver/mtd/nand/,修改nand_ids.c,作如下修改:

//{"NAND 2GiB3,3V8-bit",0xD5,0,2048,0,LP_OPTIONS},
{"NAND2GiB3,3V8-bit", 0xD5,4096,2048,512*1024,LP_OPTIONS},

 

編譯下載,運行如下:

U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410



CPU:     S3C6400@533MHz
         
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 

Board:   SMDK6410

DRAM:  256 MB

Flash:  0 kB

NAND:  raise: Signal # 8 caught

raise: Signal # 8 caught

raise: Signal # 8 caught

2048 MiB

*** Warning - bad CRC, using default environment                                
                                                                                

In:    serial                                                                   

Out:   serial                                                                   

Err:   serial 
                                                                  
Net:   dm9000                                                                  
 

Hit any key to stop autoboot:  0 

 

在NAND: 后面出現raise: Signal # 8 caught這些信息,雖然不影響運行,但是確實是一個BUG,花了一天的時間在網上查了一下,都是關於2410的,偶然在網上看到一位朋友也是碰到同樣的問題,修改跟移植2410的一樣處理,我試了,

修改/cpu/arm/arm1176/s3c64xx/timer.c,
imer_load_val用gd->timer_rate_hz替代;
timer_clk用gd->tbl替代;
timestamp用gd->timer_reset_value替代;
lastdec用gd->lastinc替代。

編譯的時候出現gd_t這個結構體根本就沒有timer_rate_hz這幾個成員變量,可能是版本的原因,在論壇上求助說修改lib_arm/eabi_compact.c,直接將printf("raise: Signal # %d caught\n", signum);注釋掉,至今我是這樣解決的,不影響啟動。修改后啟動如下:

U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410



CPU:     S3C6400@533MHz
         
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 

Board:   SMDK6410

DRAM:  256 MB

Flash:  0 kB

NAND:  2048 MiB

*** Warning - bad CRC, using default environment                                
                                                                                

In:    serial                                                                   

Out:   serial                                                                   

Err:   serial  
                                                                 
Net:   dm9000                                                                  
 

Hit any key to stop autoboot:  0 

 

這下正常了!

 

添加自己的命令:

    boot有許多指令,nandinfo,set 等等。現在我們來給u-boot添加我們想要的指令。

U-Boot的每一個命令都是通過U_Boot_CMD宏定義的。這個宏在include/command.h頭文件中定義,每一個命令定義一個cmd_tbl_t結構體。

這樣每一個U-Boot命令有一個結構體來描述。結構體包含的成員變量:命令名稱、最大參數個數、重復數、命令執行函數、用法、幫助。

從控制台輸入的命令是由common/command.c中的程序解釋執行的。(這就是我要找的)find_cmd()負責匹配輸入的命令,從列表中找出對應的命令結構體。

基於U-Boot命令的基本框架,來分析一下簡單的icache操作命令,就可以知道添加新命令的方法。

(1)定義CACHE命令。在include/cmd_confdefs.h中定義了所有U-Boot命令的標志位。

如果有更多的命令,也要在這里添加定義。

(2)實現CACHE命令的操作函數。下面是common/cmd_cache.c文件中icache命令部分的代碼。

U-Boot的命令都是通過結構體__U_Boot_cmd_##name來描述的。根據U_Boot_CMD在include/command.h中的兩行定義可以明白。

還有,不要忘了在common/Makefile中添加編譯的目標文件。

(3)打開CONFIG_COMMANDS選項的命令標志位。這個程序文件開頭有#if語句需要預處理是否包含這個命令函數。CONFIG_COMMANDS選項在開發板的配置文件中定義。例如:SMDK2410平台在include/configs/smdk2410.h中有如下定義。

按照這3步,就可以添加新的U-Boot命令。

 

這下我們就知道怎樣添加自己的Uboot命令了,下面我以添加info命令為例:

1. 進入u-boot-2010.03/commom文件夾,新建cmd_info.c文件。代碼如下:

#include<common.h>
#include<command.h>
int do_info(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])
{
printf("u-boot is made by lixiaoming!\n");
return0;
}
U_BOOT_CMD(info,CONFIG_SYS_MAXARGS,1,do_info,"usageinfo", "helpinfo");

2. 然后在common/Makefile 中 的#command 添 加 如 下 內 容 :

COBJS-$(CONFIG_CMD_INFO)+=cmd_hello.o

3. 在u-boot-2010.03/include/config_cmd_default.h中添加CONFIG_CMD_INFO命令,同時也在config_cmd_all.c中定義

這下編譯,下載,運行進入uboot命令模式后輸入:info,就會顯示信息了;

SMDK6410# info
u-boot is made by lixiaoming!

 

內核引導:

由於uboot只能引導uImage,因此需要把編譯成的zImage轉換成uImage,先進入u-boot根目錄下,把tools/下mkimage復制到主機的/bin目錄下,然后進入到linux-3.0.4/下輸入指令:make uImage。

#defineCONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=yaffs2 console=ttySAC0,115200"

是在smdk6410.h里面。這要根據linux內核mach-ok6410.c中的:

staticstructmtd_partitionok6410_nand_part[]={
{
.name ="Bootloader",
.offset =0,
.size =(1*SZ_1M),
.mask_flags =MTD_CAP_NANDFLASH,
},
{
.name ="Kernel",
.offset =(1*SZ_1M),
.size =(5*SZ_1M),
.mask_flags =MTD_CAP_NANDFLASH,
},
{
.name ="User",
.offset =(6*SZ_1M),
.size =(120*SZ_1M),
},
{
.name ="FileSystem",
.offset =MTDPART_OFS_APPEND,
.size =MTDPART_SIZ_FULL,
}
};

上面主要是對MTD進行分區,可以自己分配,不過一定要把Uboot與內核結合起來。

 

  到此,自己的6410開發板的Uboot基本移植成功,現在自己可以添加命令了,后面的就可以添加啟動后進入主菜單實現下載等功能的命令,在后面的幾天我也移植了Linux3.0.4內核到開發板上,成功運行,並移植支持yaff2文件系統的讀寫,再后面自己制作文件系統鏡像,成功運行完整的嵌入式系統!

在移植的過程中感謝網上朋友的無私分享,我也記錄一下自己的移植工程,與大家一起共同進步,有一天可以成為嵌入式牛人!

參照文章:

寧靜致遠的文章《基於OK6410的u-boot2010.03移植過程》 (http://wenku.baidu.com/view/ae78a00390c69ec3d5bb75ce.html?st=1

懶惰人的懶惰事 (http://hi.baidu.com/shangyefeng/item/4df893ee978c5e245b2d646f


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM