$cd u-boot-mini2440 $make smdk2410_config $make编译通过,说明编译环境没有问题。
smdk2410_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0复制并修改成:
mini2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t mini2440 samsung s3c24x0注意:@前面是tab键,否则编译配置的时候出错。
(2)进入/board/samsung,将smdk2410目录,复制成为mini2440.这个是我们的开发板的目录。进入mini2440目录,修改smdk2410.c为mini2440.c。修改Makefile:
COBJS := mini2440.o flash.o(3)进入/include/configs,将smdk2410.h,复制成为mini2440.h,这个是我们的配置文件。
make clean make mini2440_config make编译通过说明没有问题。
@ bl coloured_LED_init @ bl red_LED_on这个mini2440没有彩色灯,所以要注释掉
# if defined(CONFIG_S3C2440) ldr r1, =0x3fff ldr r0, =INTSUBMSK str r1, [r0] # endif因为子中断2440有15个,所以要改一下。
# if defined(CONFIG_S3C2440) #define MPLLCON 0x4c000004 #define UPLLCON 0x4c000008 /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 405 MHz ! */ ldr r0, =CLKDIVN mov r1, #5 str r1, [r0] ldr r0, =MPLLCON ldr r1, =(0x7f<<12)|(0x02<<4)|(0x01) str r1, [r0] ldr r0, =UPLLCON ldr r1, =(0x38<<12)|(0x02<<4)|(0x02) str r1, [r0] # else /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] #endif /* CONFIG_S3C2440 */以上是S3C2440时钟初始化的代码,可以看出2410和2440时钟初始化还是差别很大的。
#define Trp 0x2 /* 2clk */ #define REFCNT 1012
5. 添加检查代码位置以及判断启动方式的代码
/*********** CHECK_CODE_POSITION ************/ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup /***************** CHECK_CODE_POSITION ****/ /***************** CHECK_BOOT_FLASH *******/ #define rBWSCON 0x48000000 mov r0, #rBWSCON ldr r0, [r0] bic r0, r0, #0xfffffff5 /* BWSCON[2:1] is controled by OM[1:0] */ cmp r0, #0 /* when OM[1:0] is 00,BSWCON[2:1]=00, nand flash boot */ bne relocate /* norflash boot */ /*****************CHECK_BOOT_FLASH*************************/检查启动代码位置,是通过比较当前的代码位置和TEXT_BASE之间是否相同来判断的
6.添加Nandflash启动代码
#define LENGTH_UBOOT 0x60000 #define NAND_CTL_BASE 0x4E000000 #ifdef CONFIG_S3C2440 /* Offset */ #define oNFCONF 0x00 #define oNFCONT 0x04 #define oNFCMD 0x08 #define oNFSTAT 0x20 @ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) str r2, [r1, #oNFCONF] ldr r2, [r1, #oNFCONF] ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT] ldr r2, [r1, #oNFCONT] ldr r2, =(0x6) @ RnB Clear str r2, [r1, #oNFSTAT] ldr r2, [r1, #oNFSTAT] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait nand1: add r3, r3, #0x1 cmp r3, #0xa blt nand1 nand2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x4 beq nand2 ldr r2, [r1, #oNFCONT] orr r2, r2, #0x2 @ Flash Memory Chip Disable str r2, [r1, #oNFCONT] @ get read to call C functions (for nand_read()) ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0 @ copy U-Boot to RAM ldr r0, =TEXT_BASE mov r1, #0x0 mov r2, #LENGTH_UBOOT bl nand_read_ll tst r0, #0x0 beq ok_nand_read bad_nand_read: loop2: b loop2 @ infinite loop ok_nand_read: @ verify mov r0, #0 ldr r1, =TEXT_BASE mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq stack_setup bne go_next notmatch: loop3: b loop3 @ infinite loop #endif
nand_read_ll 这个函数是nand_read.c里面的,这个文件应该在板级目录里,添加这个文件到/board/samsung/mini2440里面。并且修改Makefile,使得编译进代码
COBJS := mini2440.o flash.o nand_read.o到此第一阶段的代码修改完毕。因为要测试编译是否通过,而代码中有CONFIG_S3C2440配置,所以要修改mini2440.h。
#define STACK_BASE 0x33f00000 #define STACK_SIZE 0x10000 .align 2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4(2)发现include/asm/arch/s3c24x0_cpu.h错误,里面定义了CONFIG_S3C2410包含了s3c2410.h,因为我们定义的是CONFIG_S3C2440所以没有包含头文件,所以改一下,将s3c2410.h复制为s3c2440.h。
# if defined(CONFIG_MINI2440_LED) #define rGPBCON 0x56000010 #define rGPBDATA 0x56000014 #define rGPBUP 0x56000018 ldr r0, =rGPBCON ldr r1, =(0x01<<10)|(0x01<<12)|(0x01<<14)|(0x01<<16) str r1, [r0] ldr r0, =rGPBUP ldr r1, =0x7fff str r1, [r0] ldr r0, =rGPBDATA ldr r1, =(0x1<<5)|(0x0<<6)|(0x1<<7)|(0x0<<8) str r1, [r0] #endif9 修改u-boot.lds 中的链接顺序,因为lowlevel_init.S,和nand_read.c都需要在前4K代码中,修改为
cpu/arm920t/start.o (.text) board/samsung/mini2440/lowlevel_init.o board/samsung/mini2440/nand_read.o配置mini2440.h,添加CONFIG_MINI2440_LED宏定义,重新编译,下载到板子上,如果LED灯,第一个和第三个亮了,其他是灭的。说明程序第一阶段正确执行了。kermit(串口终端)出现乱码,说明串口驱动还没有移植,是正常现象。
#define CONFIG_LCD #define LCD_VIDEO_ADDR 0x33d00000(2)添加2440寄存器
将lcd.c拷贝到/board/samsung/mini2440里面,说明是底层驱动。这个文件是根据参考代码修改而成。
#include <common.h> #include <netdev.h> #include <asm/arch/s3c24x0_cpu.h> #include <video_fb.h> #include <lcd.h> #include <asm/io.h> #if defined(CONFIG_CMD_NAND) #include <linux/mtd/nand.h> #endif DECLARE_GLOBAL_DATA_PTR; #define MVAL (0) #define MVAL_USED (0) //0=each frame 1=rate by MVAL #define INVVDEN (1) //0=normal 1=inverted #define BSWP (0) //Byte swap control #define HWSWP (1) //Half word swap control //TFT 240320 #define LCD_XSIZE_TFT_240320 (240) #define LCD_YSIZE_TFT_240320 (320) #define LCD_MEM_SIZE 240*320*16 //TFT240320 #define HOZVAL_TFT_240320 (LCD_XSIZE_TFT_240320-1) #define LINEVAL_TFT_240320 (LCD_YSIZE_TFT_240320-1) //Timing parameter for NEC3.5" #define VBPD_240320 (3) #define VFPD_240320 (10) #define VSPW_240320 (1) #define HBPD_240320 (5) #define HFPD_240320 (2) #define HSPW_240320_NEC (36) //Adjust the horizontal displacement of the screen :[email protected] #define HSPW_240320_TD (23) //64MB nand mini2440 is 36 ,128MB is 23 //+ : --> - : <-- #define CLKVAL_TFT_240320 (3) //FCLK=101.25MHz,HCLK=50.625MHz,VCLK=6.33MHz #ifdef CONFIG_LCD vidinfo_t panel_info = { LCD_XSIZE_TFT_240320, LCD_YSIZE_TFT_240320, LCD_BPP }; int lcd_line_length; int lcd_color_fg; int lcd_color_bg; void *lcd_base; /* Start of framebuffer memory */ void *lcd_console_address; /* Start of console buffer */ short console_col; short console_row; void lcd_ctrl_init (void *lcd_base) { struct s3c24x0_lcd * const lcd = s3c24x0_get_base_lcd(); struct s3c2410_nand * const nand = s3c2410_get_base_nand(); /* select LCM type by env variable */ /* Configuration for GTA01 LCM on QT2410 */ lcd->LCDCON1 = 0x00000378; /* CLKVAL=4, BPPMODE=16bpp, TFT, ENVID=0 */ lcd->LCDCON2 = (VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320); lcd->LCDCON3 = (HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320); if ( (nand->NFCONF) & 0x08 ) { lcd->LCDCON4 = (MVAL<<8)|(HSPW_240320_TD); } else { lcd->LCDCON4 = (MVAL<<8)|(HSPW_240320_NEC); } lcd->LCDCON5 = 0x00000f09; lcd->LPCSEL = 0x00000000; printf("Video: "); printf ("TongBao 240*320 LCD 16bit 565 mode\n"); /* Init LCD base address */ writel((((ulong)lcd_base) >> 1), &lcd->LCDSADDR1); writel((((readl(&lcd->LCDSADDR1))&0x1fffff) + (LCD_XSIZE_TFT_240320+0) * LCD_YSIZE_TFT_240320), &lcd->LCDSADDR2); writel((LCD_XSIZE_TFT_240320 & 0x7ff), &lcd->LCDSADDR3); /* Clear video memory */ memset((void *)lcd_base, 0, LCD_MEM_SIZE); /* Enable Display */ writel((readl(&lcd->LCDCON1) | 0x01), & lcd->LCDCON1); /* ENVID = 1 */ } void lcd_enable (void) { }
具体实现见u-boot lcd 分析
(4)定义颜色位数#define LCD_BPP LCD_COLOR16(5)重新编译
make clean make mini2440_config make可以看到终端提示符到LCD上了,但是字是白的,背景是黑的。
ifeq ($(LOGO_BMP),) LOGO_BMP= logos/ayst.bmp endif然后将ayst.bmp拷贝到/tools/logos里面,注意bmp图像是有要求的,宽度要是四的倍数,还得是16位的。只有这样才能正确的显示。
#define CONFIG_CMD_NAND 1 /*-------------------------------------------------------------------------------------------- * NAND flash settings */ #if defined(CONFIG_CMD_NAND) #define CONFIG_NAND_S3C2410 #define CONFIG_SYS_NAND_BASE 0x4E000000 #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define SECTORSIZE 512 #define SECTORSIZE_2K 2048 #define NAND_SECTOR_SIZE SECTORSIZE #define NAND_SECTOR_SIZE_2K SECTORSIZE_2K #define NAND_BLOCK_MASK 511 #define NAND_BLOCK_MASK_2K 2047 #define NAND_MAX_CHIPS 1 #define CONFIG_MTD_NAND_VERIFY_WRITE #define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */ #endif /* CONFIG_CMD_NAND */ (3)添加2440 nandflash寄存器 在/include/asm-arm/arch-s3c24x0/s3c24x0.h 中 #if defined (CONFIG_S3C2440) /* NAND FLASH (see S3C2440 manual chapter 6) */ struct s3c2410_nand { u32 NFCONF; u32 NFCONT; u32 NFCMD; u32 NFADDR; u32 NFDATA; u32 NFMECCD0; u32 NFMECCD1; u32 NFSECCD; u32 NFSTAT; u32 NFESTAT0; u32 NFESTAT1; u32 NFMECC0; u32 NFMECC1; u32 NFSECC; u32 NFSBLK; u32 NFEBLK; }; #endif4. 网络驱动的移植
#ifdef CONFIG_DRIVER_DM9000 rc = dm9000_initialize(bis); #endif(2)添加配置
#define CONFIG_CMD_PING 1 #define CONFIG_NET_MULTI 1 #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_BASE 0x20000300 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+4) #define CONFIG_DM9000_USE_16BIT 1 #define CONFIG_DM9000_NO_SROM 1 #undef CONFIG_DM9000_DEBUG(3)dm9000x.c的修改
if (i == 1000) { printf("could not establish link\n"); return 0; break; }(4)nfs代码的修改
#define NFS_TIMEOUT (10*2000UL)5 默认环境变量修改
/*----------------------------------------------------------------------------------------------------- *Environment variables setting */ #define CONFIG_BOOTDELAY 5 #define CONFIG_BOOTARGS "noinitrd root=/dev/nfs rw nfsroot=192.168.1.111:/home/sun/study/nfsshare/rootfs_qtopia_qt4 ip=192.168.1.230:192.168.1.1::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M" #define CONFIG_ETHADDR 08:08:11:18:12:27 #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.1.230 #define CONFIG_SERVERIP 192.168.1.111 #define CONFIG_GATEWAYIP 192.168.1.1 #define CONFIG_OVERWRITE_ETHADDR_ONCE #define CONFIG_BOOTCOMMAND "tftp 0x30008000 zImage;bootm" #if defined(CONFIG_CMD_KGDB) #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ /* what's this ? it's not used anywhere */ #define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ #endif
/* timeout values are in ticks */ #define CONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */ #define CONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Write */ #define CONFIG_ENV_IS_IN_NAND 1 #define CONFIG_ENV_OFFSET 0x40000 /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE 0x20000 /*size of environment */
/*----------------------------------------------------------------------------------------------------- * linux kernel tags * This is important for starting kernel */ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG #define CONFIG_CMDLINE_TAG #define CONFIG_SYS_HUSH_PARSER #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_CMDLINE_EDITING #define CONFIG_AUTO_COMPLETE这个标记列表配置对内核启动十分重要,没有就不会启动内核
本次移植参考tekkamaninja对友善之臂mini2440的移植代码。好多地方都是照搬其代码。因为没有时间的缘故,对一些代码的实现还是不是很了解。但是对u-boot的基本的软件架构有了一定的了解。自己独创的地方就是判断启动方式上,还有lcd驱动的移植。前一个是参考裸机程序的启动代码写的,后一个完全按照自己对代码的理解移植而成。还是比较成功的。u-boot软件分层结构给了我深刻的印象。还有Makefile的结构也对我很有启发。这个第一个接触的开源项目。以后还会经常用到。
移植的源码下载在我的csdn下载资源里http://download.csdn.net/detail/YAOZHENGUO2006/3585685