当前位置:文档之家› U-boot 基于TQ2440 开发板上的移植

U-boot 基于TQ2440 开发板上的移植

U-boot 基于TQ2440 开发板上的移植
U-boot 基于TQ2440 开发板上的移植

u-boot-2011.03在TQ2440上的移植(1)--建立自己的demo板收藏

参考文章

黄刚博客https://www.doczj.com/doc/c310102687.html,/u3/101649/showart_2276917.html

tekkman博客https://www.doczj.com/doc/c310102687.html,/u1/34474/showart_2212066.html

1、到ftp://ftp.denx.de/pub/u-boot/下载u-boot-2010.06.tar.bz2

2、解压tar jxvf u-boot-2010.06.tar.bz2

3、进入uboot cd u-boot-2010.06

4、删减uboot

进入/board,留下samsung,其它全部删除

进入/arch,留下arm,其它全部删除

进入/arch/arm/cpu,留下arm920t,其它全部删除

5、建立自己的DEMO板

cd /board/samsung

mkdir smdk2440

cp -rf smdk2410/* smdk2440///将2410下所有的代码复制到2440下

cd smdk2440//进入smdk2440目录

mv smdk2410.c smdk2440.c//将smdk2440下的

smdk2410.c改名为smdk2440.c

然后在文件夹samsung里留下smdk2440,其它全部删除

cp include/configs/smdk2410.h include/configs/smdk2440.h//建立2440头文件

在include/configs下留下smdk2440.h, 其它全部删除

vi board/samsung/smdk2440/Makefile//修改smdk2440下Makefile的编译项,如下:

COBJS := smdk2440.o flash.o//修改第28行因在smdk2440下我们将smdk2410.c改名为smdk2440.c

6、修改u-boot跟目录下的Makefile文件。查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立my2440_config的编译选项,另外还要指定交叉编译器,修改159行

CROSS_COMPILE ?= arm-linux-//指定交叉编译器为arm-linux-gcc

smdk2410_config:unconfig//2410编译选项格式

@$(MKCONFIG) $(@:_config=)arm arm920t smdk2410 samsung s3c24x0

smdk2440_config:unconfig//修改蒂3054行,2440编译选项格式

@$(MKCONFIG) $(@:_config=)arm arm920t smdk2440 samsung s3c24x0

*说明:arm:CPU的架构(ARCH)

arm920t:CPU的类型

smdk2440 :对应在board目录下建立新的开发板项目的目录

samsung:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,则这里就为NULL

s3c24x0:CPU型号

*注意:编译选项格式的第二行要用Tab键开始,否则编译会出错

7、测试编译新建的smdk2440开发板项目

在uboot根目录测试

make smdk2440_config

make即可在uboot根目录下生成bin文件

在uboot里,清除中间文件用命令make distclean

u-boot-2011.03在TQ2440上的移植(2)--初始化时钟收藏

smdk2440的初始化设置

1、u-boot主要的目录结构如下

2、启动流程图下图

由上图可知

u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;

u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。

3、在include/configs/smdk2440.h头文件中添加CONFIG_S3C2440宏

vi include/configs/smdk2440.h在第40行添加

#define CONFIG_S3C2440 1

4、stage1阶段的硬件设备初始化。

vi arch/arm/cpu/arm920t/start.S

去掉117,118行点亮AT91RM9200DK系列LED的代码

/*

bl coloured_LED_init

bl red_LED_on

*/

5、在u-boot中添加对S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分。在164行添加如下红色内容

# if defined(CONFIG_S3C2410)

ldr r1,=0x3ff

ldr r0,=INTSUBMSK

str r1,[r0]

# endif

/*164行*/

# if defined(CONFIG_S3C2440)//添加s3c2440的中断禁止部分ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK寄存器有15位可用

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

# if defined(CONFIG_S3C2440) //添加s3c2440的时钟部分

#define MPLLCON 0x4C000004 //系统主频配置寄存器基地址

#define UPLLCON 0x4C000008 //USB时钟频率配置寄存器基地址ldr r0, =CLKDIVN //设置分频系数FCLK:HCLK:PCLK = 1:4:8 mov r1, #5

str r1, [r0]

ldr r0, =MPLLCON //设置系统主频为405MHz

ldr r1, =0x7F021 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分

str r1, [r0]

ldr r0, =UPLLCON //设置USB时钟频率为48MHz

ldr r1, =0x38022 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分

str r1, [r0]

# else //其他开发板的时钟部分,这里就不用管了,我们现在是做2440的

6、S3C2440的时钟部分除了在start.S中添加外,还要分别在

board/samsung/smdk2440/smdk2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码,如下:

vi board/samsung/smdk2440/smdk2440.c

时钟部分修改第34行和在45行添加如下红色部分

#define FCLK_SPEED 2 //设置默认等于2,即下面红色代码部分有效

#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV 0xC3

#define M_PDIV 0x4

#define M_SDIV 0x1

#elif FCLK_SPEED==1 /* Fout = 202.8MHz */

#define M_MDIV 0xA1

#define M_PDIV 0x3

#define M_SDIV 0x1

#elif FCLK_SPEED==2 /* Fout = 405MHz */

#define M_MDIV 0x7F //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

USB时钟部分修改第51行和在61行添加如下红色部分

#define USB_CLOCK 2 //设置默认等于2,即下面红色代码部分有效

#if USB_CLOCK==0

#define U_M_MDIV 0xA1

#define U_M_PDIV 0x3

#define U_M_SDIV 0x1

#elif USB_CLOCK==1

#define U_M_MDIV 0x48

#define U_M_PDIV 0x3

#define U_M_SDIV 0x2

#elif USB_CLOCK==2 /* Fout = 48MHz */

#define U_M_MDIV 0x38 //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置

#define U_M_PDIV 0x2

#define U_M_SDIV 0x2

#endif

7、vi arch/arm/cpu/arm920t/s3c24x0/speed.c //根据设置的分频系数

FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数

get_PLLCLK函数修改第66行如下

static ulong get_PLLCLK(int pllreg)

{

S3C24X0_CLOCK_POWER * const clk_power =

S3C24X0_GetBase_CLOCK_POWER();

ulong r, m, p, s;

if (pllreg == MPLL)

r = clk_power->MPLLCON;

else if (pllreg == UPLL)

r = clk_power->UPLLCON;

else

hang();

m = ((r & 0xFF000) >> 12) + 8;

p = ((r & 0x003F0) >> 4) + 2;

s = r & 0x3;

#if defined(CONFIG_S3C2440)

if(pllreg == MPLL)

{ //参考S3C2440芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2s) return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));

}

#endif

return((CONFIG_SYS_CLK_FREQ * m) / (p << s));

}

修改84行get_HCLK函数为

/* return HCLK frequency */

ulong get_HCLK(void)

{

S3C24X0_CLOCK_POWER * const clk_power =

S3C24X0_GetBase_CLOCK_POWER();

#if defined(CONFIG_S3C2440)

return(get_FCLK()/4);

#endif

return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK()); }

u-boot-2011.03在TQ2440上的移植(3)--支持norflash启动收藏

