U-Boot从NAND Flash启动的实现

合集下载

u-boot_2010.6nandflash驱动彻底分析

u-boot_2010.6nandflash驱动彻底分析

u-boot_2010.6nandflash驱动彻底分析2017年11⽉13⽇15:37:34最近公司⼤裁员,闹的⼈⼼惶惶,不管怎么样,武装好⾃⼰才是硬道理,坚持学习,学会那些还没学会的。

今天虚拟机突然打不开了,吓了我⼀跳,因为代码都还没备份,⼀定得养成备份代码的习惯!好了,下⾯开始进⼊正题吧,nandflash驱动彻底分析底层驱动移植完后,执⾏nand 命令:nand read 0x30000000 0 0x2000nand read 的命令格式是 nand read addr off | partition size ,总结起来就是读到哪去?从哪读?读多⼤?返回的结果是:NAND read: device 0 offset 0x0, size 0x2000file is nand_util.c,fun is nand_read_skip_bad,line is 599,NAND read from offset 2000 failed -740 bytes read: ERROR读失败,给出读失败错误码 -74要分析失败原因,先分析函数执⾏流程执⾏nand read 命令后,其实是执⾏了nand_read_skip_bad(nand, off, &size,(u_char *)addr);跳过坏块读函数的参数简单明了,从哪读,读到哪去,读多少,以及⼀个公共句柄(包含nand的信息,例如有多少个块,块⼤⼩等) 1int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,2 u_char *buffer)3 {4int rval;5 size_t left_to_read = *length;6 size_t len_incl_bad;7 u_char *p_buffer = buffer;89 len_incl_bad = get_len_incl_bad (nand, offset, *length); /* 函数分析见2017.11.14笔记(往下翻) */1011if ((offset + len_incl_bad) > nand->size) {12 printf ("Attempt to read outside the flash area\n");13return -EINVAL;14 }1516if (len_incl_bad == *length) {17 rval = nand_read (nand, offset, length, buffer);18if (!rval || rval == -EUCLEAN)19return0;20 printf ("NAND read from offset %llx failed %d\n",21 offset, rval);22return rval;23 }2425while (left_to_read > 0) {26 size_t block_offset = offset & (nand->erasesize - 1);27 size_t read_length;2829 WATCHDOG_RESET ();3031if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {32 printf ("Skipping bad block 0x%08llx\n",33 offset & ~(nand->erasesize - 1));34 offset += nand->erasesize - block_offset;35continue;36 }3738if (left_to_read < (nand->erasesize - block_offset))39 read_length = left_to_read;40else41 read_length = nand->erasesize - block_offset;42/* read_length 最⼤不会超过 nand->erasesize (128K) */43/* nand_read 函数是⼀个按块读函数 */44 rval = nand_read (nand, offset, &read_length, p_buffer);45if (rval && rval != -EUCLEAN) {46 printf ("NAND read from offset %llx failed %d\n",47 offset, rval);48 *length -= left_to_read;49return rval;50 }5152 left_to_read -= read_length;53 offset += read_length;54 p_buffer += read_length;55 }5657return0;58 }先看get_len_incl_bad1static size_t get_len_incl_bad (nand_info_t *nand, loff_t offset,2const size_t length)3 {4 size_t len_incl_bad = 0;5 size_t len_excl_bad = 0;6 size_t block_len;78while (len_excl_bad < length) {9 block_len = nand->erasesize - (offset & (nand->erasesize - 1));1011if (!nand_block_isbad (nand, offset & ~(nand->erasesize - 1)))12 len_excl_bad += block_len;1314 len_incl_bad += block_len;15 offset += block_len;1617if (offset >= nand->size)18break;19 }2021return len_incl_bad;22 }想要看懂这个函数,先要理解offset的构成2017年11⽉14⽇10:00:40每天进步⼀点点nand->erasesize = 128K = 0x20000nand->erasesize - 1 = 0x1FFFFoffset & (nand->erasesize - 1) 保留低17位,清⾼位,因为nand的特性,所以是按块来统计长度block_len = nand->erasesize - offset & (nand->erasesize - 1) 作⽤是统计当前块要读的长度然后判断当前块是不是坏块,如果不是坏块,则让len_excl_bad += block_len,判断是否循环的标准是len_excl_bad < length 不论当前块是不是坏块,都让len_incl_bad += block_len,len_incl_bad 得到的是包含坏块的长度总结get_len_incl_bad函数的作⽤为:①如果偏移offset是从整块开始的,返回的结果是块的整数倍(不⽤看length,⽐如length是0x20001,则读两块)②如果偏移offset不是从整块开始的,返回的结果是块的整数倍+第⼀块要读的长度总之,返回的结果是按块补齐的再继续分析nand_read_skip_bad1if (len_incl_bad == *length) {2 rval = nand_read (nand, offset, length, buffer);3if (!rval || rval == -EUCLEAN)4return0;56return rval;7 }什么情况下,len_incl_bad == *length ?要读的内容⾥,没有坏块,且长度最后按块对齐(例如,从0x400开始读,读的长度为0x40000-0x400)如果不满⾜,则进⼊while循环读,在while⾥,按块读,先判断当前块是不是坏块,如果是则跳过,不是则读下⾯分析nand_read函数1/* 1.从哪读 2.读多少 3.读到哪去 */2static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,3 size_t *retlen, uint8_t *buf)4 {5struct nand_chip *chip = mtd->priv;6int ret;78/* Do not allow reads past end of device */9if ((from + len) > mtd->size)10return -EINVAL;11if (!len)12return0;13/* 选中芯⽚ */14 nand_get_device(chip, mtd, FL_READING);1516 chip->ops.len = len;17 chip->ops.datbuf = buf;18 chip->ops.oobbuf = NULL;1920 ret = nand_do_read_ops(mtd, from, &chip->ops);2122 *retlen = chip->ops.retlen;23/* 取消选中芯⽚ */24 nand_release_device(mtd);2526return ret;27 }其实真正的读函数是nand_do_read_ops,从哪去,读多少,读到哪去都被装载在chip->ops结构体中再看nand_do_read_ops函数1/**2 * nand_do_read_ops - [Internal] Read data with ECC3 *4 * @mtd: MTD device structure5 * @from: offset to read from6 * @ops: oob ops structure7 *8 * Internal function. Called with chip held.9*/10static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,11struct mtd_oob_ops *ops)12 {13int chipnr, page, realpage, col, bytes, aligned;14struct nand_chip *chip = mtd->priv;15struct mtd_ecc_stats stats;16int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;17int sndcmd = 1;18int ret = 0;19 uint32_t readlen = ops->len;//128K 0x20000 根据输⼊的长度决定20 uint32_t oobreadlen = ops->ooblen; // oobreadlen = 021 uint8_t *bufpoi, *oob, *buf;2223 stats = mtd->ecc_stats;2425 chipnr = (int)(from >> chip->chip_shift);26 chip->select_chip(mtd, chipnr);27/* realpage 总页地址(⾼17位) */28 realpage = (int)(from >> chip->page_shift);//pageshift is 1129 page = realpage & chip->pagemask;//pagemask = 1ffff30/* col 低11位 */31 col = (int)(from & (mtd->writesize - 1));//writesize = 2048, 2047 = 0x7ff32/* 得到页地址和列地址 */33 buf = ops->datbuf;34 oob = ops->oobbuf;3536while(1) {37 bytes = min(mtd->writesize - col, readlen); //128K 0x20000 根据输⼊的长度决定38 aligned = (bytes == mtd->writesize); //aligned = 1;3940/* Is the current page in the buffer ? */41if (realpage != chip->pagebuf || oob) {42 bufpoi = aligned ? buf : chip->buffers->databuf;43/* 对齐与不对齐读到的缓冲是不⼀样的 */44if (likely(sndcmd)) {45 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);46 sndcmd = 0;47 }4849/* Now read the page into the buffer */50if (unlikely(ops->mode == MTD_OOB_RAW))51 ret = chip->ecc.read_page_raw(mtd, chip,//nand_read_page_raw52 bufpoi, page);//从哪⾥读,读到哪⾥去,读多少53else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)54 ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi);55/* nand_read_subpage */56else57 ret = chip->ecc.read_page(mtd, chip, bufpoi,//整页读 bufpoi = buf58 page); //nand_read_page_swecc59if (ret < 0)60break;6162/* Transfer not aligned data */63if (!aligned) {64if (!NAND_SUBPAGE_READ(chip) && !oob)65 chip->pagebuf = realpage;66 memcpy(buf, chip->buffers->databuf + col, bytes);67 }6869 buf += bytes;7071if (unlikely(oob)) {72/* Raw mode does data:oob:data:oob */73if (ops->mode != MTD_OOB_RAW) {74int toread = min(oobreadlen,75 chip->yout->oobavail);76if (toread) {77 oob = nand_transfer_oob(chip,78 oob, ops, toread);79 oobreadlen -= toread;80 }81 } else82 buf = nand_transfer_oob(chip,83 buf, ops, mtd->oobsize);84 }8586if (!(chip->options & NAND_NO_READRDY)) {87/*88 * Apply delay or wait for ready/busy pin. Do89 * this before the AUTOINCR check, so no90 * problems arise if a chip which does auto91 * increment is marked as NOAUTOINCR by the92 * board driver.93*/94if (!chip->dev_ready)95 udelay(chip->chip_delay);96else97 nand_wait_ready(mtd);98 }99 } else {100 memcpy(buf, chip->buffers->databuf + col, bytes);101 buf += bytes;102 }103104 readlen -= bytes;105106if (!readlen)107break;108109/* For subsequent reads align to page boundary. */110 col = 0;111/* Increment page address */112 realpage++;113114 page = realpage & chip->pagemask;115/* Check, if we cross a chip boundary */116if (!page) {117 chipnr++;118 chip->select_chip(mtd, -1);119 chip->select_chip(mtd, chipnr);120 }121122/* Check, if the chip supports auto page increment123 * or if we have hit a block boundary.124*/125if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))126 sndcmd = 1;127 }128129 ops->retlen = ops->len - (size_t) readlen;130if (oob)131 ops->oobretlen = ops->ooblen - oobreadlen;132133if (ret)134return ret;135136if (mtd->ecc_stats.failed - stats.failed)137return -EBADMSG;138139return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; 140 }。

U-BOOT启动过程

U-BOOT启动过程

U-Boot启动过程U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能Ø硬件设备初始化Ø加载U-Boot第二阶段代码到RAM空间Ø设臵好栈Ø跳转到第二阶段代码入口(2)第二阶段的功能Ø初始化本阶段使用的硬件设备Ø检测系统内存映射Ø将内核从Flash读取到RAM中Ø为内核设臵启动参数Ø调用内核1.1.1U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/start.S和board/samsung/mini2440/lowlevel_init.S。

U-Boot启动第一阶段流程如下:图 2.1 U-Boot启动第一阶段流程根据cpu/arm920t/u-boot.lds中指定的连接方式:ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/start.o (.text)board/samsung/mini2440/lowlevel_init.o (.text)board/samsung/mini2440/nand_read.o (.text)*(.text)}……}第一个链接的是cpu/arm920t/start.o,因此u-boot.bin的入口代码在cpu/arm920t/start.o中,其源代码在cpu/arm920t/start.S中。

