U-BOOT 移植到友善之臂mini2440


开发环境:ubuntu 10.10
编译器:友善之臂mini2440光盘自带arm-linux-gcc 4.4.3


一. 在denx官网下载源代码,我所用版本为u-boot-2010.03。               
二. 主机编译环境为友善之臂提供的arm-linux-gcc.所参考板子为smdk2410。
三. 启动第一阶段移植过程
1.首先测试编译环境,因为arm-linux-gcc,已经加入了PATH环境变量,在lib_arm目录下的config.mk 定义了CRPSS_COMPILE 为arm-linux-,而主目录下的Makefile包含这个文件,所以交叉编译工具连就已经确定了。无需再改。

[plain] view plaincopyprint?
$cd  u-boot-mini2440  
$make smdk2410_config  
$make  
$cd  u-boot-mini2440
$make smdk2410_config
$make编译通过,说明编译环境没有问题。
2.建立mini2440配置以及文件
 (1)进入顶层目录Makefile,找到:

[plain] view plaincopyprint?
smdk2410_config :       unconfig  
     @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0  
smdk2410_config :       unconfig
     @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0复制并修改成:

[plain] view plaincopyprint?
mini2440_config :       unconfig  
     @$(MKCONFIG) $(@:_config=) arm arm920t mini2440 samsung s3c24x0  
mini2440_config :       unconfig
     @$(MKCONFIG) $(@:_config=) arm arm920t mini2440 samsung s3c24x0注意:@前面是tab键,否则编译配置的时候出错。
            这条命令实际是执行顶层目录下的 mkconfig,后面的都是参数

 (2)进入/board/samsung,将smdk2410目录,复制成为mini2440.这个是我们的开发板的目录。进入mini2440目录,修改smdk2410.c为mini2440.c。修改Makefile:
[plain] view plaincopyprint?
COBJS   := mini2440.o flash.o  
COBJS   := mini2440.o flash.o (3)进入/include/configs,将smdk2410.h,复制成为mini2440.h,这个是我们的配置文件。
这样我们的开发板的文件就都有了,但是内容都是smdk2410开发板的。
编译测试

[plain] view plaincopyprint?
make clean  
make mini2440_config  
make  
make clean
make mini2440_config
make编译通过说明没有问题。
3. start.S的修改(1)

[plain] view plaincopyprint?
@       bl      coloured_LED_init  
@       bl      red_LED_on  
@       bl      coloured_LED_init
@       bl      red_LED_on这个mini2440没有彩色灯,所以要注释掉

[plain] view plaincopyprint?
# if defined(CONFIG_S3C2440)  
        ldr     r1, =0x3fff  
        ldr     r0, =INTSUBMSK  
        str     r1, [r0]  
# endif  
# if defined(CONFIG_S3C2440)
        ldr     r1, =0x3fff
        ldr     r0, =INTSUBMSK
        str     r1, [r0]
# endif因为子中断2440有15个,所以要改一下。

[plain] view plaincopyprint?
# 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 */  
# 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时钟初始化还是差别很大的。
4.  初始化时钟后,紧接着就是cpu内部初始化。这个函数cpu_init_crit无需修改,但是里面调用的lowlevel_init函数必须修改,因为是初始化内存的代码,每个开发板的内存都不同,所以lowlevel_init.S在/board/samsung/mini2440目录里。

[plain] view plaincopyprint?
 #define Trp                     0x2     /* 2clk */  
 #define REFCNT                  1012     
 #define Trp                     0x2     /* 2clk */
 #define REFCNT                  1012   
5. 添加检查代码位置以及判断启动方式的代码

