参考:http://www.cnblogs.com/lixiaoming90/archive/2012/08/10/2633151.html
源码下载:ftp://ftp.denx.de/pub/u-boot/
下载u-boot-2010.03
----------------------------------------------------------
使用环境
PC: Centos5.4
kernel: 3.0.1
corss: arm-linux-gcc 4.4.1
arm: s3c6410
uboot: uboot-2010-03
----------------------------------------------------------
第一处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef CONFIG_NAND_SPL/* * flush v4 I/D caches */mov r0, #0mcr 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, 0bic 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) Alignorr r0, r0, #0x00001000 @ set bit 12 (I) I-Cachemcr 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/ |
第二处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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。
第三处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #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 theLastJumptheLastJump: 之前加上以下语句 /* * 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_BASE1: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne compare_failed /* not matched */ subs r9, r9, #4 bne 1b4: mov lr, r10 /* all is OK */ mov pc, lrcopy_failed: nop /* copy from nand failed */ b copy_failedcompare_failed: nop /* compare failed */ b compare_failed |
接着进入u-boot-2010.03/include/configs编辑smdk6410.h,添加下面的宏定义;
1.
1 | #definevirt_to_phys(x) virt_to_phy_smdk6410(x) |
2.
1 | #defineCONFIG_SYS_PROMPT "SMDK6410#" /*MonitorCommandPrompt */ |
1 | 这里的”SMDK6410”可以自己修改,这就是你进入uboot的命令模式的#前面的文字。 |
1 |
1 2 | //#definePHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */#definePHYS_SDRAM_1_SIZE 0x10000000 /*256MBinBank#1 */ |
1 | 修改SDRAM内存为256M的。 |
1 |
1 2 3 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) |
1 | 这里的定义是后面写nand_cp.c要用到的宏定义 |
1 |
1 2 3 4 5 | /**Architecturemagicandmachinetype*///#define MACH_TYPE 1270/*smdk6400ID*/#defineMACH_TYPE 1626/*smdk6410ID*/ |
1 | 6410的ID号; |
1 |
1 2 3 4 5 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*/ |
1 | 修改内存大小; |
1 |
1 | #defineCONFIG_BOOTDELAY 3 |
1 | 修改bootdelay延迟时间 |
1 |
1 2 3 4 | //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x7e00000)/*126MBinDRAM*/#defineCONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x9e00000)/*256MBinDRAM*/ |
1 | 修改SDROM大小; |
1 |
1 2 3 4 | /*the PWMTImer4usesacounterof15625for10ms,soweneed*//*ittowrap100times (total1562500)toget1sec.*///#define CONFIG_SYS_HZ 1000 //atPCLK50MHz#defineCONFIG_SYS_HZ 1562500 |
1 | 时钟修改; |
1 | 10. |
1 2 | //#define CONFIG_STACKSIZE 0x40000 /*regularstack256KB*/#defineCONFIG_STACKSIZE 0x80000 /*regularstack512KB*/ |
1 | 堆栈大小修改; |
1 | 11. |
1 2 | //#define PHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */#definePHYS_SDRAM_1_SIZE0x10000000 /*256MBinBank#1 */ |
1 | Nand Flash每块大小修改; |
1 | 12. |
1 2 | //#define CONFIG_ENV_SIZE 0x4000 /*TotalSizeofEnvironmentSector*/#defineCONFIG_ENV_SIZE 0x80000 /*TotalSizeofEnvironmentSector*/ |
1 | Total Size of Environment Sector修改; |
1 | 13. |
1 2 3 4 | //#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x60000 0x1c0000;"\//"bootm0x50018000"#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;"\"bootm0x50018000" |
1 | CONFIG_BOOTCOMMAND修改 |
1 | 14. |
1 | #defineCONFIG_ENV_OFFSET 0x0080000 |
1 | CONFIG_ENV_OFFSET修改 |
1 | 15. |
1 2 | //#define CONFIG_SYS_NAND_PAGE_SIZE 2048#defineCONFIG_SYS_NAND_PAGE_SIZE 4096 |
1 | Nand Flash每一页大小的修改 |
1 | 16. |
1 2 3 | /*NANDchipblocksize *///#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)#defineCONFIG_SYS_NAND_BLOCK_SIZE (512*1024) |
1 | Nand Flash每一块大小的修改 |
1 | 17. |
1 2 3 | /*NANDchippageperblockcount *///#define CONFIG_SYS_NAND_PAGE_COUNT 64#defineCONFIG_SYS_NAND_PAGE_COUNT 128 |
1 | 校验位修改 |
1 | 并将里面的所有6400除了(#define CONFIG_S3C6400 1)替换为6410 |
1 | |
1 | 接下来在u-boot-2010.03/cpu/arm1176/下面新建一个nand_cp.c文件,代码如下: |
1 2 3 4 | #include<common.h>#ifdefCONFIG_S3C64XX#include<asm/io.h>#include<linux/mtd/nand.h> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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; |
1 2 3 4 5 6 7 8 9 10 | 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 0x08NFCMD_REG=(*( (volatileu32*) (0x70200008) ))NFCMMD 0x70200008 NANDFlash命令设置寄存器0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #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(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /*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;} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 */ |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | }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 0x04NFCONT_REG=(*( (volatileu32*) (0x70200004) ))NFCONT0x70200004 读/写NANDFlash控制寄存器[0]1:NANDFlash控制器使能*/NAND_ENABLE_CE(); |
1 2 3 4 5 6 7 8 | /*#defineNFCMD_REG__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)#defineELFIN_NAND_BASE 0x70200000#defineNFCMMD_OFFSET 0x08NFCMD_REG=(*( (volatileu32*) (0x70200008) ))NFCMMD 0x70200008 NANDFlash命令设置寄存器0#defineNAND_CMD_READID 0x90 |
1 2 3 4 5 6 7 8 9 10 11 | */NFCMD_REG=NAND_CMD_READID;*#defineNFADDR_REG__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)#defineELFIN_NAND_BASE 0x70200000#defineNFADDR_OFFSET 0x0CNFADDR_REG =(*( (volatileu32*) (0x7020000C) ))NFADDR0x7020000C NANDFlash地址设置寄存器*/NFADDR_REG= 0x00; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /*#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; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /*readNANDBlock.*128KB->240KBbecauseofU-Bootsizeincrease.byscsuh*So,read0x3c000bytesnot0x20000(128KB).*//*#define CONFIG_SYS_PHY_UBOOT_BASE(CONFIG_SYS_SDRAM_BASE+0x07e00000)#define CONFIG_SYS_SDRAM_BASE 0x50000000CONFIG_SYS_PHY_UBOOT_BASE= 0x57e000000x3c000 = 1M*/returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,0x3c000,large_block);}#endif |
1 | |
1 | 修改u-boot-2010.03/cpu/arm1176/Makefile,在COBJS = cpu.o后面加nand_cp.o |
1 | COBJS = cpu.o nand_cp.o |
1 | 修改u-boot-2010.03/board/samsung/smdk6410/u-boot-nand.lds,添加nand_cp.o 如下: |
1 2 3 4 5 6 7 8 | {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)} |
1 | 修改u-boot-2010.03/cpu/arm1176/u-boot.lds,添加nand_cp.o,如下: |
1 2 3 4 5 6 7 8 | {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)} |
1 | 进入u-boot-2010.03/nand_spl/board/samsung,复制一个smdk6410,修改Makefile,作如下修改: |
1 | COBJS =nand_boot.onand_ecc.os3c64xx.onand_cp.o |
1 | 在下面代码 |
1 2 3 4 | #fromSoCdirectory$(obj)cpu_init.S:@ rm -f$@@ ln -s$(TOPDIR) /cpu/arm1176/s3c64xx/cpu_init .S$@ |
1 | 之后添加 |
1 2 3 | $(obj)nand_cp.c:@ rm -f$@@ ln -s$(TOPDIR) /cpu/arm1176/nand_cp .c$@ |
1 | 修改u-boot-2010.03/board/samsung/smdk6410/lowlevel_init.S,修改 /*LEDononly#8*/ LED灯的测试代码,将所有灯点亮,修改为: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* 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] |
1 | 配置,编译,生成u-boot.bin,下到开发板上如下所示: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
1 | |
1 2 3 4 5 | 2048 MiB *** Warning - bad CRC, using default environment In:serial |
1 2 | Out:serial |
1 2 | Err:serial |
1 2 | Net:cs8900 |
1 2 3 4 | Hit any key to stop autoboot: 0 板子上的4盏LED全亮! |
1 | 这就完成了u-boot移植的第一步。 |
1 | |
1 | 网卡DM9000移植: |
1 | 在u-boot-2010.03 /include/configs/smdk6410 .h中将CS8900的宏定义注释掉: |
1 2 3 4 | // #define CONFIG_NET_MULTI// #define CONFIG_CS8900 /*wehaveaCS8900on-board*/// #define CONFIG_CS8900_BASE 0x18800300// #define CONFIG_CS8900_BUS16 /*followthe Linuxdriver*/ |
1 | 然后添加DM9000网卡的宏定义: |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #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 |
1 | // #define CONFIG_DM9000_DEBUG |
1 | 上面的IP和网关、子网掩码等根据自己的具体情况进行修改。接着打开u-boot-2010.03/net/eth.c,并且进入到函数inteth_initialize(bd_t*bis)中,在: |
1 2 3 | #ifdefined(CONFIG_DB64460)|| defined(CONFIG_P3Mx)mv6446x_eth_initialize(bis);#endif |
后面添加:
1 | 同样在u-boot-2010.03/net/net.c, |
1 | 1.将 |
1 | #defineARP_TIMEOUT 5000UL /*MillisecondsbeforetryingARPagain*/ |
1 | 修改为 |
1 | #defineARP_TIMEOUT 5 /*MillisecondsbeforetryingARPagain*/ |
2. 将
1 | if ((t-NetArpWaitTimerStart)>ARP_TIMEOUT) |
修改为
1 | if ((t-NetArpWaitTimerStart)>ARP_TIMEOUT*CONFIG_SYS_HZ |
3. 将
1 | NetSetTimeout(10000UL,PingTimeout); |
修改为
1 | NetSetTimeout(10*CONFIG_SYS_HZ,PingTimeout); |
接着进入u-boot-2010.03/net/tftp.c,找到void TftpStart(void)函数,用#if0 #endif注释掉下面的程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #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" , |
1 2 | TftpBlkSizeOption,TftpTimeoutMSecs);#endif |
再编译,下载,运行情况如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
1 | |
1 2 3 4 5 6 7 8 9 10 | 2048 MiB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial |
1 2 3 4 5 | Net: dm9000 Hit any key to stop autoboot: 0 |
Nandflash读写:
nandflash的控制都是这个套路,因为这就是硬件协议,先使能芯片->发送命令->发送地址序列->读或写数据寄存器->判断准备就绪状态->禁止芯片,这是对nand flash操作的大体过程,根据发送命令的不同还有些区别。
进入u-boot-2010.03/driver/mtd/nand/,修改nand_ids.c,作如下修改:
1 2 | // { "NAND 2GiB3,3V8-bit" ,0xD5,0,2048,0,LP_OPTIONS},{ "NAND2GiB3,3V8-bit" , 0xD5,4096,2048,512*1024,LP_OPTIONS}, |
编译下载,运行如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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 |
1 2 3 4 5 | 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);注释掉,至今我是这样解决的,不影响启动。修改后启动如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
1 2 3 4 5 | 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文件。代码如下:
1 2 3 4 5 6 7 8 | #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 添 加 如 下 内 容 :
1 | 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,就会显示信息了;
1 2 | SMDK6410 # infou-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中的:
1 2 3 4 5 6 7 8 | staticstructmtd_partitionok6410_nand_part[]={{.name = "Bootloader" ,.offset =0,.size =(1*SZ_1M),.mask_flags =MTD_CAP_NANDFLASH,},{ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | .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)
转载于:https://www.cnblogs.com/start530/archive/2012/09/27/3834393.html