下面我们来分析cpu/arm920t/start.S的执行。

1.硬件设备初始化(1)设臵异常向量cpu/arm920t/start.S开头有如下的代码:.globl _start_start: b start_code /* 复位*/ldr pc, _undefined_instruction /* 未定义指令向量 */ldr pc, _software_interrupt /* 软件中断向量*/ldr pc, _prefetch_abort /* 预取指令异常向量 */ldr pc, _data_abort /* 数据操作异常向量 */ldr pc, _not_used /* 未使用 */ldr pc, _irq /* irq中断向量 */ldr pc, _fiq /* fiq中断向量 *//* 中断向量表入口地址 */_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq.balignl 16,0xdeadbeef以上代码设臵了ARM异常向量表,各个异常向量介绍如下:表 2.1 ARM异常向量表在cpu/arm920t/start.S中还有这些异常对应的异常处理程序。

U-boot烧内核到NandFlash步骤

U-boot烧内核到NandFlash步骤

U-boot烧内核到NandFlash步骤
1.把uImage内核镜象放到TFT服务器文件夹内。

2.配置Window下的IP地址:192.168.0.30 这个其实也是TFTP服务器的地址。

3.修改u-boot配置文件u-boot-1.3.4/include/configs/xyd2440.h
修改为:
4.保存文件,重新编译u-boot.把生成的u-boot文件烧录到Norflash中。

5.重新启动开发板,
6.内核的启动过程:(在2 的条件下)
#tftp 30000000 uImage ; 通过tftp 命令将uImage 文件下载到内存30000000 位置。

