<三> u-boot 的移植

来源:互联网 发布:合工大网络视频课 编辑:程序博客网 时间:2024/05/17 01:26
说明:后面实验中的命令行提示符是($)则为主机命令(主机上执行), (#)则为开发板命令
(开发板上执行)


一、 建立自己的平台


1、 下载源码

我们可以在下面这个网站上下载最新的和以前任一版本的 uboot
ftp://ftp.denx.de/pub/u-boot/


2、 解压 uboot 源码并进入目录

$ tar xvf u-boot-2010.03.tar.gz
$ cd u-boot-2010.03


3、 添加 lz210 平台信息

我们关心的板级相关文件或目录
u-boot-2010.03/Makefile
u-boot- 2010.03/include/configs/smdkc100.h
u-boot- 2010.03 /cpu/arm_cortexa8/start.S
u-boot- 2010.03 /board/samsung/smdkc100
u-boot- 2010.03/lib_arm


4、 smdkc100 是使用 s5pc100 芯片的参考板,我们在其基础之上移植 lz210$ cd board/samsung/

$ cp -a smdkc100 lz210
$ cd lz210
$ mv smdkc100.c lz210.c
$ vim Makefile
修改
COBJS-y := smdkc100.o

COBJS-y := lz210.o
$ cd include/configs
$ cp smdkc100.h lz210.h
修改 u-boot 顶层目录下的 Makefile, 指定交叉工具链
$ vim Makefile

ifeq ($(HOSTARCH, $(ARCH))
CROSS_COMPILE ?=
endif
下添加:
ifeq (arm, $(ARCH))
CROSS_COMPILE ?= arm-cortex_a8-linux-gnueabiendif
在 u-boot 顶层目录下的 Makefile 中添加 lz210 配置信息
$ vim Makefile
在smdkc100_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 smdkc100 samsung s5pc1xx
下添加:
lz210_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 lz210 samsung s5pc1xx


5、 编译 u-boot-2010.03

$ make distclean
$ make lz210_config
$ make
编译完成后生成的 u-boot.bin 就是可执行的镜像文件。 但是该文件只能在
smdkv210 平台上运行,我们需要对 u-boot 源代码进行相应的修改。


二、 uboot 移植


1、 修改 board/samsung/lz210/config.mk

修改
TEXT_BASE = 0x34800000
为:
TEXT_BASE = 0x23e00000


2、 拷贝 lz210.c、 mem_setup.S、 lowlevel_init.S、 nand_cp.c、 smdkc110_val.h 到

board/samsung/lz210/目录下
这些文件是板级初始化代码,来源是三星的 BSP


3、 修改 board/samsung/lz210/Makefile

修改
COBJS-y := lz210.o
SOBJS := lowlevel_init.o

COBJS-y := lz210.o nand_cp.o
SOBJS := lowlevel_init.o mem_setup.o


4、 go 命令的优化:

修改 common/cmd_boot.c 文件:
添加头文件:
#include <image.h>
导入函数:
extern int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t*images);
修改 do_go 函数为:
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr;
addr = simple_strtoul(argv[1], NULL, 16);
bootm_headers_t images;
images.ep = addr;
return do_bootm_linux(flag, argc, argv, &images);
}


5、 添加 nand 启动校验功能:

修改 common/cmd_nand.c

else
ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr);
} else if (!strcmp(s, ".oob")) {
改为
else {
ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr);
if (ret == 0) {
uint *magic = (uint *)(PHYS_SDRAM_1);
if ((0x24564236 == magic[0]) && (0x20764316 == magic[1]))
magic[0] = 0x27051956;
}
}
} else if (!strcmp(s, ".oob")) {


6、 修改 cpu/arm_cortexa8/start.S


#include <config.h>
#include <version.h>
下添加如下代码:
#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
.word 0x2000
.word 0x0
.word 0x0
.word 0x0
#endif注释掉如下代码
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: @ relocate U-Boot to RAM
adr r0, _start @ r0 <- current position of code
……
cmp r0, r2 @ until source end addreee [r2]
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
并在上边注释掉的代码下添加如下代码
ldr sp,=(0x22000000)
bl copy_uboot_to_ram


7、 修改 cpu/arm_cortexa8/u-boot.lds

修改
.text :
{
cpu/arm_cortexa8/start.o(.text)
*(.text)
} 为
.text :
{
cpu/arm_cortexa8/start.o(.text)
board/samsung/lz210/lowlevel_init.o
board/samsung/lz210/mem_setup.o
board/samsung/lz210/nand_cp.o
*(.text)
}


8、 添加 nand flash 的支持

a) 拷贝 s5pv210.c 到 drivers/mtd/nand/
s5pv210.c 是 nand flash 控制器驱动
b) 修改 drivers/mtd/nand/Makefile

COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
下边添加
COBJS-$(CONFIG_NAND_S5PV210) += s5pv210.o
c) 修改 include/linux/mtd/mtd-abi.h在
uint32_t oobavail;
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
下添加
uint32_t useecc;
uint32_t reserved;
d) 修改 driver/mtd/nand/nand_base.c
修改函数 nand_block_bad 中
if (getchip) {
chipnr = (int)(ofs >> chip->chip_shift);
nand_get_device(chip, mtd, FL_READING);
/* Select the NAND device */
chip->select_chip(mtd, chipnr);
} 为
if (getchip) {
chipnr = (int)(ofs >> chip->chip_shift);
nand_get_device(chip, mtd, FL_READING);
/* Select the NAND device */
chip->select_chip(mtd, chipnr);
} else
page = (int)ofs;
#if defined(CONFIG_NAND_BL1_8BIT_ECC) && defined(CONFIG_S5PV210)
if(page < CONFIG_NAND_PAGES_IN_BLOCK)
return 0;
#endif
在函数 nand_do_read_ops 上边添加如下代码
extern int s3c_nand_read_page_8bit(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf);
修改函数 nand_do_read_ops 中
修改
/* Now read the page into the buffer */
if (unlikely(ops->mode == MTD_OOB_RAW))
ret = chip->ecc.read_page_raw(mtd, chip,
bufpoi, page);
else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi);else
ret = chip->ecc.read_page(mtd, chip, bufpoi,
page);
为:
#if defined(CONFIG_NAND_BL1_8BIT_ECC) && defined(CONFIG_S5PV210)
if (page < CONFIG_NAND_PAGES_IN_BLOCK) {
s3c_nand_read_page_8bit(mtd, chip, bufpoi);
} else
#endif
{
/* Now read the page into the buffer */
if (unlikely(ops->mode == MTD_OOB_RAW))
ret = chip->ecc.read_page_raw(mtd, chip, bufpoi, page);
else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi);
else
ret = chip->ecc.read_page(mtd, chip, bufpoi,
page);
}
修改 nand_do_read_oob 函数
注释掉如下内容:
/* Check, if we cross a chip boundary */
if (!page) {
chipnr++;
chip->select_chip(mtd, -1);
chip->select_chip(mtd, chipnr);
}
在函数 nand_write_page 前面添加如下内容:
extern void s3c_nand_write_page_8bit(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf);
修改函数 nand_write_page
修改
if (unlikely(raw))
chip->ecc.write_page_raw(mtd, chip, buf);
else
chip->ecc.write_page(mtd, chip, buf);
为:
#if defined(CONFIG_NAND_BL1_8BIT_ECC) && defined(CONFIG_S5PV210)
if (page < CONFIG_NAND_PAGES_IN_BLOCK) {
memset(chip->oob_poi, 0xff, mtd->oobsize);s3c_nand_write_page_8bit(mtd, chip, buf);
} else
#endif
{
if (unlikely(raw))
chip->ecc.write_page_raw(mtd, chip, buf);
else
chip->ecc.write_page(mtd, chip, buf);
}
修改函数 nand_set_defaults
注释掉如下代码
if (!chip->controller) {
chip->controller = &chip->hwcontrol;
/* XXX U-BOOT XXX */
#if 0
spin_lock_init(&chip->controller->lock);
init_waitqueue_head(&chip->controller->wq);
#endif
}
修改 drivers/mtd/nand/nand_util.c
修改函数 nand_write_skip_bad
在:
u_char *p_buffer = buffer;
下边添加如下代码:
#if defined(CONFIG_S5PV210) && defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
&&
int i;
ulong checksum;
uint8_t *ptr;
if (offset == 0) {
ptr = buffer + 16;
for(i = 16, checksum = 0; i < 8192; i++) {
checksum += *ptr;
ptr++;
}
*((volatile u32 *)(buffer + 0x8)) = checksum;
printk("Checksum is calculated.\n");
}
#endif拷贝 hardware.h 到 include/asm-arm/arch-s5pc1xx/
拷贝 lz210.h 到 include/configs 目录下
拷贝 s5pc110.h 到 include
拷贝 s5pc11x.h 到 include


9、 修改 net/net.c

在 int NetArpWaitTry; 后添加如下代码
ulong timer_clk;
void ArpTimeoutCheck(void)
{
……

t = get_timer(0);
改成
t = get_timer(0) / (timer_clk / CONFIG_SYS_HZ);
}
extern unsigned long (*get_pclk)(void);
int NetLoop(proto_t protocol)
{
bd_t *bd = gd->bd;
添加如下代码:
timer_clk = get_pclk() / (16 * 2);
……
} 把if (timeHandler && ( …> timeDelta) {
改成
ulong t;
t = get_timer(0) / (timer_clk / CONFIG_SYS_HZ);
if (timeHandler && (t - timeStart) > timeDelta) {
……
}
void NetSetTimeout(ulong iv, thand_f *f)
{

timeStart = get_timer(0);
改成
timeStart = get_timer(0) / (timer_clk / CONFIG_SYS_HZ);
} i
nt NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport,
int len)
{
……

NetArpWaitTimerStart = get_timer(0);
改成
NetArpWaitTimerStart = get_timer(0) / (timer_clk / CONFIG_SYS_HZ);
……
}int PingSend(void)
{
……

NetArpWaitTimerStart = get_timer(0);
改成
NetArpWaitTimerStart = get_timer(0) / (timer_clk / CONFIG_SYS_HZ);
……
}


10、 编译 u-boot-2010.03

$ make distclean
$ make lz210_config
$ make
按上个实验烧写 uboot 到板子上,查看 uboot 是否能够正常启动
0 0