[plain] view plaincopyprint?
/*********** 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*************************/  
/*********** 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之间是否相同来判断的
而判断启动方式是通过检查BWSCON[2:1]来判断的,具体实现见start.S的分析

6.添加Nandflash启动代码
[plain] view plaincopyprint?
#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  
#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
#endifnand_read_ll 这个函数是nand_read.c里面的,这个文件应该在板级目录里,添加这个文件到/board/samsung/mini2440里面。并且修改Makefile,使得编译进代码
[plain] view plaincopyprint?
COBJS   := mini2440.o flash.o nand_read.o  
COBJS   := mini2440.o flash.o nand_read.o到此第一阶段的代码修改完毕。因为要测试编译是否通过,而代码中有CONFIG_S3C2440配置,所以要修改mini2440.h。
7 编译排错:
(1).发现DW_STACK_START没有定义,这个是进入C语言初始话栈的时候用到的,加上定义。

[plain] view plaincopyprint?
#define STACK_BASE 0x33f00000  
#define STACK_SIZE 0x10000  
        .align  2  
DW_STACK_START: .word   STACK_BASE+STACK_SIZE-4  
#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。
(3)  发现s3c2440.h没有定义CONFIG_S3C2440,将其中有关CONFIG_S3C2410 的预处理选项都换成CONFIG_S3C2410||CONFIG_S3C2440,这样代码才能够编译进来。
8 加上led灯显示程序。

[plain] view plaincopyprint?
#  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]  
#endif  
#  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代码中,修改为

[plain] view plaincopyprint?
cpu/arm920t/start.o     (.text)  
board/samsung/mini2440/lowlevel_init.o  
board/samsung/mini2440/nand_read.o  
                cpu/arm920t/start.o     (.text)
                board/samsung/mini2440/lowlevel_init.o
                board/samsung/mini2440/nand_read.o配置mini2440.h,添加CONFIG_MINI2440_LED宏定义,重新编译,下载到板子上,如果LED灯,第一个和第三个亮了,其他是灭的。说明程序第一阶段正确执行了。kermit(串口终端)出现乱码,说明串口驱动还没有移植,是正常现象。
四. 启动第二阶段移植过程
1.串口初始化修改
        串口实现基本上不用修改什么,串口初始化函数是serial_init,在/drivers/serial/serial_s3c24x0.c中,因为串口要初始化波特率,需要get_PCLK()这个函数,而这个函数在/cpu/arm920t/speed.c里面,24102440实现是不同的,所以需要修改这个函数。修改完了,重新编译出现错误,CAMDIVN没有定义,因为2410里面没有这个寄存器,在s3c24x0.h中加入定义就可以了。然后下载到板子上,串口就会出现正常的终端显示。但是很多命令用不了。因为是其他的驱动没有移植。
2. LCD终端移植
参考代码的LCD驱动是通过VFD方式实现的,但是分析一下代码感觉其编程方式让人很不爽,看了一下LCD实现的方式,更加贴近自己的风格。所以果断转向LCD方式实现LCD终端。
(1)首先在mini2440.h中添加宏定义

[plain] view plaincopyprint?
#define CONFIG_LCD  
#define LCD_VIDEO_ADDR  0x33d00000  
#define CONFIG_LCD
#define LCD_VIDEO_ADDR  0x33d00000(2)添加2440寄存器
24102440寄存器是一样的,所以只需要增加CONFIG_S3C2440就可以了。
(3)添加底层LCD驱动代码lcd.c

将lcd.c拷贝到/board/samsung/mini2440里面,说明是底层驱动。这个文件是根据参考代码修改而成。
[plain] view plaincopyprint?
#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 :tekkamanninja@163.com  
#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)  
{  
}  
#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 :tekkamanninja@163.com
#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)定义颜色位数
因为/common/lcd.c中的默认的颜色是8位的,而统宝的是16位的。所以在mini440.h中定义

[plain] view plaincopyprint?
#define LCD_BPP                 LCD_COLOR16  
#define LCD_BPP                 LCD_COLOR16(5)重新编译

[plain] view plaincopyprint?
make clean  
make mini2440_config  
make  
make clean
make mini2440_config
make可以看到终端提示符到LCD上了,但是字是白的,背景是黑的。
在mini2440.h中定义#define CONFIG_SYS_WHITE_ON_BLACK       1 
就会反白了。这样才够帅。因为默认是LCD终端提示符,这个是因为注册设备顺序的缘故,在/common/stdio.c stdio_init函数中,将drv_lcd_init ()放到serial_stdio_init ()后面就可以了。然后重新编译下载。就会默认串口终端了,可以通过输入 setenv stdout lcd 进行切换。
(6)添加logo.
在mini2440.h,定义CONFIG_LCD_LOGO。重新编译就会出现denx 的开机logo如果还觉的不够帅,添加自己的logo。修改方法,/tools/Makefile

[plain] view plaincopyprint?
ifeq ($(LOGO_BMP),)  
LOGO_BMP= logos/ayst.bmp  
endif  
ifeq ($(LOGO_BMP),)
LOGO_BMP= logos/ayst.bmp
endif然后将ayst.bmp拷贝到/tools/logos里面,注意bmp图像是有要求的,宽度要是四的倍数,还得是16位的。只有这样才能正确的显示。
3. Nandflash驱动移植
(1)修改底层驱动代码
修改/drivers/mtd/nand/s3c2410_nand.c
(2)添加配置
在mini2440.h中添加Nandflash的配置

[plain] view plaincopyprint?
#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;  
};  
#endif  
#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. 网络驱动的移植1)修改网卡初始化代码
在mini2440.c中添加

[plain] view plaincopyprint?
#ifdef CONFIG_DRIVER_DM9000  
        rc = dm9000_initialize(bis);  
#endif  
#ifdef CONFIG_DRIVER_DM9000
        rc = dm9000_initialize(bis);
#endif(2)添加配置
在mini244.h中添加

[plain] view plaincopyprint?
#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  
#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的修改
364行

[plain] view plaincopyprint?
if (i == 1000) {  
    printf("could not establish link\n");  
    return 0;  
    break;  
}  
if (i == 1000) {
    printf("could not establish link\n");
    return 0;
    break;
}(4)nfs代码的修改
33行

[plain] view plaincopyprint?
#define NFS_TIMEOUT (10*2000UL)  
#define NFS_TIMEOUT (10*2000UL)5 默认环境变量修改

[plain] view plaincopyprint?
/*-----------------------------------------------------------------------------------------------------  
 *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  
/*-----------------------------------------------------------------------------------------------------
 *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[plain] view plaincopyprint?
/* 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 */  
/* 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 */
这个是所处的存储介质,默认的Flash,这里是NandFlash

[plain] view plaincopyprint?
/*-----------------------------------------------------------------------------------------------------  
 * 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  
/*-----------------------------------------------------------------------------------------------------
 * 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的结构也对我很有启发。这个第一个接触的开源项目。以后还会经常用到。
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