1、修改命令提示符为自己的

vi include/configs/smdk2440.h

第118行修改为

#define CONFIG_SYS_PROMPT "[SMDK2440]#"//将命令行前的名字改成[SMDK2440]

2、通常,在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动。u-boot中默认是从Nor Flash启动的。

3、TQ2440的所用的Norflash为EN29LV160AB。接线同AM29LV160DB

翻开此芯片的datasheet看到

TQ2440原理图上的第47脚BYTE#是接高电平的,so 此芯片工作于16位模式(半字

模式)

A0-A19是地址线,在半字模式下,D0-D15做为数据输入输出口。因为数据位是16位,A0-A19可以选择2^20 = 1M *2BYTE = 2Mbyte。正好是AM29LV160DB的容量。S3C2440的ADDR1要接AM29LV160DB的A0。上图中AM29LV160DB的A20,A21是空脚,分别接的是LADDR21,LADDR22。这应该是为了以后方便扩展NOR FLASH的容量。LADDR21,LADDR22对AM29LV160DB是没用的。

<1>2048K * 8bit / 1024K * 16bit Flash Memory Boot Sector Flash Memory

<2>Flexible Sector Architecture:

-One 16-Kbyte, two 8-Kbyte, one 32-Kbyte, and thirty-one 64-Kbyte

sectors(byte mode)

-One 8-Kword, two 4-Kword, one 16-Kword,and thirty-one 32-Kword

sectors(word mode)

无论哪种模式总扇区是35 sectors。

4、修改Norflash参数

vi include/configs/smdk2440.h

/*-----------------------------------------------------------------------

* FLASH and environment organization

*/

#if 0//注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号

#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */

#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */

#endif

#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */

#define CONFIG_SYS_MAX_FLASH_SECT (19) /* max number of sectors on one chip */

#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of environment */

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */

#define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors

on one chip */

#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */

#endif

//第175行添加如下内容

#define CONFIG_EON_29LV160AB 1 //添加TQ2440开发板Nor Flash设置

#define PHYS_FLASH_SIZE 0x200000 //我们开发板的Nor Flash是2M

#define CONFIG_SYS_MAX_FLASH_SECT (35) //根据

EN29LV160AB的芯片手册描述,共35个扇区

#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE +

0x80000) //暂设置环境变量的首地址为0x80000 //在256K处放uboot参数

5、添加Norflash的information

vi include/flash.h

第181行添加

#define EON_ID_LV160AB 0x22492249

6、修改norflash的驱动,在u-boot中对Nor Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、write_hword。

vi board/samsung/smdk2440/flash.c

由-One 8-Kword, two 4-Kword, one 16-Kword,and thirty-one 32-Kword sectors(word mode)

可知主要扇区大小为32k,so修改第31行

#define MAIN_SECT_SIZE 0x8000 //定义为32k,主要扇区的大小

#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))

#define MEM_FLASH_ADDR2 (*(volatile u16

*)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))

由于我们是把norflash连接到了s3c2440的bank0上,因此norflash中的地址相对于s3c2440来说基址为0x00000000,即CONFIG_SYS_FLASH_BASE= 0。

而之所以又把norflash中的地址向左移一位(即乘以2),是因为我们是把s3c2440的ADDR1连接到了norflash的A0上的缘故。

由数据手册可知EN29LV160AB第0扇区大小为8K,第1、2为4K,第3为16K,后面31扇区为32K。前面4个扇区加起来刚好是主要扇区的大小= 32K, 所以修改87行下如下

for (j = 0; j < flash_info[i].sector_count; j++)

{

if (j <= 3)

{

/* 1st one is 8 KB */

if (j == 0)

{

flash_info[i].start[j] = flashbase + 0;

}

/* 2nd and 3rd are both 4 KB */

if ((j == 1) || (j == 2))

{

flash_info[i].start[j] = flashbase + 0x2000 + (j - 1) * 0x1000; }

/* 4th 16 KB */

if (j == 3)

{

flash_info[i].start[j] = flashbase + 0x4000;

}

}

else

{

flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE; }

}

size += flash_info[i].size;

修改flash_print_info,添加EN29LV160AB相关信息如下:

switch (info->flash_id & FLASH_VENDMASK) {

case (AMD_MANUFACT & FLASH_VENDMASK):

printf ("AMD: ");

break;

case (EON_MANUFACT & FLASH_VENDMASK):

printf ("EON: ");

break;

default:

printf ("Unknown Vendor ");

break;

}

switch (info->flash_id & FLASH_TYPEMASK) {

case (AMD_ID_LV400B & FLASH_TYPEMASK):

printf ("1x Amd29LV400BB (4Mbit)\n");

break;

case (AMD_ID_LV800B & FLASH_TYPEMASK):

printf ("1x Amd29LV800BB (8Mbit)\n");

break;

case (EON_ID_LV160AB & FLASH_TYPEMASK):

printf ("1x EN29LV160AB (16Mbit)\n");

break;

default:

printf ("Unknown Chip Type\n");

goto Done;

break;

}

修改int flash_erase (flash_info_t * info, int s_first, int s_last) if ((info->flash_id & FLASH_VENDMASK) !=

(EON_MANUFACT & FLASH_VENDMASK)) {

return ERR_UNKNOWN_FLASH_VENDOR;

7、至此,uboot关于Norflash已经移植好

make distclean

make smdk2440_config

make即可生成u-boot.bin

下载到板子的Norflash,在命令台输入saveenv即可

[SMDK2440]# saveenv

Saving Environment to Flash...

Un-Protected 2 sectors

Erasing Flash...Erasing sector 19 ... ok.

Erasing sector 20 ... ok.

Erased 2 sectors

Writing to Flash... done

Protected 2 sectors

[SMDK2440]# flinfo

Bank # 1: EON: 1x EN29LV160AB (16Mbit)

Size: 2 MB in 35 Sectors

Sector Start Addresses:

00000000 (RO) 00002000 (RO) 00003000 (RO) 00004000 (RO) 00008000 (RO)

00010000 (RO) 00018000 (RO) 00020000 00028000 00030000 00038000 00040000 00048000 00050000 00058000

00060000 00068000 00070000 00078000 00080000

00088000 00090000 00098000 000A0000 000A8000

000B0000 000B8000 000C0000 000C8000 000D0000 000D8000 000E0000 000E8000 000F0000 000F8000 [SMDK2440]#

/*

关于Norflash的好文章

https://www.doczj.com/doc/c310102687.html,/zhaocj/archive/2010/07/04/5712259.aspx

*/

u-boot-2011.03在TQ2440上的移植(4)--支持nandflash启动收藏

1、由原理图知接TQ2440的nanflash型号是K9F2G08U0A,2KB页面大页结构,256M。16位数据格式,接2440如下图所示:

2、在include/configs/smdk2440.h头文件中定义Nand要用到的宏和寄存器,如下:

vi include/configs/smdk2440.h

/*

* Nand flash register and envionment variables

*/

#define CONFIG_S3C2440_NAND_BOOT 1

#define NAND_CTL_BASE 0x4E000000

#define STACK_BASE 0x33F00000

#define STACK_SIZE 0x8000

#define oNFCONF 0x00

#define oNFCONT 0x04

#define oNFADDR 0x0c //0x4E00000c

#define oNFDATA 0x10 //0x4E000010

#define oNFCMD 0x08 //0x4E000008

#define oNFSTAT 0x20 //0x4E000020

#define oNFECC 0x2c //0x4E00002c

3、修改cpu/arm920t/start.S这个文件,使u-boot从Nand Flash启动,在上一节中提过,u-boot默认是从Nor Flash启动的。修改部分如下:

//注释掉系统从Norflash启动这部分代码

#if 0

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate: /* relocate U-Boot to RAM */

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

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2 /* r2 <- size of armboot */

add r2, r0, r2 /* r2 <- source end address */

copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0] */