(#bootm 32000000 ; 跳到内存32000000 处运行)。

#nand erase
#nand write.jffs2 32000000 100000322b90 ; 将内存32000000 处的数据写到NAND 的0 地址处大小为322b90 322b90这个值是内核大小,是执行tftp 32000000 uImage ;命令后下载内核产生的值,根据实际情况修改。

100000这个值是内核在NandFlash起始地址,要和。

中#defind CONFIG_BOOTCOMMAND “nboot 0x32000000 0 100000; bootm 0x32000000”中的100000相同。

7.重启开发板,如果有以下信息表示已经成功烧录。

(启动linux的信息)。

uboot启动参数设置

uboot启动参数设置
tftp 30800000 uImage 获取uImage,存放到内存的30800000
nand erase 40000 1c0000 nand erase offset size
nand write 30800000 40000 1c0000 存放内存30800000位置上的uImge,烧写到nandflash的40000位置上
=========================================================================================
例如如下:
FS2410# setenv serverip 192.168.7.x (其中X是虚拟机中IP的最后的数字[用ifconfig可以获取])
farsight_N中的N用座位号来表示,比如座位4即为farsight_4 //设置uboot传给内核的参数
saveenv
自定义参数版本:
4.设置UBOOT参数
确保一下FS2410的核心班上的JP1跳线帽短接了,给板子上电,
查看板子启动信息,如果板子启动信息中,有U-Boot 1.3.1(Oct 25 2008 - 15:45:21)或者更新的版本,则直接设置下面的参数,否则根据文档烧录 u-boot131-for-farsight-shenzhen-advanced-drivers.bin(请参考文档"farsight-实验前的准备步骤-v2.3.doc")
setenv bootargs console=ttySAC0,115200 init=/linuxrc root=/dev/nfs nfsroot=192.168.7.113:/opt/filesystem ip=192.168.7.173:192.168.7.113:192.168.7.1:255.255.255.0:farsight_13:eth0:off //或者console=ttySAC0,115200 root=1f02 rootfstype=jffs2 rw init=/linuxrc mem=64M

移植笔记从Norflash启动的uboot

移植笔记从Norflash启动的uboot

移植笔记从Norflash启动的uboot uboot移植记录之一uboot整个移植过程我们可以分为三个阶段:一,移植可以从Nor flash启动的uboot这个阶段是移植一个最简单的uboot,可以烧在Nor flash内运行.二,移植支持Nand flash驱动的uboot加入Nand flash驱动的支持,可以在uboot命令行下操作Nand flash.但还未能从Nand flash启动,只能在Nor flash内运行.三,移植可以从Nor flash启动的uboot可以烧录在Nand flash,并设置从Nand flash启动运行uboot.分三个阶段进行移植,可以对整个uboot的移植过程及原理更加清晰明了,同时降低了发现问题时解决问题的困难度和解决范围.首先介绍移植可以从Nor flash启动的uboot. 这个阶段相对简单一点,是移植一个最简单的uboot,可以烧在Nor flash内运行.不需要修改太多的东西。

步骤如下: 测试一下默认的smdk2410_config配置能否在你的板子上正常运行 1.编译uboot1.1.4#make smdk2410_config#make ARCH=arm注:编译针对arm的平台时,uboot默认使用arm-linux-gcc编译,若交叉编译器名字不一样,需要自行在Makefile里修改。

会出现两个错误.错误信息一:cc1: Invalid option `abi=apcs-gnu'make[1]: *** [hello_world.o] Error 1make[1]: Leaving directory `/root/u-boot-1.1.4/examples'make: *** [examples] Error 2解决办法:出错的文件是/cpu/arm920t/下的config.mk:将PLATform_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) 改成: PLATform_CPPFLAGS +=$(call cc-option,-mapcs-32,$(callcc-option,-mabi=apcs-gnu,))错误信息二:make[1]: *** No rule to make target `hello_world.srec', needed by`all'. Stop. make[1]: Leaving directory `/work/src/u-boot-1.1.4/examples' 解决方法:打开 examples/Makefile把example文件夹下的Makefile中的第126行%.srec: % 改成 %.srec: %.o第129行的%.bin: % 改成 %.bin: %.o2.若编译成功,则会在uboot源码下产生u-boot.bin文件。

Nandflashuboot命令详解

Nandflashuboot命令详解

Nandflashuboot命令详解(转⾃)nand info & nand device显⽰flash的信息:DM365 :>nand infoDevice 0: NAND 32MiB 3,3V 8-bit, sector size 16 KiBDM365 :>nand deviceDevice 0: NAND 32MiB 3,3V 8-bitnand read(.oob) addr off size不管是读取data, 使⽤nand read,还是读取oob,使⽤命令nand read.oob,后⾯跟的地址addr,都是ram的地址,off指的是nand flash的地址, size:指要读取nand flash的数据⼤⼩,但是如果是读取oob, size不能超过⼀个page 的oob size,如果page size为512个字节, oob size就是16个字节.DM365 :>nand read 86000000 58000 100NAND read: device 0 offset 0x58000, size 0x100256 bytes read: OKDM365 :>md 86000000 4086000000: ea000012 e59ff014 e59ff014 e59ff014 ................…………860000f0: e1a0000d eb00022e 00000000 00000000 ................DM365 :>nand read.oob 86000000 58000 10NAND read: device 0 offset 0x58000, size 0x1016 bytes read: OKDM365 :>md 86000000 4086000000: ffffffff 2707ffff 33e316ad 44b2e1a1 .......'...3...D如果⼀次想读取完整的⼀个page 的值,包含oob,使⽤下⾯将的命令, nand dump.nand dump [addr] [size]调⽤过程: nand dump addr size (common/cmd_nand.c)==> nand_dump() ==> nand_read_raw();nand dump 不管你的size有多⼤,⾄少会dump出⼀个page的⼤⼩:SMDK2440 # nand dump 0 100Page 00000000 dump:12 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e514 f0 9f e5 14 f0 9f e5 14 f0 9f e5 14 f0 9f e500 02 f8 33 60 02 f8 33 c0 02 f8 33 20 03 f8 3380 03 f8 33 e0 03 f8 33 40 04 f8 33 ef be ad de00 00 f8 33 00 00 f8 33 58 19 fa 33 34 6d fa 3300 00 0f e1 1f 00 c0 e3 d3 00 80 e3 00 f0 29 e1…………04 30 8c e5 fc 4d 00 eb 00 01 9f e5 f0 3c 00 eb02 0d 00 eb 41 42 00 eb f4 00 9f e5 00 40 98 e504 02 00 eb 0d 10 a0 e1 04 00 84 e5 40 20 a0 e3OOB:ff ff ff ff ff ff ff ffff ff ff ff ff ff ff ffff ff ff ff ff ff ff ffff ff ff ff ff ff ff ffff ff ff ff ff ff ff ff69 a6 ab 3c 33 cf 66 5aa7 cf f0 33 a6 96 97 3f0c c3 30 30 c3 cc 33 f3nand write - addr off size这个命令和nand read⼀样,只是⽅向是反的,是把ram的值写到 nand flash中,但是这个写只能将1改为0,不能将0写成1. 这个command 会⾃动skipping bad blocks。

UBOOT移植(NANDFLASH的支持)——初步移植(二)

UBOOT移植(NANDFLASH的支持)——初步移植(二)

UBOOT移植(NANDFLASH的支持)——初步移植(二)NAND FLASH初始化入口函数(arch/arm/lib/board.c)这里需要定义CONFIG_CMD_NAND这个宏才行,在配置头文件中已经包含进去了,没问题。

nand_init()函数(drivers/mtd/nand/nand.c)这个函数里面使用两个宏参数进行控制CONFIG_SYS_MAX_NAND_DEVICE和CONFIG_SYS_NAND_SELECT_DEVICE,前者已经在配置头文件中进行了描述,后者由于对应的是有多个NAND设备存在的情况,这里就忽略了。

nand_init_chip()函数(drivers/mtd/nand/nand.c)这个函数需要配置三个宏参数,除了CONFIG_RELOC_FIXUP_WORKS其余都定义了。

没有定义的那个宏给出的描述是“Relocation to SDRAM works on all XXX boards”意思是重置到SDRAM工作在所有XXX板子上。

UBOOT中大部分ARM板子上都没有定义这个宏,SMDK2410也没有定义这个宏,这里也就选择不定义。

这个函数函数还需要三个参数,这三个参数在开头进行了定义。

nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] =CONFIG_SYS_NAND_BASE_LIST;宏CONFIG_SYS_NAND_BASE_LIST采用默认的配置。

