zoukankan      html  css  js  c++  java
  • U-BOOT 移植到友善之臂mini2440

    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包括这个文件,所以交叉编译工具连就已经确定了。无需再改。
    $cd  u-boot-mini2440
    $make smdk2410_config
    $make
    编译通过,说明编译环境没有问题。
    2.建立mini2440配置以及文件
     (1)进入顶层文件夹Makefile,找到:
    smdk2410_config :       unconfig
         @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 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:

    COBJS   := mini2440.o flash.o

     (3)进入/include/configs,将smdk2410.h,复制成为mini2440.h,这个是我们的配置文件。
    这样我们的开发板的文件就都有了,可是内容都是smdk2410开发板的。
    编译測试
    make clean
    make mini2440_config
    make
    编译通过说明没有问题。
    3. start.S的改动(1)
    @       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时钟初始化还是区别非常大的。
    4.  初始化时钟后,紧接着就是cpu内部初始化。这个函数cpu_init_crit无需改动,可是里面调用的lowlevel_init函数必须改动,由于是初始化内存的代码,每一个开发板的内存都不同,所以lowlevel_init.S在/board/samsung/mini2440文件夹里。
     #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之间是否同样来推断的
    而推断启动方式是通过检查BWSCON[2:1]来推断的,详细实现见start.S的分析

    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。
    7 编译排错:
    (1).发现DW_STACK_START未定义,这个是进入C语言初始话栈的时候用到的,加上定义。
    #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灯显示程序。
    #  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
    9 改动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(串口终端)出现乱码,说明串口驱动还没有移植,是正常现象。
    四. 启动第二阶段移植过程
    1.串口初始化改动
            串口实现基本上不用改动什么,串口初始化函数是serial_init,在/drivers/serial/serial_s3c24x0.c中,由于串口要初始化波特率,须要get_PCLK()这个函数,而这个函数在/cpu/arm920t/speed.c里面,2410与2440实现是不同的,所以须要改动这个函数。改动完了,又一次编译出现错误,CAMDIVN未定义,由于2410里面没有这个寄存器,在s3c24x0.h中添�定义就能够了。然后下载到板子上,串口就会出现正常的终端显示。可是非常多命令用不了。由于是其它的驱动没有移植。
    2. LCD终端移植
    參考代码的LCD驱动是通过VFD方式实现的,可是分析一下代码感觉其编程方式让人非常不爽,看了一下LCD实现的方式,更加贴近自己的风格。所以果断转向LCD方式实现LCD终端。
    (1)首先在mini2440.h中加入�宏定义
    #define CONFIG_LCD
    #define LCD_VIDEO_ADDR	0x33d00000
    (2)加入�2440寄存器
    2410和2440寄存器是一样的,所以仅仅须要添加�CONFIG_S3C2440就能够了。
    (3)加入�底层LCD驱动代码lcd.c

    将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 :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
    ");
    	/* 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中定义
    #define LCD_BPP                 LCD_COLOR16
    (5)又一次编译
    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
    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的配置
    #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
    4. 网络驱动的移植
    (1)改动网卡初始化代码
    在mini2440.c中加入�
    #ifdef CONFIG_DRIVER_DM9000
            rc = dm9000_initialize(bis);
    #endif
    (2)加入�配置
    在mini244.h中加入�
    #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行
    if (i == 1000) {
    	printf("could not establish link
    ");
    	return 0;
    	break;
    }
    (4)nfs代码的改动
    33行
    #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 */

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

  • 相关阅读:
    使用 ASP.NET Core MVC 创建 Web API(五)
    使用 ASP.NET Core MVC 创建 Web API(四)
    使用 ASP.NET Core MVC 创建 Web API(三)
    使用 ASP.NET Core MVC 创建 Web API(二)
    使用 ASP.NET Core MVC 创建 Web API(一)
    学习ASP.NET Core Razor 编程系列十九——分页
    学习ASP.NET Core Razor 编程系列十八——并发解决方案
    一个屌丝程序猿的人生(九十八)
    一个屌丝程序猿的人生(九十七)
    一个屌丝程序猿的人生(九十五)
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3840388.html
Copyright © 2011-2022 走看看