stmia r1!, {r3-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source end addreee [r2] */

ble copy_loop

#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

#endif

//下面添加2440中u-boot从Nand Flash启动-----------------

#ifdef CONFIG_S3C2440_NAND_BOOT

mov r1, #NAND_CTL_BASE //复位Nand Flash

ldr r2, =( (0<<12)|(3<<8)|(0<<4)|(3<<2)|(1<<1) )

str r2, [r1, #oNFCONF] //设置配置寄存器的初始值,参考s3c2440手册

ldr r2, [r1, #oNFCONF]

ldr r2, =( (1<<4)|(1<<1)|(1<<0) )

str r2, [r1, #oNFCONT] //设置控制寄存器

ldr r2, [r1, #oNFCONT]

//ldr r2, =(0x01) //RnB Clear

//str r2, [r1, #oNFSTAT]

//ldr r2, [r1, #oNFSTAT]

mov r2, #0xff //复位command

strb r2, [r1, #oNFCMD]

mov r3, #0 //等待

nand1:

add r3, r3, #0x1

cmp r3, #0xa

blt nand1

nand2:

ldr r2, [r1, #oNFSTAT] //等待就绪

tst r2, #0x4

beq nand2

ldr r2, [r1, #oNFCONT]

orr r2, r2, #0x02 //取消片选

str r2, [r1, #oNFCONT]

//get read to call C functions (for nand_read())

ldr sp, DW_STACK_START //为C代码准备堆栈,DW_STACK_START定义在下面

mov fp, #0

//copy U-Boot to RAM

ldr r0, =TEXT_BASE//传递给C代码的第一个参数:u-boot在RAM中的起始地

mov r1, #0x0 //传递给C代码的第二个参数:Nand Flash的起始地址

mov r2, #0x30000 //传递给C代码的第三个参数:u-boot的长度大小(192k) bl nand_read_ll //此处调用C代码中读Nand的函数,现在还没有要自己编写实现

tst r0, #0x0

beq ok_nand_read

bad_nand_read:

loop2: b loop2 //infinite loop

ok_nand_read:

//检查搬移后的数据,如果前4k完全相同,表示搬移成功

mov r0, #0

ldr r1, =TEXT_BASE

mov r2, #0x1000 //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 //CONFIG_S3C2440_NAND_BOOT

//以上为2440中u-boot从Nand Flash启动-----------------

4、在board/samsung/smdk2440/目录下新建一个nand_read.c文件,在该文件中来实现上面汇编中要调用的nand_read_ll函数,代码如下:

#include

#define BUSY 1

#define NF_BASE 0x4E000000 //Nand Flash配置寄存器基地址

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NFCONF __REGi(NF_BASE + 0x0 ) //通过偏移量还是得到配置寄存器基地址

#define NFCONT __REGi(NF_BASE + 0x4 ) //通过偏移量得到控制寄存器基地址

#define NFCMD __REGb(NF_BASE + 0x8 ) //通过偏移量得到指令寄存器基地址

#define NFADDR __REGb(NF_BASE + 0xC ) //通过偏移量得到地址寄存器基地址

#define NFDATA __REGb(NF_BASE + 0x10) //通过偏移量得到数据寄存器基地址

#define NFSTAT __REGb(NF_BASE + 0x20) //通过偏移量得到状态寄存器基地址

#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1)) //Nand片选使能

#define NAND_CHIP_DISABLE (NFCONT |= (1<<1)) //取消Nand片选#define NAND_CLEAR_RB (NFSTAT |= BUSY)

#define NAND_DETECT_RB { while(!(NFSTAT & BUSY));}

#define NAND_SECTOR_SIZE 2048

#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

static void s3c2440_write_addr_lp(unsigned int addr)

{

int i;

volatile unsigned char *p = (volatile unsigned char *)&NFADDR;

int col, page;

col = addr & NAND_BLOCK_MASK;

page = addr / NAND_SECTOR_SIZE;

*p = col & 0xff; /* Column Address A0~A7 */

for(i=0; i<10; i++);

*p = (col >> 8) & 0x0f; /* Column Address A8~A11 */

for(i=0; i<10; i++);

*p = page & 0xff; /* Row Address A12~A19 */

for(i=0; i<10; i++);

*p = (page >> 8) & 0xff; /* Row Address A20~A27 */

for(i=0; i<10; i++);

*p = (page >> 16) & 0x01; /* Row Address A28~A29 */

for(i=0; i<10;

i++);

}

/* low level nand read function */

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

int i, j;

if ((start_addr & NAND_BLOCK_MASK) || (size &

NAND_BLOCK_MASK))

{

return -1; //地址或长度不对齐

}

NAND_CHIP_ENABLE; //选中Nand片选

for(i = start_addr; i < (start_addr + size);)

{

//发出READ0指令

//NAND_CLEAR_RB;

NFCMD = 0;

s3c2440_write_addr_lp(i);

//2k page

NFCMD = 0x30;

NAND_DETECT_RB;

for(j=0; j < NAND_SECTOR_SIZE; j++, i++)

{

*buf = NFDATA;

buf++;

}

}

NAND_CHIP_DISABLE; //取消片选信号

return 0;

}

以上紫色部分对应于K9F2G08U0A的数据手册写操作顺序,如下图所示:

整一芯片= 2048块

一个块(扇区)= 64 页

一页= 2048 字节+ 64字节

5、然后,在board/samsung/smdk2440/Makefile中添加nand_read.c的编译选项,使他编译到u-boot中,如下:

COBJS := smdk2440.o flash.o nand_read.o

6、还有一个重要的地方要修改,在arch/arm/cpu/arm920t/u-boot.lds中,这个u-boot启动连接脚本文件决定了u-boot运行的入口地址,以及各个段的存储位置,这也是链接定位的作用。添加下面两行代码的主要目的是防止编译器把我们自己添加的用于nandboot的子函数放到4K之后,否则是无法启动的。如下:

.text :

{

arch/arm/cpu/arm920t/start.o (.text)

board/samsung/smdk2440/lowlevel_init.o (.text)

board/samsung/smdk2440/nand_read.o (.text)

*(.text)

}

7、现在进入u-boot的第二阶段(添加Nand Flash(K9F2G08U0A)的有关操作支持)。在上一节中我们说过,通常在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动,但不管是从Nor启动或者从Nand启动,进入第二阶段以后,两者的执行流程是相同的。

当u-boot的start.S运行到“_start_armboot: .word start_armboot”时,就会调用

lib_arm/board.c中的start_armboot函数,至此u-boot正式进入第二阶段。此时注意:以前较早的u-boot版本进入第二阶段后,对Nand Flash的支持有新旧两套代码,新代码在drivers/nand目录下,旧代码在drivers/nand_legacy目录下,CFG_NAND_LEGACY宏决定了使用哪套代码,如果定义了该宏就使用旧代码,否则使用新代码。但是现在的

u-boot-2010.06版本对Nand的初始化、读写实现是基于最近的Linux内核的MTD架构,删除了以前传统的执行方法,使移植没有以前那样复杂了,实现Nand的操作和基本命令都直接在drivers/mtd/nand目录下(在doc/README.nand中讲得很清楚)。下面我们结合代码来分析一下u-boot在第二阶段的执行流程:

8、//新建s3c2440_nand.c文件,来实现对Nandflash的各种操作。

touch drivers/mtd/nand/s3c2440_nand.c

#include

#if 0

#define DEBUGN printf

#else

#define DEBUGN(x, args ...) {}

#endif

#include

#include

#include

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000 //Nand配置寄存器基地址

#define NFCONF __REGi(NF_BASE + 0x0) //偏移后还是得到配置寄存器基地址#define NFCONT __REGi(NF_BASE + 0x4) //偏移后得到Nand控制寄存器基地址

#define NFCMD __REGb(NF_BASE + 0x8) //偏移后得到Nand指令寄存器基地址

#define NFADDR __REGb(NF_BASE + 0xc) //偏移后得到Nand地址寄存器基地址

#define NFDATA __REGb(NF_BASE + 0x10) //偏移后得到Nand数据寄存器基地址

#define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移后得到Nand主数据区域ECC0寄存器基地址

#define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移后得到Nand主数据区域ECC1寄存器基地址

#define NFSECCD __REGi(NF_BASE + 0x1C) //偏移后得到Nand空闲区域ECC 寄存器基地址

#define NFSTAT __REGb(NF_BASE + 0x20) //偏移后得到Nand状态寄存器基地址

#define NFSTAT0 __REGi(NF_BASE + 0x24) //偏移后得到Nand ECC0状态寄存器基地址

#define NFSTAT1 __REGi(NF_BASE + 0x28) //偏移后得到Nand ECC1状态寄存器基地址

#define NFMECC0 __REGi(NF_BASE + 0x2C) //偏移后得到Nand主数据区域ECC0状态寄存器基地址

#define NFMECC1 __REGi(NF_BASE + 0x30) //偏移后得到Nand主数据区域ECC1状态寄存器基地址

#define NFSECC __REGi(NF_BASE + 0x34) //偏移后得到Nand空闲区域ECC状态寄存器基地址

#define NFSBLK __REGi(NF_BASE + 0x38) //偏移后得到Nand块开始地址

#define NFEBLK __REGi(NF_BASE + 0x3c) //偏移后得到Nand块结束地址

#define S3C2440_NFCONT_nCE (1<<1)

#define S3C2440_ADDR_NALE 0x0c

#define S3C2440_ADDR_NCLE 0x08

ulong IO_ADDR_W = NF_BASE;

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) {

struct nand_chip *chip = mtd->priv;

DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

if (ctrl & NAND_CTRL_CHANGE) {

IO_ADDR_W = NF_BASE;

if (!(ctrl & NAND_CLE)) //要写的是地址

IO_ADDR_W |= S3C2440_ADDR_NALE;

if (!(ctrl & NAND_ALE)) //要写的是命令

IO_ADDR_W |= S3C2440_ADDR_NCLE;

if (ctrl & NAND_NCE)

NFCONT &= ~S3C2440_NFCONT_nCE; //使能nand flash else

NFCONT |= S3C2440_NFCONT_nCE; //禁止nand flash }

if (cmd != NAND_CMD_NONE)

writeb(cmd,(void *)IO_ADDR_W);

}

static int s3c2440_dev_ready(struct mtd_info *mtd)

{

DEBUGN("dev_ready\n");

return (NFSTAT & 0x01);

}

int board_nand_init(struct nand_chip *nand)

{

u_int32_t cfg;

u_int8_t tacls, twrph0, twrph1;

struct s3c24x0_clock_power * const clk_power =

s3c24x0_get_base_clock_power();

DEBUGN("board_nand_init()\n");

clk_power->CLKCON |= (1 << 4);

twrph0 = 3; twrph1 = 0; tacls = 0;

cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4)|(3<<2)|(1<<1)|(0<<0);

NFCONF = cfg;

//cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);

cfg = (1<<4)|(0<<1)|(1<<0);

NFCONT = cfg;

/* initialize nand_chip data structure */

nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

/* read_buf and write_buf are default */

/* read_byte and write_byte are default */

/* hwcontrol always must be implemented */

nand->cmd_ctrl = s3c2440_hwcontrol;

nand->dev_ready = s3c2440_dev_ready;

nand->ecc.mode = NAND_ECC_SOFT;

return 0;

}

添加完以后还要修改Makefile

vi drivers/mtd/nand/Makefile

添加如下两行:

COBJS-y += s3c2440_nand.o

COBJS-$(CONFIG_NAND_S3C2440)+= s3c2440_nand.o

9、在Nandflash上保存环境变量

vi include/configs/smdk2440.h

//注释掉环境变量保存到Flash的宏(注意:如果你要使用上一篇中的从Nor启动的saveenv命令,则要恢复这些Flash宏定义)

/*

#define CONFIG_ENV_IS_IN_FLASH 1

#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */

*/

//添加环境变量保存到Nand的宏(注意:如果你要使用上一篇中的从Nor启动的saveenv 命令,则不要这些Nand宏定义)

#define CONFIG_ENV_IS_IN_NAND 1

#define CONFIG_ENV_OFFSET 0x30000 //将环境变量保存到nand中的0x30000位置

#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */

10、编译

make smdk2440_config && make

把根目录下的u-boot.bin 下载到Nandflash的地址0处

saveenv

nand info

[SMDK2440]# nand info

Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB

u-boot-2011.03在TQ2440上的移植(6)--支持dm9000x网卡收藏

移植过程基本同https://www.doczj.com/doc/c310102687.html,/u3/101649/showart_2126764.html,稍作修改

1、u-boot-2011.03默认的网卡是CS8900,所以要先把它屏蔽掉

vi include/configs/smdk2440.h

/*

#define CONFIG_NET_MULTI

#define CONFIG_CS8900 /* we have a CS8900 on-board */

UBOOT命令详解

常用U-boot命令详解(z) 2010-09-30 15:05:52| 分类:学习心得体会|字号订阅 U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的 U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。 [u-boot@MINI2440]# version U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# v U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# base Base Address: 0x00000000 [u-boot@MINI2440]# ba Base Address: 0x00000000 由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧! (1)获取帮助 命令:help 或? 功能:查看当前U-boot版本中支持的所有命令。 [u-boot@MINI2440]#help ?- alias for'help' askenv - get environment variables from stdin base - print or set address offset bdinfo - print Board Info structure bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol

UBoot移植详解

u-boot 移植步骤详解 1 U-Boot简介 U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux 系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。 选择U-Boot的理由: ①开放源码; ②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS; ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale; ④较高的可靠性和稳定性; ④较高的可靠性和稳定性; ⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等; ⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等; ⑦较为丰富的开发调试文档与强大的网络技术支持; 2 U-Boot主要目录结构 - board 目标板相关文件,主要包含SDRAM、FLASH驱动; - common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

Tiny6410_Uboot移植步骤详解

Uboot_for_Tiny6410_移植步骤详解 一、设计要求 1.目的 1)掌握U-boot剪裁编写 2)掌握交叉编译环境的配置 3)掌握U-boot的移植 2.实现的功能 1)U-boot编译成功 2)移植U-boot,使系统支持从NAND FLASH启动 二、设计方案 1.硬件资源 1)ARM处理器:ARM11芯片(Samsung S3C6410A),基于ARM1176JZF-S核设 计,运行频率533Mhz,最高可达 667Mhz 2)存储器:128M DDR RAM,可升级至 256M;MLC NAND Flash(2GB) 3)其他资源:具有三LCD接口、4线电阻 触摸屏接口、100M标准网络接口、标准DB9 五线串口、Mini USB2.0接口、USB Host 1.1、3.5mm音频输入输出口、标准TV-OUT