#ifndef CONFIG_SYS_NAND_BASE_LIST#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }#endif上述所有参数在配置头文件中都有定义。

uboot中NANDflash的MTD驱动移植

uboot中NANDflash的MTD驱动移植

u-boot中NAND flash的MTD驱动移植u-boot中移植了linux中的MTD驱动源码来支持NAND flash擦除、烧写及读的驱动。

MTD(memory technology device内存技术设备)是用于访问flash设备的Linux的子系统。

MTD的主要目的是为了使新的存储设备的驱动更加简单并有通用接口函数可用。

MTD驱动可支持CFI接口的norflash驱动、NAND flash驱动。

我们知道NAND flash 的访问接口并没有像norflash一样提供了一个标准的CFI访问接口,但是NAND flash生产厂家之间在各品牌、各型号NAND falsh芯片的访问接口方面做了一些约定俗成规定,如命令字、地址序列、命令序列、坏块标记位置、oob区格式等。

值得注意的是:在工艺制程方面分NAND flash有两种类型:MLC和SLC。

MLC和SLC属于两种不同类型的NAND FLASH存储器。

SLC全称是Single-Level Cell,即单层单元闪存,而MLC全称则是Multi-Level Cell,即为多层单元闪存。

它们之间的区别,在于SLC每一个单元,只能存储一位数据,MLC每一个单元可以存储两位数据,MLC的数据密度要比SLC 大一倍。

在页面容量方面分NAND也有两种类型:大页面NAND flash(如:HY27UF082G2B)和小页面NAND flash(如:K9F1G08U0A)。

这两种类型在页面容量,命令序列、地址序列、页内访问、坏块标识方面都有很大的不同,并遵循不同的约定所以在移植驱动时要特别注意。

下面以大页面的NAND flash:现代HY27UF082G2B为例介绍一下NAND flash一些基本情况,再来介绍MTD驱动的基本结构及流程分析,最后介绍u-boot中MTD驱动移植的详细步骤:3.4.1)NAND flash一些基本情况fl2400开发板上的nandflash芯片型号为:现代HY27UF082G2B,下面先介绍一下nandflash,及norflash与nandflash之间的区别:NOR和NAND是现在市场上两种主要的非易失闪存技术。

Nand Flash启动模式下的Uboot移植

Nand Flash启动模式下的Uboot移植

好 的移 植 性 和 可 读 性 , 在 阶 段 2中 通 常 用 C代 码 来 实 现 。 关于 C P U 的初始化文 件一般放 在第一 阶段 , 其 对 应 的 文 件 目录 为 c p u / a r m9 2 0 t / s t a r t . S , 主 要 实 现 一 些 寄 存 器 的
映射图 、 将 系统 的 软 硬环 境 带 到 一 个 合适 的状 态 , 为 最 终 的
内核调 试 做 好 准 备 。Ub o o t 是在 p p c b o o t 以 及 AR Mb o o t 的 基础上 发展 而来 的较 为 通用 的 B o o t I o a d e r , 不 仅 仅 支 持
工程与应 用, 2 O 1 1 ( 3 4 ) . ( 责任编辑 : 孙 娟)
[ 6 ] 邓金 华 , 蒋浩 , 邝达 , 等. 用 擂 台赛 排 挤 算 法 构 造 多 目标 最 优 解 集 的
M oGA Ba s e d On g - Do mi n a t e d M e t h o d f o r kna p s a c k pr o b l e ms
s 3 c 2 4 4 0 A 平 台上 如 何 实现 Na n d F l a s h启 动 模 式 下 的 Ub o o t 移 植 进 行 了介 绍 。 具 体 操 作 和 编 译 在 f e d o r a 9操 作 系 统
和 a r m— l i n u x - g c c 4 . 3 . 2交 叉 编 译 下 完 成 。
硬 件 设 备 的初 始 化 函数 来 完 成 本 阶 段 要 使 用 到 的 硬 件 设
中 的 No r f l a s h。但 No r f l a s h存 储 器 的价 格 比较 昂 贵且 存

U-Boot从NANDFlash启动的实现

U-Boot从NANDFlash启动的实现
U B t 动 流 程 的 两 个 阶段 及 实现 从 N N ah启 动 的 原 理 和 思路 。并 根 据 N N ah的 物 理 结 构 和 存 储 特 .o 启 A DF s l A DF s l 点 , 加 UB o 对 N N ah的操 作 支 持 , 而 完成 把 存 储 在 N N ah上 的 U B t 码 复 制 到 S R M 中执 增 .ot A D Fs l 从 A D Fs l -o 代 D A 行。 实现 从 N N Is A D Fah的 启 动 。 修 改 过 后 的 U B t 以 直接 从 N N l h启 动 , 应 用 带 来便 利 。 .o 可 A D Fa s 给
王 磊
( 原 理 工 大 学 信 息 工 程 学 院 ,山 西 太 原 0 0 2 ) 太 3 04
摘 要 : .ot 能从 N N l h启 动 给 应 用带 来些 不便 。 UBo 不 A D Fa s 因此 修 改 UB o 使 其 支持 从 N N s 动 。 分 析 了 .ot A D nah启
Re l a ino Bo t o t gt r u h NAND ls ai t f z o U. o o i o g b n h Fa h
W ANG I 七i
( eate tf n r ai nier g T i a nvre T cnl y T i a 3 04 C / ) D p r n o I om t nE gnei , a unU i s o e ho g , ay n0 02 , hn m f o n y ei f o u a
关 键 词 :U. o t AND ls B o ;N Fah;B f a e ;S C 4 O o l d r 3 2 4 ;移植 o

