本文主要是介绍ok6410 u-boot-2012.04.01移植三增加菜单update功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
继ok6410 u-boot-2012.04.01移植二后,增加以前写的裸板程序update菜单功能。以后就可以利用菜单,通过串口下载程序。读写NAND FLASH,把程序放到内存运行等功能。
开发环境:系统:ubuntu 10.04.4
单板:ok6410
NAND FLASH:K9GAG08U0D 2048MB
DDR:K4X1G163PCX2 256MB
NET:DM9000AEP
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。
目标:
1.板级初始化,支持单板ok6410
2.修改u-boot,支持NAND启动
3.增加菜单update功能
4.增加MLC NAND支持
5.支持DM9000,网卡下载程序
6.修改环境变量以及mtdpart分区
7.u-boot裁剪及制作补丁
一、增加菜单运行命令
在下面地方增加run_command("menu", 0);
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
#if defined(CONFIG_MENU_SHOW)
bootdelay = menu_show(bootdelay);
#endif
# ifdef CONFIG_BOOT_RETRY_TIME
init_cmd_timeout ();
# endif /* CONFIG_BOOT_RETRY_TIME */
#ifdef CONFIG_POST
if (gd->flags & GD_FLG_POSTFAIL) {
s = getenv("failbootcmd");
}
else
#endif /* CONFIG_POST */
#ifdef CONFIG_BOOTCOUNT_LIMIT
if (bootlimit && (bootcount > bootlimit)) {
printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
(unsigned)bootlimit);
s = getenv ("altbootcmd");
}
else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
s = getenv ("bootcmd");
debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1);/* disable Control C checking */
# endif
run_command(s, 0);
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev);/* restore Control C checking */
# endif
}
# ifdef CONFIG_MENUKEY
if (menukey == CONFIG_MENUKEY) {
s = getenv("menucmd");
if (s)
run_command(s, 0);
}
#endif /* CONFIG_MENUKEY */
#endif /* CONFIG_BOOTDELAY */
run_command("menu", 0);
/*
* Main Loop for Monitor Command Processing
*/
也就是在宏定义#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)结束后添加
二、增加cmd_menu.c实现菜单命令
1.在common/下增加文件cmd_menu.c:
#include <common.h>
#include <command.h>
#include <nand.h>
extern char console_buffer[];
extern int readline (const char *const prompt);
//extern char awaitkey(unsigned long delay, int* error_p);
extern void download_nkbin_to_flash(void);
extern void nand_read_ll(unsigned int nand_start, unsigned int ddr_start, unsigned int len);
//extern void putc(char c);
//extern void puts(char *str);
//extern void puthex(unsigned int val);
//extern unsigned char getc(void);
extern int getc_nowait(unsigned char *pChar);
//extern void putbyte(unsigned char val);
extern void nand_erase_block_ll(unsigned long addr);
extern void nand_write_ll(unsigned int nand_start, unsigned char * buf, unsigned int len);
void puthex(unsigned int val)
{
/* 0x1234abcd */
int i;
int j;
printf("0x");
for (i = 0; i < 8; i++)
{
j = (val >> ((7-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);
}
}
void putbyte(unsigned char val)
{
/* 0x1234abcd */
int i;
int j;
printf("0x");
for (i = 0; i < 2; i++)
{
j = (val >> ((1-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);
}
}
void param_menu_usage()
{
printf("\r\n##### Parameter Menu #####\r\n");
printf("[g] Use gtk/V2.2.exe write the file to NAND Flash\r\n");
printf("[b] Boot the system \r\n");
printf("[r] Reset the u-boot \r\n");
printf("[q] Quit \r\n");
printf("Enter your selection: ");
}
void main_menu_usage(void)
{
printf("\r\n##### Update menu for ok6410 #####\r\n");
printf("[g] get file, and write to nand flash 0 block\n\r");
printf("[b] Boot the system\r\n");
printf("[r] Reset the u-boot \r\n");
printf("[q] Quit from menu\r\n");
printf("Enter your selection: ");
}
void update_program(void)
{
unsigned char *buf = (unsigned char *)0x52000000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
unsigned long erase_addr;
char c;
int i;
/* \u8bfb\u4e32\u53e3\u83b7\u5f97\u6570\u636e */
puts("\n\ruse V2.2.exe/gtkterm to send file\n\r");
while (1)
{
if (getc_nowait(&buf[len]) == 0)
{
have_begin = 1;
nodata_time = 0;
len++;
}
else
{
if (have_begin)
{
nodata_time++;
}
}
if (nodata_time == 1000)
{
break;
}
}
printf("\n\rhave get data:");
puthex(len);
printf(" bytes\n\r");
printf("the first 16 bytes data: \n\r");
for (i = 0; i < 16; i++)
{
// put("%02x ", buf[i]);
putbyte(buf[i]);
printf("\t");
}
printf("\n\r");
printf("Press Y to program the flash: \n\r");
c = getc();
putc(c);
printf("\n\r");
if (c == 'y' || c == 'Y')
{
/* \u70e7\u5199\u5230nand flash block 0 */
for (erase_addr = 0; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)
{
nand_erase_block_ll(erase_addr);
}
nand_write_ll(0, buf, len);
printf("update program successful\n\r");
}
else
{
printf("Cancel program!\n\r");
}
}
void menu_shell(void)
{
char c;
char cmd_buf[200];
char *p = NULL;
unsigned long size;
unsigned long offset;
struct mtd_info *mtd = &nand_info[nand_curr_device];
while (1)
{
main_menu_usage();
//c = awaitkey(-1, NULL);
c = getc();
printf("%c\n", c);
switch (c)
{
case 'g':
{
//extern void do_bootm_rawLinux (ulong addr);
update_program();
//do_bootm_rawLinux(0x30008000);
}
case 'b':
{
printf("Booting Linux ...\n");
strcpy(cmd_buf, "nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0");
run_command(cmd_buf, 0);
break;
}
case 'r':
{
strcpy(cmd_buf, "reset");
run_command(cmd_buf, 0);
break;
}
case 'q':
{
return;
break;
}
}
}
}
int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
menu_shell();
return 0;
}
U_BOOT_CMD(
menu, 3, 0, do_menu,
"menu - display a menu, to select the items to do something\n",
" - display a menu, to select the items to do something"
);
2.修改common/Makefile:
在# command下77:增加COBJS-y += cmd_menu.o
三、编译测试
change@change:~$ cd /si/OK6410/u-boot-2012.04.01/
change@change:/si/OK6410/u-boot-2012.04.01$ make
将生成的u-boot.bin拷贝到我们移植二中制作的启动SD卡里·,再拨到SD卡启动,串口输出如下:
K
U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410
****************************************
** u-boot 1.1.6 **
** Updated for TE6410 Board **
** Version 1.0 (10-01-15) **
** OEM: Forlinx Embedded **
** Web: http://www.witech.com.cn **
****************************************
CPU: S3C6410 @532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board: SMDK6410
DRAM: 128 MB
Flash: 0 kB
NAND: tmp = 29
select s3c_nand_oob_mlc_128
2048 MB
SD/MMC: 1904 MB
*** Warning - bad CRC or moviNAND, using default environment
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
NAND erase: device 0 whole chip
Skipping bad block at 0x00800000
Skipping bad block at 0x0e400000
Skipping bad block at 0x0e780000
Skipping bad block at 0x13b80000
Skipping bad block at 0x27a80000
Skipping bad block at 0x7e280000
Erasing at 0x7ff80000 -- 100% complete.
OK
reading u-boot.bin
221092 bytes read
NAND write: device 0 offset 0x0, size 0x100000
1032192 bytes written: OK
reading zImage
** Unable to read "zImage" from mmc 0:1 **
1032192 bytes written: OK说明烧写OK,接着拨到NAND启动,串口输出如下:
U-Boot 2012.04.01 (Jun 30 2013 - 15:31:39) for SMDK6400
CPU: S3C6400@532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6400
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: 0 KB
NAND: No oob scheme defined for oobsize 218
2048 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
##### Update menu for ok6410 #####
[g] get file, and write to nand flash 0 block
[b] Boot the system
[r] Reset the u-boot
[q] Quit from menu
Enter your selection: q
SMDK6400 #
启动按任意键,进入菜单。下面测试更新程序功能,这里“g”是更新程序命令,更新程序需要使用GTK或者V2.2.exe串口工具,使用V2.2.exe测试如下:
用V2.2.exe手动发送任意键进入菜单,手动发送g接着选择发送文件,然后点击发送文件,再跟着提示输入y,开始更新程序。截图如下:
接着手动输入r系统重启进入刚刚烧写的新u-boot,如下:
这篇关于ok6410 u-boot-2012.04.01移植三增加菜单update功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!