接口、SD卡座、红外接收等常用接口;另外 还引出4路TTL串口,另1路TV-OUT、 SDIO2接口(可接SD WiFi)接口等;在板的 还有蜂鸣器、I2C-EEPROM、备份电池、A D 可调电阻、8个中断式按键等。 2.软件资源 1)arm-linux-gcc-4.5.1(交叉编译) 2)u-boot-2010.09.tar.gz arm-linux-gcc-4.5.1-v6-vfp-20101103.t gz 三、移植过程 1.环境搭建 1)建立交叉编译环境 2)去这2个网站随便下载都可以下载得到最 新或者你想要的u-boot。( https://www.doczj.com/doc/c310102687.html,/batch.viewl ink.php?itemid=1694 ftp://ftp.denx.de/pub/u-boot/ )

i.MX6UL -- Linux系统移植过程详解(最新的长期支持版本)

i.MX6UL -- Linux系统移植过程详解(最新的长期支持版本) ?开发平台:i.MX 6UL ?最新系统: u-boot2015.04 + Linux4.1.15_1.2.0 ?交叉编译工具:dchip-linaro-toolchain.tar.bz2 源码下载地址: U-Boot: (选择rel_imx_4.1.15_1.2.0_ga.tar.bz2) https://www.doczj.com/doc/c310102687.html,/git/cgit.cgi/imx/uboot-imx.git/ Kernel: (选择rel_imx_4.1.15_1.2.0_ga.tar.bz2) https://www.doczj.com/doc/c310102687.html,/git/cgit.cgi/imx/linux-2.6-imx.git/ 源码移植过程: 1、将linux内核及uBoot源码拷贝到Ubuntu12.04系统中的dchip_imx6ul目录下; 2、使用tar命令分别将uboot和kernel解压到dchip_imx6ul目录下; 3、解压后进入uboot目录下,新建文件make_dchip_imx6ul_uboot201504.sh,且文件内容如下: ################################################################### # Build U-Boot.2015.04 For D518--i.MX6UL By FRESXC # ################################################################### #!/bin/bash export ARCH=arm export CROSS_COMPILE=/dchip-linaro-toolchain/bin/arm-none-linux-gnueabi - make mrproper # means CLEAN make mx6ul_14x14_evk_defconfig make2>&1|tee built_dchip_imx6ul_uboot201504.out 4进入kernel目录下,新建文件make_dchip_imx6ul_linux4115120.sh,且文件内容如下: ###################################################################

UBoot源码分析1

?UBoot源码解析(一)

主要内容 ?分析UBoot是如何引导Linux内核 ?UBoot源码的一阶段解析

BootLoader概念?Boot Loader 就是在操作系统内核运行之前运行 的一段小程序。通过这段小程序,我们可以初始 化硬件设备、建立内存空间的映射图,从而将系 统的软硬件环境带到一个合适的状态,以便为最 终调用操作系统内核准备好正确的环境 ?通常,Boot Loader 是严重地依赖于硬件而实现 的,特别是在嵌入式世界。因此,在嵌入式世界 里建立一个通用的Boot Loader 几乎是不可能的。 尽管如此,我们仍然可以对Boot Loader 归纳出 一些通用的概念来,以指导用户特定的Boot Loader 设计与实现。

UBoot来源?U-Boot 是 Das U-Boot 的简称,其含义是 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。最早德国 DENX 软件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSROM 的源码创建了 PPCBoot 工程项目,此后不断 添加处理器的支持。而后,Sysgo Gmbh 把 PPCBoot 移 植到 ARM 平台上,创建了 ARMBoot 工程项目。最终, 以 PPCBoot 工程和 ARMBoot 工程为基础,创建了 U- Boot 工程。 ?而今,U-Boot 作为一个主流、通用的 BootLoader,成功地被移植到包括 PowerPC、ARM、X86 、MIPS、NIOS、XScale 等主流体系结构上的百种开发板,成为功能最多、 灵活性最强,并且开发最积极的开源 BootLoader。目前。 U-Boot 仍然由 DENX 的 Wolfgang Denk 维护

uboot移植步骤介绍

uboot移植过程 1.修改Makefile 首先给要建立的S3C2410开发板取名为TE2410, 移植uboot时以smdk2410为模板, 修改Makefile #tar xvjf u-boot-1.1.3.tar.bz2 #cd u-boot-1.1.3 #vi Makefile scb9328_config : unconfig @./mkconfig $(@:_config=) arm arm920t scb9328 NULL imx smdk2400_config : unconfig @./mkconfig $(@:_config=) arm arm920t smdk2400 NULL s3c24x0 smdk2410_config : unconfig @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0 SX1_config : unconfig @./mkconfig $(@:_config=) arm arm925t sx1 te2410_config : unconfig @./mkconfig $(@:_config=) arm arm920t te2410 NULL s3c24x0 蓝色字体是添加的内容。其中,te2410_config : unconfig意思是为TE2410建立一个编译项,@./mkconfig $(@:_config=) arm arm920t te2410 NULL s3c24x0中的arm表示CPU的架构是基于ARM体系结构的;arm920t表示CPU类型是arm920t;te2410是开发板的型号;NULL表示开发商或经销商的名称为空;s3c24x0表示是基于s3c24x0的片上系统。 2.在uboot的board目录下建立te2410开发板子目录 #cp –fr board/smdk2410 /board/te2410 #cd board/te2410 #mv smdk2410.c te2410.c 还要修改board/te2410/Makefile文件, OBJS := smdk2410.o flash.o -------- OBJS := te2410.o flash.o 3.在include/configs目录下建立te2410.h头文件 #cd include/configs #cp –fr smdk2410.h te2410.h 4.指定交叉编译器的路径 选择支持softfloatpoint的交叉编译器,在etc/bashrc文件中添加一行 export PATH=/home/newdisk/toolchain/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linu x-gnu/bin:$PATH 其中, /home/newdisk/toolchain/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu /bin是交叉编译器路径

uboot移植实验

一、移植环境 ?主机:UBUNTU ?开发板:飞凌2440 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.03.tar.bz2

3)修改u-boot根目录下的Makefile文件。查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立mini2440_config的编译选项,另外还要指定交叉编译器 4)测试编译新建的mini2440开发板项目