1-通过usb将u-boot.bin烧写到nand-flash

1-通过usb将u-boot.bin烧写到nand-flash

一、PC机到TPAD的连接方式PC机(开发主机)下载到TPAD(目标机,开发板)USB口RS232串口网口 JTAG口二、设置TPAD的启动方式:启动方式的设定是通过拨码开关来进行设置的。

设置从USB启动。

1.4->ON三、连接开发板:B线,大口接PC,小口接TPAD上的OTG口2.串口线,一端接PC,一端接TPAD的COM1口3.电源线,一端接插线板,一端接电源孔(5V/3A)四、在PC端的Windows下运行DNW软件1. 通过USB口从主机端下载启动程序到TPAD的内存中运行2. 要求通信双方都要运行软件主机端———— USB ————TPADDNWs5pv210处理器 IROM(只读存储器)说明:s5pv210处理器里面有一段三星固化好的代码(出厂自带),代码在处理器里面IROM只读存储器中,板子一上电,执行IROM中代码,就会判断拨码开关,通过判断拨码开关的设置方式,就知道从哪里去获得启动程序,由于拨码开关设置从USB启动,因此,IROM代码将从USB接口获取启动程序。

3.串口的配置configuration->oprtion配置串口的波特率:115200配置使用的串口为:COM14.点击serial port ->connect->标题栏出现com1,115200bps,说明串口已生效。

连接前的状态:连接后的状态:5. 5. USB驱动的安装,使用DNW软件通过USB向TPAD发送程序x210_usb.bin1)配置下载地址:0xd0020010configuration->oprtion送:x210_usb.binTPAD中IROM负责接收:接收x210_usb.bin,运行x210_usb.bin,但并DNW中没有任何显示信息。

6. 使用DNW软件通过USB向TPAD发送程序u-boot.bin1)配置下载地址:0x23e00000configuration->oprtion2)PC机通过DNW软件向TPAD发送:u-boot.binTPAD中IROM负责接收:接收u-boot.bin,运行u-boot.bin,显示信息通过串口发送给DNW软件进行显示。

最新Uboot移植步骤 6:NandFlash读操作

最新Uboot移植步骤 6:NandFlash读操作

最新Uboot移植步骤6:NandFlash读操作前面在调试时把NAND相关的宏CONFIG_CMD_NAND注释掉了一些,现在去重新打开:编译,看看会出什么错误:先看第一个error:72行显示一个不完整的类型看这个nand的定义:发现nand是2410_nand的结构体,但我们未定义CONFIG_S3C2410这个宏,我们现在要使用2440,正好下面有,我们直接使用2440的结构体好了:这个文件都是给2410用的,我们直接拷贝一份,改名为2440,SI文件添加一下:修改宏定义:修改Makefile:先看看nand是如何操作的,着nand相关函数:看nand_init函数:可见这里就可以识别nand并输出nand的大小了,先看运行哪个函数:可见CONFIG_SYS_NAND_SELF_INIT宏未定义,所以运行nand_init_chip函数:看单板初始化函数:把2410修改为2440:发现s3c2440_get_base_nand函数未定义,我们先搜下2410的定义,改为2440的定义:修改发现S3C2440_NAND_BASE未定义,那我们找到2410定义的地方自己仿照定义2440下:修改初始化时序:看这个函数,我们把2410都改成2440:修改这里:看到nfcont,我们还要设置下这个:现在board_nand_init函数修改完了,开始修改nand_scan函数:观察之后,发现要修改如下(具体为何这样修改,参考NAND驱动开发视频,现在我还没看,无法详述):编译,下载:有错误:搜索nand_wait_ready,发现再我们自己的init.c函数里也定义了,把我们的改一下:再编译下载:发现NAND已经可以识别!把uboot从nor拷贝到nand:验证:数据都相同,现在重启开发板从nand启动:这时从NAND启动,Nor无法识别,所以显示0KB!成功!。

基于ARM平台和NAND flash启动技术的u-boot移植过程浅析

基于ARM平台和NAND flash启动技术的u-boot移植过程浅析

0 引 言
b o 德 国 D N 小 组 的 开 发 用 于 多 种 嵌 入 式 C U 的 0t是 EX P B o 0d r ot ae 程序 , ~ ot l u b o 不仅仅支持嵌入 式 L u 系统 的引 导 ,当前 , ix n 它还 支持 N tS , Wok, NX R E , R O , yx S嵌 入式操 eB D Vx rs Q , T MS A T S Ln O 作系统 。u b t 了支持 P w r C系列 的处理器 外 。 —o 除 oe P 还能支持 M P 、 IS x 6 A M、 IS X cl等诸多常用系列的处理器。 8 、R NO 、Sa e 目前关 于 u bo 的移植解 决方 案 主要面 向 的是 微处 理器 中 的 — ot N R f s . N N ah O ah 而 A D f s 闪存容量 大 , l l 价格便宜 。 如果能在 微处理器 上的 N N ah A Dfs 中实现 ubo 的启动 .则不仅有效 降低嵌入式应用 l —ot 系统 的成本 . 也给实 际应用带来极大的方便。
Po t g p o e so - o t ri r c s fu b o . n
【 yw r sE b d e s m ; R ;ot ae;A D f s; bo Ke o d 】 m e dds t sA M B o od r N ah — ot ye L N l u
【 bt c]oi f ot ae iavr iprn pri t m eddssm dv om n p cs i ae aa zs otgo u bo A s at rn o Bo odrs e oat atn h e bde y e ee p et r es ppr nl e bon —ot r P tg L y m t e t l o . y i f

u-boot设计文档

u-boot设计文档

u-boot 设计文档1. 引言u-boot是bootloader成员中一种应用普遍,功能强大,极具代表意义的引导程序。

在嵌入式开发中起着举足轻重的作用。

U-boot是一段运行于内核之前的代码,为内核的启动初始化硬件环境并提供必需的参数,引导内核运行。

总之,u-boot的基本工作就是能够成功得引导内核运行。

一般情况下u-boot映像,内核和根文件系统映像都存储在Flash上。

也就是说开发板是从Nor Flash启动的。

但考虑到Nor flash容量小,价格高的因素,而Nand Flash 有更高的性价比,增加了从Nand Flash启动的功能。

2. 目标实现初始化开发板硬件环境,为启动内核提供硬件平台参数,引导内核启动的基本功能。

实现Nor/Nand Flash两种启动模式。

3. u-boot启动流程分析为了能够更好的移植u-boot到新的开发板上,有必要掌握u-boot的启动流程。

借助u-boot 启动流程图,简单介绍u-boot的启动过程。

考虑到执行效率和代码的扩展性和灵活性,一般情况把u-boot启动过程分为两个阶段。

第一阶段代码由汇编实现,这是u-boot一开始就执行的操作,其目的是为第二阶段的执行以及随后的kernel 的执行准备好一些基本的硬件环境。

通常包括以下步骤:硬件设备初始化;为加载u-boot第二阶段准备RAM 空间;拷贝u-boot第二阶段代码到RAM空间中;设置好堆栈;跳转到第二阶段的C 入口点。

第二阶段用c语言编写,用以实现复杂的功能。

通常包括以下步骤:初始化本阶段要使用到的硬件设备;检测系统内存映射(memory map);将kernel 映像和根文件系统映像从flash上读到RAM 空间中;为内核设置启动参数;调用内核。

4. u-boot移植U-Boot能够支持多种体系结构的处理器,支持的开发板也越来越多。

因为系统引导程序是完全依赖硬件平台的,所以在新电路板上需要移植U-Boot程序。

NAND Flash启动的问题(u-boot)

NAND Flash启动的问题(u-boot)

NAND Flash启动的问题(u-boot)用的是S3C2410.见附件start.s 其中关于nand flash启动的那一段一直百思不得其解,按说从NAND FLASH启动时,应该是前4KB映射到NGCS0,其中的代码将NAND中存放的程序拷贝到RAM中,但该文件提供的程序好象是先从NAND拷贝 128K的代码到ResetEntry开始的地方,即地址为0的地方,然后再从ResetEntry处拷到RAM中,但此时NGCS0好象只有4KB的 RAM区,怎么能存储128K的代码,一直没想通.望高手指点,谢谢!搞明白了,是两条指令的差别LDR r0,=_entry和ADR r0,_entry前者是在编译的时候按照load address生成的绝对地址,后者反汇编后是相对当前PC寻址,例如在ADS 中设置RO地址为0X30000000,那么前者传给r0的值是 0x30000000,而后者传给r0的值要视当前PC而定,一般从NGCS0中启动时,传给r0的值就是0。

amsung S3C2410支持Nor Flash和Nand Flash启动,在SBC-2410X上可以通过BOOTSEL跳线设置启动方式:|------||。

| boot from nand flash|------|--。

boot from nor flash注:(1) BOOTSEL跳线在"串口"和"usb slave接口"之间(2) 两个引脚用"跳线卡"连接,则表示从nand flash启动。

拔下"跳线卡"表示从nor flash启动。

椐了解 NOR FLASH 是容量小,速度快,稳定性好,适合做程序存储器。

NAND FLASH 总容量大,适合做数据存储器是不能从NAND FLASH启动的,NAND FLASH是的读写时序是不能直接有ARM硬件产生的,要读写NAND FLASH是要通过程序来实现的,很明显能看出来的就是NAND FLASH只有8个数据、地址复用的数据地址接口2410/2440可以直接从NAND FLASH启动的,因为它把NAND前面的4K映射到了RAM的空间首先应该先了解Flash ROM的种类NOR FLASH地址线和数据线分开,来了地址和控制信号,数据就出来。

ubootmmc命令详解Nandflashuboot命令详解

ubootmmc命令详解Nandflashuboot命令详解

ubootmmc命令详解Nandflashuboot命令详解
md指令
uboot下输⼊指令md,会提⽰md的⽤法,memory display,即内存显⽰。

b:8位
w:16位
l:32位(默认值)
⽰例:
上述0x10000000是要显⽰内存的那个地址,后⾯的数字是输出的个数,注意是16进制的。

直接输⼊md来显⽰,默认是以32位为单位输出。

mw指令
uboot下输⼊指令mw,会提⽰md的⽤法,memory write,即向内存中写⼊数据。

b\w\l的意思同上,address是要写⼊内存的地址,value是要写⼊的值,count是从address开始要写⼊多少个数,这些都是16进制数。

⽰例:
⽰例
在0x10000000地址内存的起始位置写⼊0x12345678,打印出内存的输出。

发现低位0x78是写在低地址0x10000000,⾼位0x12是写在⾼地址0x10000003上,也就是常说的⼩端模式(little endian),简单记忆:低低模式,即低位在低地址。

uboot学习之uboot启动流程简述

uboot学习之uboot启动流程简述

uboot学习之uboot启动流程简述⼀、uboot启动分为了三个阶段BL0、BL1、BL2;BL0表⽰上电后运⾏ROM中固化的⼀段程序,其中ROM中的程序是⼚家写进去的,所以具体功能可能根据⼚家芯⽚⽽有所不同。

功能如下:1. 初始化系统时钟、特殊设备的控制器、启动设备、看门狗、堆栈、SRAM等硬件;2. 验证B1镜像,并且加载BL1镜像到SRAM中,然后跳转到BL1镜像的地址上。

BL0需要将BL1加载到对应的RAM上,这就涉及到它的启动模式,详细如下:1.OneNand Boot模式要了解OneNAND先得了解NOR Flash和NAND Flash。

与NOR Flash相⽐,NAND Flash的读数据速度稍慢,但是擦写速度快得多,并且在容量、使⽤寿命、成本上也占有较⼤优势。

NOR Flash的编程简单,⽽NAND Flash的编程较为复杂(因为它的flash管理需要特殊的接⼝)。

NAND Flash⼀般⽤于存储数据,⽽NOR Flash⼀般⽤于存储启动代码。

NOR Flash带有SRAM接⼝,有⾜够的地址引脚来寻址,可以很容易地存取其内容的每⼀字节(有限的地址引脚是限制其容量的因素之⼀)。

NAND Flash使⽤复杂的I/O⼝来串⾏地存取数据,各个产品或⼚商的⽅法可能各不相同。

为了弥补NAND Flash的不⾜,三星公司在NAND Flash芯⽚内集成了⼀个RAM接⼝,命名为OneNAND Flash,这类Flash拥有与NOR Flash相同的简单接⼝,⽽且不受地址引脚的限制,即容量与地址引脚⽆关。