到此为止,u-boot对自己的mini2440开发板还没有任何用处,以上的移植只是搭建了一个mini2440开发板u-boot的框架,要使其功能实现,还要根据mini2440开发板的具体资源情况来对u-boot源码进行修改。 3. 根据u-boot启动流程图的步骤来分析或者修改添加u-boot源码,使之适合mini2440开发板(注:修改或添加的地方都用红色表示)。 1)mini2440开发板u-boot的stage1入口点分析。 一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。那么我们的my2440开发板u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下:

知道了程序的入口点是_start,那么我们就打开mini2440开发板u-boot第一个要运行的程序cpu/arm920t/start.S(即u-boot的stage1部分),查找到_start的位置如下: 从这个汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code 处的代码如下:

嵌入式Linux之我行 史上最牛最详细的uboot移植,不看别后悔

嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一) 嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux 的朋友提供方便。如有错误之处,谢请指正。 ?共享资源,欢迎转载:https://www.doczj.com/doc/c310102687.html, 一、移植环境 ?主机:VMWare--Fedora 9 ?开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 本次移植的功能特点包括: ?支持Nand Flash读写 ?支持从Nor/Nand Flash启动 ?支持CS8900或者DM9000网卡 ?支持Yaffs文件系统 ?支持USB下载(还未实现) 1.了解u-boot主要的目录结构和启动流程,如下图。