其实OneNAND 其实就是采⽤了NOR的接⼝,NAND的架构,是两者的性能得到了综合。

这就有了X-LOADER的产⽣,以前我们接触到的都是BOOTLOADER,其实这个X-LOADER也起到初始化的作⽤,因为我们的BOOTLOADER是放在NAND的架构下的,⽽CPU却是从NOR的接⼝下读取BOOTLOADER到SDRAM中的,所以现在要做⼀个⼯作就是要如何将BOOTLOADER在OneNAND的架构下从NAND复制到SDRAM中,这就是X-LOADER的功能了,它不仅初始化OneNAND,并且把U-BOOT从NAND的架构下复制到BufferRam中,再复制到SDRAM中。

u_boot 移植(一)之uboot配置编译

u_boot 移植(一)之uboot配置编译

u_boot 移植(一)之uboot配置编译一 、开发环境PC OS : Ubuntu 14.04SOC : 基于ARM Cortex-a8 核的S5PC100开发板 : FSC100u_boot : u-boot-2010.03编译器 : arm-cortex_a8-linux-gnueabi-gcc version 4.4.6二、目标1.Uboot 能从FSC100的 Nand Flash 正常启动2.Uboot 支持DM9000 网卡3.Uboot 支持Nand Flash 读、写、擦除4.Uboot 支持Linux 内核引动好了,接下来就进行移植uboot到FSC100开发板吧 。

三、建立自己的平台1、 下载源码我们可以在下面这个网站上下载最新的和以前任一版本的 ubootftp://ftp.denx.de/pub/u-boot/2、 解压 uboot 源码并进入目录tar zxvf u-boot-2010.03.tar.gzcd u-boot-2010.03u-boot-2010.3 源码中已经支持了SMDKC100了(SMDKC100是三星公司基于SOC : S5PC100设计的一块开发板)。

我们的FSC100使用的SOC也是S5PC100,所以我们只需要稍加修改Uboot支持的SMDC100代码,就可以编译出支持我们的FSC100开发板的uboot了。