u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。各个部分的流程图如下:

2. 建立自己的开发板项目并测试编译。 目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM 处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。 1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440 2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改

uboot环境变量总结

Common目录下面与环境变量有关的文件有以下几个:env_common.c,env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c,env_nowhere.c,env_nvram.c,environment.c。 env_common.c中包含的是default_environment[]的定义; env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c, env_nvram.c 中包含的是相应存储器与环境变量有关的函数:env_init(void),saveenv(void),env_relocate_spec (void),env_relocate_spec (void),use_default()。至于env_nowhere.c,因为我们没有定义CFG_ENV_IS_NOWHERE,所以这个文件实际上没有用。 environment.c这个文件时是我真正理解环境变量的一个关键。在这个文件里定义了一个完整的环境变量的结构体,即包含了这两个ENV_CRC(用于CRC校验),Flags(标志有没有环境变量的备份,根据CFG_REDUNDAND_ENVIRONMENT这个宏定义判断)。定义这个环境变量结构体的时候还有一个非常重要的关键字: __PPCENV__,而__PPCENV__在该.c文件中好像说是gnu c编译器的属性,如下: # define __PPCENV__ __attribute__ ((section(".text"))) 意思是把这个环境变量表作为代码段,所以在编译完UBOOT后,UBOOT的代码段就会有环境变量表。当然,这要在我们定义了ENV_IS_EMBEDDED之后才行,具体而言,环境变量表会在以下几个地方出现(以nand flash为例): 1、UBOOT中的代码段(定义了ENV_IS_EMBEDDED), 2、UBOOT中的默认环 境变量, 3、紧接UBOOT(0x0 ~ 0x1ffff)后面:0x20000 ~ 0x3ffff 之间,包括备份的环境变量,我们读取,保存也是对这个区域(即参数区)进行的。3、SDRAM中的UBOOT中,包括代码段部分和默认部分,4、SDRAM中的melloc分配的内存空间中。 Environment.c代码如下: env_t environment __PPCENV__ = { ENV_CRC, /* CRC Sum */ #ifdef CFG_REDUNDAND_ENVIRONMENT 1, /* Flags: valid */ #endif { #if defined(CONFIG_BOOTARGS) "bootargs=" CONFIG_BOOTARGS "\0" #endif #if defined(CONFIG_BOOTCOMMAND) "bootcmd=" CONFIG_BOOTCOMMAND "\0" #endif #if defined(CONFIG_RAMBOOTCOMMAND) "ramboot=" CONFIG_RAMBOOTCOMMAND "\0"

u_boot移植(五)之分析uboot源码中nand flash操作

u_boot移植(五)之分析uboot源码中nand flash操作 一、OneNand 和Nand Flash 我们已经能从Nand Flash启动了,启动之后,大家会看到如下效果: 可以看出,我们的uboot默认使用的是OneNand。需要注意的是我们的FSC100上面是没有OneNand的,有的是K9F2G08U0B 型号的NAND FLASH。 前面我们了解过Nor Flash 和Nand Flash,那OneNand Flash又是什么呢?

二、uboot 源码中Nand Flash部分代码分析 我们从Nand Flash初始化看起,打开lib_arm/board.c文件,为了紧抓主 线,以下代码只列举出了主线代码。

可以看出,我们可以通过CONFIG_CMD_NAND和 CONFIG_CMD_ONENAND两个宏来选择NAND FLASH初始化还是 ONENAND FLASH初始化。 uboot 中默认定义了宏CONFIG_CMD_ONENAND,所以选择的是ONENAND FLASH初始化。我们的FSC100上面使用的是 NAND FLASH,所以我们要定义CONFIG_CMD_NAND宏,取消CONFIG_CMD_ONENAND宏的定义。 嗯!先做个记录: 修改include/configs/fsc100.h,定义宏CONFIG_CMD_NAND,取消宏CONFIG_CMD_ONENAND。 好了,接下我们看看nand_init()函数时如何实现的。

看以看出,这段代码调用根据CONFIG_SYS_MAX_NAND_DEVICE宏[默认没有定义]的值来决定系统中Nand Flash设备的个数。接着调 用nand_init_chip()函数完成Nand Flash初始化,然后计算出每块Nand Flash的大小。最终会输出Nand Flash总的容量。 嗯!做个记录: 修改include/configs/fsc100.h,定义 宏CONFIG_SYS_MAX_NAND_DEVICE,值为1 没有看明白的地方是给nand_init_chip()函数传递的参数,接下来我们来看看他们是如何定义的。 哈哈,终于到了让人头疼的地方了。先来看看struct nand_chip和struct mtd_info两个结构体,这两个结构体的成员有很多很多,很多初学者一看到就晕头转向了,为了让大家不被吓到,我对这两个结构体的成员做了精简,只保留我们关心的成员,其它的都去掉了。 (1)struct nand_chip

UBOOT详细解读