1.修改 u-boot 顶层目录下的 Makefile,指定交叉工具链在ifeq ($(HOSTARCH, $(ARCH))CROSS_COMPILE ?=endif下添加:ifeq (arm, $(ARCH))CROSS_COMPILE ?= arm-cortex_a8-linux-gnueabiendif2.在 u-boot 顶层目录下的 Makefile 中添加 fsc100 配置信息在smdkc100_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 smdkc100 samsung s5pc1xx下添加:fsc100_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 fsc100 samsung s5pc1xx3. 添加 fsc100 平台信息(1)进入board/samsung目录(2)拷贝smdkc100 为 fsc100(3)进入fsc100目录下修改smdkc100.c 为fsc100.c修改Makefile中的smkc100.o 为fsc100.o(4)进入include/configs目录,拷贝smdkc100.h为fsc100.hinclude/configs目录下的.h文件为对应开发板的配置文件。

U-Boot启动过程--详细版的完全分析

U-Boot启动过程--详细版的完全分析

(一)U—Boot启动过程-—详细版的完全分析我们知道,bootloader是系统上电后最初加载运行的代码.它提供了处理器上电复位后最开始需要执行的初始化代码。

在PC机上引导程序一般由BIOS开始执行,然后读取硬盘中位于MBR(Main Boot Record,主引导记录)中的Bootloader(例如LILO或GRUB),并进一步引导操作系统的启动。

然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动就完全由bootloader来完成.它主要的功能是加载与引导内核映像一个嵌入式的存储设备通过通常包括四个分区:第一分区:存放的当然是u-boot第二个分区:存放着u-boot要传给系统内核的参数第三个分区:是系统内核(kernel)第四个分区:则是根文件系统如下图所示:u—boot是一种普遍用于嵌入式系统中的Bootloader。

Bootloader介绍Bootloader是进行嵌入式开发必然会接触的一个概念,它是嵌入式学院<嵌入式工程师职业培训班〉二期课程中嵌入式linux系统开发方面的重要内容。

本篇文章主要讲解Bootloader的基本概念以及内部原理,这部分内容的掌握将对嵌入式linux系统开发的学习非常有帮助!Bootloader的定义:Bootloader是在操作系统运行之前执行的一小段程序,通过这一小段程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备.意思就是说如果我们要想让一个操作系统在我们的板子上运转起来,我们就必须首先对我们的板子进行一些基本配置和初始化,然后才可以将操作系统引导进来运行。

具体在Bootloader中完成了哪些操作我们会在后面分析到,这里我们先来回忆一下PC的体系结构:PC机中的引导加载程序是由BIOS和位于硬盘MBR 中的OS Boot Loader(比如LILO和GRUB等)一起组成的,BIOS在完成硬件检测和资源分配后,将硬盘MBR 中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

U -Boot 从NAND Flash 启动的实现王磊(太原理工大学信息工程学院,山西太原030024)摘要:U -Boot 不能从NAND Flash 启动给应用带来些不便,因此修改U -Boot 使其支持从NAND Flash 启动。

分析了U -Boot 启动流程的两个阶段及实现从NAND Flash 启动的原理和思路,并根据NAND Flash 的物理结构和存储特点,增加U -Boot 对NAND Flash 的操作支持,从而完成把存储在NAND Flash 上的U -Boot 代码复制到SDRAM 中执行,实现从NAND Flash 的启动。

修改过后的U -Boot 可以直接从NAND Flash 启动,给应用带来便利。

关键词:U -Boot ;NAND Flash ;Bootloader ;S3C2440;移植中图分类号:TP316文献标识码:A文章编号:1674-6236(2010)05-0098-03Realization of U -Boot booting through NAND FlashWANG Lei(Department of Information Engineering ,Taiyuan University of Technology ,Taiyuan 030024,China )Abstract:It is not convenient that U -Boot can ’t boot through NAND Flash.In this paper ,the codes of U -Boot is modified to support that.This paper analyzes two steps of U -Boot and the method of supporting that the U -Boot boots from NAND Flash.Based on the memory characteristics and the physical structure of NAND Flash ,this paper adds the codes of NAND Flash in order to carry the codes to SDRAM that stored in the NAND Flash ,thus realizes U -Boot boots from NAND Flash.The modified U -Boot runs through NAND Flash straightly ,it is a great convenience to the application of U -Boot.Key words:U -Boot ;NAND Flash ;Bootloader ;S3C2440;porting电子设计工程Electronic Design Engineering第18卷Vol.18第5期No.52010年5月May.2010收稿日期:2009-10-11稿件编号:200910032作者简介:王磊(1985—),男,山西河津人,硕士研究生。

研究方向:嵌入式系统、DCS 、自动控制。

Bootloader 引导装载程序是系统上电后运行的第一段程序,其作用是完成基本的硬件初始化工作,所以引导装载程序跟硬件有着紧密的联系。

因此必须根据开发板的硬件配置对引导装载程序进行修改才可以使其运行起来。

随着嵌入式系统的复杂化,大容量数据存储的NAND Flash 的应用会越来越广泛,同时U -Boot 是功能最丰富的Bootloader ,但遗憾的是U -Boot 不支持从NAND Flash 启动。

所以如果能实现U -Boot 从NAND Flash 启动的话将会给应用带来很大的方便。

本文讨论修改U -Boot 使其支持从NAND Flash 启动,采用基于S3C2440的开发板。

1U -Boot 简介及流程分析U -Boot ,全称universal boot loader ,是遵循GPL 条款的开放源代码项目。

可以引导多种操作系统,支持多种架构的CPU 。

它支持如下操作系统:Linux 、NetBSD 、VxWorks 等,支持如下架构的CPU :PowerPC 、MIPS 、X86、ARM 、NIOS 、XScale 等,同时支持NFS 挂载,是一个功能丰富的BootLoader 。

它的整个程序框架清晰,易于移植,许多设计人员将自己的移植代码上传到网站(http :///projects/u-boot/)上,更新速度很快。

目前的版本是1.1.6,本论文正是采用此版本进行说明,U -Boot 的目录结构参见U -Boot 源代码。

要进行U -Boot 的修改移植必须了解U -Boot 的程序运行流程,这是必要的一步。

U -Boot 属于两阶段的BootLoader ,其启动流程如图1所示。

第一阶段的文件为cpu/arm920t/start.S 和board/smdk2410/lowlevel_init.S ,用ARM 汇编语言编写,前者是平台相关的,后者是开发板相关的[1]。

第一阶段主要是关于基本硬件的初始化,包括关闭MMU 、CACHE 、设置PLL 时钟比例、关闭看门狗;初始化SDRAM ,为复制第二阶段代码做准备,最后复制第二阶段代码到SDRAM 中,然后跳到图1U -Boot 启动流程-98-SDRAM中运行第二阶段。

第二阶段代码都是用C语言编写的,功能更加复杂,主要是进一步初始化硬件设备、检测内存映射、复制内核镜像和根文件系统到SDRAM以及设置启动参数从而启动内核。

2支持NAND启动的代码修改2.1添加NAND Flash的初始化函数U-Boot中关于NAND Flash的初始化流程如下:在上电后最先运行的汇编程序cpu\arm920t\start.S中调用start_arm-boot函数,而start_armboot该函数则调用了一系列的关于设备的初始化函数。

这一系列的函数中包含一个名为nand_init 的函数,nand_init就是完成NAND Flash的初始化工作。

在1.1.6版本的U-Boot的include\linux\mtd\nand.h中定义了nand_chip结构体,该结构体中定义了关于NAND Flash 操作的所有函数,包括读、写、ECC校验等,而这些函数在U-Boot中都有完整编写,只是有些个别函数需要根据自己的要求重新编写。

而实现NAND Flash初始化的nand_init函数主要任务就是完成这些需要重新编写的函数和用这些函数连同U-Boot中其他默认函数来初始化nand_chip结构体。

NAND_init中的board_nand_init函数在U-Boot中并未实现,显然需要重新编写的函数就在其内添加[2]。

先在cpu\arm920t\s3c24x0中添加nand.c文件,然后在该文件中实现所需要的初始化函数。

一般只需要重新编写nand_chip结构体中相对应的hwcontrol、dev_ready和se-lect_chip函数。

这些函数的构建可参照linux内核2.6版本里的drivers\mtd\nand\s3c2410.c文件来进行编写,如内核文件中的s3c2440_nand_hwcontrol,s3c2440_nand_devready,s3c2410_ nand_select_chip函数,然后将其赋值给nand_chip结构体中对应的函数[3-4]。

static int s3c2440_nand_devready(struct mtd_info*mtd){S3C2440_NAND*const s3c2440nand=S3C2440_Get-Base_NAND();return(s3c2440nand->NFSTAT&S3C2440_NFSTAT_ READY);}void board_nand_init(struct nand_chip*chip){chip->dev_ready=s3c2440_nand_devready;...}接着在/include/configs/SMDK2410.h中的CONFIG_COM-MANDS内添加CFG_CMD_NAND同时在最后添加#define CFG_NAND_BASE0#define CFG_MAX_NAND_DEVICE1#define NAND_MAX_CHIPS1初始化函数工作基本完成。

最后修改Makefile,把nand.c 文件添加进工程。

2.2实现NAND启动由于NAND的自身特点,对NAND Flash的操作不能像对NOR Flash那样方便地直接对地址进行操作,而是通过读写NAND Flash控制器的寄存器来完成。

三星公司的S3C2440自带NAND Flash控制器,寄存器的地址是从nGCS4的地址开始。

S3C2440处理器有NOR和NAND两种启动模式,当选择从NAND模式启动时,S3C2440会把NAND Flash的前4K数据搬运到内部称为Steppingstone的硬件中,同时把Steppingstone映射到地址0X00处,从而启动,启动完成后处理器会把Steppingstone释放掉以作为他用。

U-Boot的一般大小都上100K,远大于4K,所以实现从NAND启动的原理就是让前4K代码完成基本初始化,重要的是把NAND Flash中的U-Boot代码复制到SDRAM中,从而跳到SDRAM中去执行[5]。

分析可知,S3C2440的该特点为U-Boot从NAND Flash启动提供了可能。

本文讨论的实现思路就是依据此原理。

源代码中有/board/smdk2410/u-boot/lds,该文件是U-Boot代码的链接脚本,有如下代码:SECTIONS{.=0x00000000;.=ALIGN(4);.text:{cpu/arm920t/start.o(.text)*(.text)}可以看到Text段也就是程序代码段,被编译链接到0X00地址处,同时start.S编译后的目标文件start.o被放到text段的第一个文件处,所以start.S就是程序上电运行的第一段代码,而/cpu/arm920t/start.S这个汇编文件正是U-Boot 的程序代码入口。

因此代码修改和添加主要在start.S中完成,以此来保证NAND启动代码可以在最终程序编译链接所生成的文件的前4K内。

NAND Flash读写操作比较复杂,汇编实现较为麻烦,没有C语言简单容易,因此用C语言实现对NAND的操作复制工作,最后在start.s中调用编写的C程序即可。

相关文档
最新文档