大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。 1、Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。 (2)设置异常向量(Exception Vector)。 (3)设置CPU的速度、时钟频率及终端控制寄存器。 (4)初始化内存控制器。 (5)将ROM中的程序复制到RAM中。 (6)初始化堆栈。 (7)转到RAM中执行,该工作可使用指令ldr pc来完成。 2、Stage2 C语言代码部分 lib_arm/board.c中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作: (1)调用一系列的初始化函数。 (2)初始化Flash设备。 (3)初始化系统内存分配函数。 (4)如果目标系统拥有NAND设备,则初始化NAND设备。 (5)如果目标系统有显示设备,则初始化该类设备。 (6)初始化相关网络设备,填写IP、MAC地址等。 (7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。 3、U-Boot的启动顺序(示例,其他u-boot版本类似) cpu/arm920t/start.S @文件包含处理 #include @由顶层的mkconfig生成,其中只包含了一个文件:configs/<顶层makefile中6个参数的第1个参数>.h #include #include

uboot移植笔记

u-boot-2015-01移植笔记 一、修改编译器路径 修改顶层Makefile文件,查找CROSS_COMPILE =,注释掉if判断,增加一行CROSS_CMPILE = arm-linux- (根据编译器不同这个自行添加,在这里感谢胡茂晓同学)。 二、复制平台相近board 1、进入board子目录下的samsung子目录,复制trats2文件夹为自己平台名字的文件夹(这里笔者使用iTop4412)。 2、进入iTop4412子目录,修改为。 3、修改Makefile,将trats2改为iTop4412。 三、修改板子相应配置 1、从源码根目录下进入include/configs目录,复制为。 2、从源码根目录下进入configs目录,复制trats2_defconfig为iTop4412_defconfig。 3、修改iTop4412_defconfig,将CONFIG_DEFAULT_DEVICE_TREE="exynos4412-trats2"改为CONFIG_DEFAULT_DEVICE_TREE="exynos4412-iTop4412"。

四、增加自己的Device Tree Source 1、从源码根目录下进入arch/arm/Dts目录,复制 exynos4412- 。 2、修改当前目录下的Makefile文件,将 dtb-$(CONFIG_EXYNOS4) += \ \ \ \ \ 修改成 dtb-$(CONFIG_EXYNOS4) += \ \ \ \ \ \

五、制作顶层.config文件 1、在源码根目录下使用命令make menuconfig(貌似刚支持图形界面配置)。 2、先配置基本的,Architecture select 选项选择ARM architecture,architecture选项的子选项Target select选择Samsun EXYNOS;EXYNOS board select选项选择Exynos4412 Trat2 board。 3、在Device Tree Control选项下,y(yes)Run-time configuration via Device Tree,选择Provider of DTB for control 为Embedded DTB for DT control,在Default Device Tree for DT control选项下输入exynos4412-iTop4412,退出。 4、保存退出,在源码根目录下会生成.config文件,需要用命令ls –a 查看。 5、在源码根目录下使用命令vim .config,修改.config文件。将CONFIG_SYS_BOARD="trats2" 修改成CONFIG_SYS_BOARD="iTop4412";将CONFIG_SYS_CONFIG_NAME="trats2"修改成CONFIG_SYS_CONFIG_NAME="iTop4412";将CONFIG_DEFAULT_DEVICE_TREE=""修改成CONFIG_DEFAULT_DEVICE_TREE="exynos4412-iTop4412"。(注意:每次使用make menuconfig后都要修改本条)

Uboot_for_mini6410_移植步骤详解

这是u-boot-2010.09 针对友善之臂MINI6410移植的最基础版本,只包含了就基本的系统引导,NAND读写,DM9000网卡等等。但是这个足够开发的方便使用。今后会陆续添加原先我为mini2440添加的所有功能。 但是此次移植并非我的功劳,首先基本的移植是由Alex Ling 完成的,你可以在这里看到他提交的补丁,但是编译后无法使用,可能是因为host系统不同,对脚本的解析不同,使得spl部分的生成出现问题,只需修改一下nand_spl目录下目标板目录的中config.mk中的 PAD_TO := $(shell expr $$[$(TEXT_BASE) + 4096]) 即可。 DM9000的驱动没有太大的问题(修改了一点可能出现问题的地方,感谢肖工指教),但是原本的u-boot并没有调整所有SROM控制器的配置(其中包括连接DM9000所使用的bank1的总线),我使用了友善带的u-boot的参数配置了一下就好了。 一:https://www.doczj.com/doc/c310102687.html,/batch.viewlink.php?itemid=1694 ftp://ftp.denx.de/pub/u-boot/ 去这2个网站随便下载都可以下载得到最新或者你想要的u-boot。现在我将下载u-boot-2010-09,这个也就是最新的版本啦。 下载后把它解压,然后得到u-boot-2010-09的文件夹,然后进去,并且做下面几件事情:1:进入arch这个文件夹,把出arm外的前部文件夹删掉 2:进入board这个文件夹,把除samsung外前部文件夹删掉 3:进入include/configs,把除smdk6400.h外的所有文件删除。 4: 把顶层目录下有一个叫onenand_ipl的文件夹删除掉,因为没有用到。 5:进入nand_spl/board,把除samsung外全部文件删除掉。 6:再进入arch/arm/cpu文件夹,把除arm1176外其他文件夹删除掉。 7:再进入arch/arm/include/asm文件夹,把除arch-s3c64xx文件外带arch-XX的文件夹删除8:再进入board/samsung文价夹下,把除smdk6400外其他文价夹删除掉。 至此已经把没用到或者不想见到它的文件夹跟文件删除掉了。爽吧。 二: 1:在顶层的目录下找到Makefile文件,并且打开,因为vi或者vim没用习惯而是改用gedit。lwf@lwf-desktop:/home/u-boot-2010.12$ sudo gedit Makefile 在这个Makefile你会找到: ######################################################################### ## ARM1176 Systems ######################################################################### smdk6400_noUSB_config \ smdk6400_config : unconfig @mkdir -p $(obj)include $(obj)board/samsung/smdk6400 @mkdir -p $(obj)nand_spl/board/samsung/smdk6400

韦东山u-boot移植笔记

一:准备移植 1、从下面的官网下载最新的U-boot。用google英文版搜索最新的u-boot源码 ftp://ftp.denx.de/pub/u-boot/ 2、建立sourceinsight工程 a、解压并在E:\colin weidongshan\transplant_u-boot-2012.04.01\u-boot-2012.04.01建立SI b、添加文件到SI工程 1、点击"Add All",选中“Include top level sub-directories”和“Recursively add lower sub-directories”点击“OK” 2、选中“Board”目录,点击“Remove Tree”,去掉总个目录 进入“Board\Samsung\Smdk2410\”,点击"Add All" 3、选中“Arch”目录,点击“Remove Tree”,去掉总个目录 进入“Arch\Arm\Cpu\Arm920t\”,双击选中“Cpu.c”“Interrupts.c”“start.S”。 进入“Arch\Arm\Cpu\Arm920t\S3c24x0\”,点击"Add All" 进入“Arch\Arm\”,选中"Dts"目录,点击"Add Tree" 进入“Arch\Arm\Include\Asm\Arch_s3c24x0”,点击"Add All" 进入“Arch\Arm\Include\Asm\”,点击"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加顶层目录的文件 进入“Arch\Arm\Include\Asm\”,单击选中"Proc-armv",点击"Add Tree" 进入“Arch\Arm\Lib\”,点击"Add All" 4、选中“Include”目录,点击“Remove Tree”,去掉总个目录 进入“Include\”,点击"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加顶层目录的文件 进入“Include\”,单击选中"Andestech",点击"Add Tree" 进入“Include\”,单击选中"Asm-generic",点击"Add Tree" 进入“Include\”,同上选中除"Configs"目录外的所有目录,点击"Add Tree"。"Configs"目录先不加,下面再议 进入“Include\Configs\”,双击选中“Smdk2410.h” 5、同步文件,完成 3、编译 尝试编译 解压:book@book-desktop:/work/system$ tar xjf u-boot-2012.04.01.tar.bz2 book@book-desktop:/work/system$ cd u-boot-2012.04.01/ 配置:book@book-desktop:/work/system/u-boot-2012.04.01$ make smdk2410_config 编译:book@book-desktop:/work/system/u-boot-2012.04.01$ make

UBOOT分析移植

ARM 平台下的U-boot 移植 u-boot 移植 嵌入式BootLoader 的引导过程 图 1-1给出了嵌入式系统中的一般的引导过程,一般来说,引导程序都是保存在非易失的存储介质(如Flash 等)中,因为引导程序运行的时候需要对数据进行读写操作,所以引导程序的RW 段必须放到RAM 中,所以一般的引导程序初始化的第一件事情就是要在初始化完内存控制器后将其RW 段拷贝到RAM 中,同时开辟一段内存用于其ZI 段。如果引导过程是放置在不可原位执行的存储介质,如NAND Flash 上的时候,引导程序还必须将其自身也拷贝到RAM 中。 一般来说大概的步骤可以分为两个步骤: Stage1 ? 硬件设备初始化(内存控制器的设置); ? 为加载BootLoader 的stage2部分的代码准备RAM 空间; ? 拷贝BootLoader 的stage2部分的代码到RAM 空间中,并跳转执行; ? 设置好堆栈,Heap 等; ? 跳转到 stage2 的 C 入口点; Stage2 ? 初始化本阶段要使用到的硬件设备(net ,flash 等); ? 将OS 映像从 flash 上读到 RAM 空间中; ? 为OS 设置启动参数; ? 跳转到OS 内核image 的入口点。 图1-1 嵌入式系统引导

u-boot简介 U-Boot是由开源项目PPCBoot发展起来的,ARMboot并入了PPCBoot,和其他一些arch 的Loader合称U-Boot。2002年12月17日第一个版本U-Boot-0.2.0发布,同时PPCBoot 和ARMboot停止维护。 U-Boot支持的处理器构架包括PowerPC(MPC5xx, MPC8xx, MPC82xx, MPC7xx,MPC74xx, 4xx), ARM(ARM7,ARM9,StrongARM,Xscale),MIPS (4Kc,5Kc),x86等等,U-Boot (Universal Bootloader)是在GPL下资源代码最完整的一个通用Boot Loader。 U-Boot提供两种操作模式:启动加载(Boot loading)模式和下载(Downloading)模式,并具有大型Boot Loader的全部功能。主要特性为: ●SCC/FEC以太网支持 ●BOOTP/TFTP引导 ●IP,MAC预置功能 ●在线读写FLASH,DOC, IDE,IIC,EEROM,RTC ●支持串行口kermit,S-record下载代码 ●识别二进制、ELF32、pImage格式的Image,对Linux引导有特别的支持 ●监控(minitor)命令集:读写I/O,内存,寄存器、内存、外设测试功能等 ●脚本语言支持(类似BASH脚本) ●支持WatchDog,LCD logo,状态指示功能等 U-Boot的功能是如此之强大,涵盖了绝大部分处理器构架,提供大量外设驱动,支持多个文件系统,附带调试、脚本、引导等工具,特别支持Linux,为板级移植做了大量的工作。U-Boot的完整功能性和后续不断的支持,使系统的升级维护变得十分方便。 u-boot的目录树结构 1.1.1 Borad目录 包括大量的Board dependent files的代码文件,每一个开发板都以一个子目录出现在当前目录中,每个board目录下至少包括这样几个文件 1.config.mk:其中至少包括TEXT_BASE这个一个Makefile的变量,这个变量指出了被编译的可执行uboot image应该放在RAM中的位置,也就是该image的执行位置;2.flash.c:这里主要还是对NorFlash的操作,flash的基本操作; 3.lowlevel_init.S:提供lowlevel_init函数供u-boot在第一阶段调用,一般是针对SDRAM 控制器的初始化,如设置SDRAM的刷新率,等待时钟等,一般来说,如果需要将第二阶段代码和数据拷贝到SDRAM中,这个操作是必须的; 4.Makefile:编译board目录下的代码所使用的makefile; 5.board.c:和板级相关的初始化函数,如设置GPIO,设置时钟,设置总线时序等;6.u-boot.lds:针对开发板的情况编写的连接脚本,通过连接脚本,一般应该将u-boot的stage1的代码放在image的开始的地方; 1.1.2Common目录 该目录下实现uboot支持的命令和公用函数,每一条命令都对应一个文件。例如bootm 命令对应就是cmd_bootm.c。

最新Uboot移植步骤 5:NorFlash

最新Uboot移植步骤5:NorFlash 显示Flash:***failed***,说明norflash未识别,我们搜索“Flash:” 进入第一个查看 找到这个判断条件,如果flash_size>0则输出flash大小,否则输出 *** failed *** ### ERROR ### Please RESET the board ###

其中hang函数导致程序无法继续向下执行,我们只实现了nand启动肯定在这会卡住,所以我们不用这个hang 函数,直接输出flash未识别的信息就好了,改动如下: 现在来找norflash未识别的原因,进入flash_init函数 看见这样一段代码 可知,有2个函数可以检测flash的大小如果flash_detect_legacy函数不行再使用flash_get_size函数,先进入flash_detect_legacy函数看下,其结构如下: 该函数有2个,使用哪一个由宏CONFIG_FLASH_CFI_LEGACY决定,搜索该宏:

很明显,前面我们都是使用该函数进行大小检测的,而该函数无法识别flash,那我们使用新方法进行检测,进入新方法查看: 发现有很多可用调试信息,我们看看如何起用这些调试信息: 发现只要定义了_DEBUG即可启用调试信息,我们定义该宏: 在文件开始发现注释: 我们直接定义DEBUG即可,

配置,编译,下载到板子norflash: 重新上电从norflash启动,输出如下: 我们查看JEDEC PROBE:从哪来

查看norflash手册,看读取的设备ID是否正确 可以看到输出的厂家设备ID是正确的, 说明下面这个函数读取正确 那就是 函数出现错误,我们进入该函数查看:

相关主题
文本预览
相关文档 最新文档