在u-boot启动的时候,在3秒之内按下空格键就可以进入快捷菜单,效果如下:
通过串口输入数字,就可以执行相应的功能,例如:启动内核,重启u-boot,下载镜像到NandFlash。
这个菜单其实就是u-boot中添加的一个命令,u-boot启动时,如果进入下载模式,就先运行这个命令。
添加一个名为cmd_menu.c的文件到common目录下,该文件的内容如下:
- #include
- #include
- #include <../drivers/usb/slave/def.h>
- #include
- extern char console_buffer[];
- extern int readline (const char *const prompt);
- extern char awaitkey(unsigned long delay, int* error_p);
- /**
- * Parses a string into a number. The number stored at ptr is
- * potentially suffixed with K (for kilobytes, or 1024 bytes),
- * M (for megabytes, or 1048576 bytes), or G (for gigabytes, or
- * 1073741824). If the number is suffixed with K, M, or G, then
- * the return value is the number multiplied by one kilobyte, one
- * megabyte, or one gigabyte, respectively.
- *
- * @param ptr where parse begins
- * @param retptr output pointer to next char after parse completes (output)
- * @return resulting unsigned int
- */
- static unsigned long memsize_parse2 (const char *const ptr, const char **retptr)
- {
- unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
- int sixteen = 1;
- switch (**retptr) {
- case 'G':
- case 'g':
- ret <<= 10;
- case 'M':
- case 'm':
- ret <<= 10;
- case 'K':
- case 'k':
- ret <<= 10;
- (*retptr)++;
- sixteen = 0;
- default:
- break;
- }
- if (sixteen)
- return simple_strtoul(ptr, NULL, 16);
-
- return ret;
- }
- void param_menu_usage(void)
- {
- printf("\r\n##### Parameter Menu #####\r\n");
- printf("[1] 查看参数\r\n");
- printf("[2] 设置参数 \r\n");
- printf("[3] 删除参数 \r\n");
- printf("[4] 写入参数到flash \r\n");
- printf("[5] 返回 \r\n");
- printf("Enter your selection: ");
- }
- void param_menu_shell(void)
- {
- char c;
- char cmd_buf[256];
- while (1)
- {
- param_menu_usage();
- c = awaitkey(-1, NULL);
- printf("%c\n", c);
- switch (c)
- {
- case '1':
- {
- strcpy(cmd_buf, "printenv ");
- printf("Name(enter to view all paramters): ");
- readline(NULL);
- strcat(cmd_buf, console_buffer);
- run_command(cmd_buf, 0);
- break;
- }
-
- case '2':
- {
- sprintf(cmd_buf, "setenv ");
- printf("Name: ");
- readline(NULL);
- strcat(cmd_buf, console_buffer);
- printf("Value: ");
- readline(NULL);
- strcat(cmd_buf, " ");
- strcat(cmd_buf, console_buffer);
- run_command(cmd_buf, 0);
- break;
- }
-
- case '3':
- {
- sprintf(cmd_buf, "setenv ");
- printf("Name: ");
- readline(NULL);
- strcat(cmd_buf, console_buffer);
- run_command(cmd_buf, 0);
- break;
- }
-
- case '4':
- {
- sprintf(cmd_buf, "saveenv");
- run_command(cmd_buf, 0);
- break;
- }
-
- case '5':
- {
- return;
- break;
- }
- }
- }
- }
- void erase_menu_usage(void)
- {
- printf("\r\n##### Erase Nand Menu #####\r\n");
- printf("[1] Nand scrub - really clean NAND erasing bad blocks (UNSAFE) \r\n");
- printf("[2] Nand earse - clean NAND eraseing \r\n");
- printf("[q] Return main Menu \r\n");
- printf("Enter your selection: ");
- }
- void erase_menu_shell(void)
- {
- char c;
- char cmd_buf[256];
- char *p = NULL;
- unsigned long size;
- while (1)
- {
- erase_menu_usage();
- c = awaitkey(-1, NULL);
- printf("%c\n", c);
- switch (c)
- {
- case '1':
- {
- strcpy(cmd_buf, "nand scrub ");
- run_command(cmd_buf, 0);
- break;
- }
- case '2':
- {
- strcpy(cmd_buf, "nand erase ");
- printf("Start address: ");
- readline(NULL);
- strcat(cmd_buf, console_buffer);
- printf("Size(eg. 4000000, 0x4000000, 64m and so on): ");
- readline(NULL);
- p = console_buffer;
- size = memsize_parse2(p, &p);
- sprintf(console_buffer, " %x", size);
- strcat(cmd_buf, console_buffer);
- run_command(cmd_buf, 0);
- break;
- }
- case 'q':
- {
- return;
- break;
- }
- }
- }
- }
- void main_menu_usage(void)
- {
- printf("[1] 烧写bootloader到nandflash\r\n");
- printf("[2] 烧写Linux Kernel到nandflash\r\n");
- printf("[3] 烧写yaffs2文件系统到nandflash\r\n");
- printf("[4] 下载程序在SDRAM中运行\r\n");
- printf("[5] 设置uboot参数\r\n");
- printf("[6] 格式化Nandflash\r\n");
- printf("[7] 启动Linux系统\r\n");
- printf("[8] 进入Shell模式\r\n");
- printf("[9] 重启uboot\r\n");
- if (bBootFrmNORFlash == 1)
- printf("[0] 下载bootloader到NorFlash\r\n");
- printf("Enter your selection: ");
- }
- void menu_shell(void)
- {
- char c;
- char cmd_buf[200];
-
- while (1)
- {
- main_menu_usage();
- c = awaitkey(-1, NULL);
- printf("%c\n", c);
- switch (c)
- {
- case '1': //download bootloader
- {
- strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase bios; nand write.jffs2 0x30000000 bios 0x100000");
- run_command(cmd_buf, 0);
- break;
- }
- case '2': //kernel
- {
- strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel 0x400000");
- run_command(cmd_buf, 0);
- break;
- }
- case '3': //yaffs
- {
- strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase root; nand write.yaffs 0x30000000 root $(filesize)");
- run_command(cmd_buf, 0);
- break;
- }
- case '4': //sdram
- {
- extern volatile U32 downloadAddress;
- extern int download_run;
-
- download_run = 1;
- strcpy(cmd_buf, "usbslave 1 0x30000000");
- run_command(cmd_buf, 0);
- download_run = 0;
- sprintf(cmd_buf, "go %x", downloadAddress);
- run_command(cmd_buf, 0);
- break;
- }
- case '5': //set param
- {
- param_menu_shell();
- break;
- }
-
- case '6': //format
- {
- erase_menu_shell();
- break;
- }
- case '7': //boot
- {
- printf("Start Linux ...\n");
- strcpy(cmd_buf, "nand read 0x30008000 0x120000 0x400000; go 0x30008000");
- run_command(cmd_buf, 0);
- break;
- }
- case '8': //quit
- {
- return;
- break;
- }
- case '9': //reset
- {
- strcpy(cmd_buf, "reset");
- run_command(cmd_buf, 0);
- break;
- }
-
- case '0': //download uboot to NOR
- {
- if (bBootFrmNORFlash == 1)
- {
- strcpy(cmd_buf, "usbslave 1 0x30000000; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");
- run_command(cmd_buf, 0);
- }
- 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"
- );
修改common目录下的Makefile文件,加入cmd_menu.c的编译选项,代码如下:
- COBJS-$(CONFIG_UPDATE_TFTP) += update.o
- COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
- COBJS-$(CONFIG_CMD_MENU) += cmd_menu.o
然后修改smdk2440.h文件,添加CONFIG_CMD_MENU命令,这样就会编译cmd_menu.c文件,修改的代码如下:- #define CONFIG_CMD_CACHE
- #define CONFIG_CMD_DATE
- #define CONFIG_CMD_ELF
- #define CONFIG_CMD_NAND
- #define CONFIG_CMD_MTDPARTS
- #define CONFIG_CMD_PING
- #define CONFIG_CMD_MENU
在main.c的main_loop函数中调用menu命令,在bootdelay时间没有按下空格键,如果是NorFlash启动的话则运行menu命令,如果是NandFlash启动则启动linux内核,修改代码如下:
- if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
- # ifdef CONFIG_AUTOBOOT_KEYED
- int prev = disable_ctrlc(1); /* disable Control C checking */
- # endif
- #ifdef CONFIG_CMD_MENU
- if (bBootFrmNORFlash == 1)
- {
- run_command("menu", 0);
- }
- else
- {
- printf("Booting Linux ...\n");
- }
- #else
- printf("Booting Linux ...\n");
- #endif
u-boot源代码中,在bootdelay时间内按下空格键的话,则会进入shell命令行模式,我们修改代码使其运行menu命令,进入快捷菜单界面,修改的代码如下:
- #ifdef CONFIG_AMIGAONEG3SE
- {
- extern void video_banner(void);
- video_banner();
- }
- #endif
- #ifdef CONFIG_CMD_MENU
- run_command("menu", 0);
- #endif
另外,在start.S文件中定义变量bBootFrmNORFlash,如果是从NorFlash驱动的话,则把该变量置为1,修改的代码如下:
- .globl _bss_start
- _bss_start:
- .word __bss_start
- .globl _bss_end
- _bss_end:
- .word _end
-
- .globl bBootFrmNORFlash
- bBootFrmNORFlash:
- .word 0
在NorFlash启动的时候,把该变量置1
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 */
SetBootFlag:
ldr r0, =bBootFrmNORFlash
mov r1, #1
str r1, [r0]
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CONFIG_SYS_MALLOC_LEN
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
修改include/asm-arm/目录下的u-boot-arm.h文件,这样在main.c里就可以使用bBootFrmNORFlash这个变量了,修改的代码如下:
- extern ulong IRQ_STACK_START; /* top of IRQ stack */
- extern ulong FIQ_STACK_START; /* top of FIQ stack */
- extern ulong bBootFrmNORFlash;
重新编译u-boot,下载到NandFlash中,就可以看到效果了。
我们还可以继续修改代码,添加自己的打印消息,如下所示:
在main.c中添加一个show_myinfo函数,修改的代码如下:
- static void show_myinfo(void)
- {
- printf("****************************************\n");
- printf("******* zjw 制作 2012.10.20 ********\n");
- printf("*** u-boot-2010.03 for smdk2440 ***\n");
- if (bBootFrmNORFlash == 1)
- printf("*** NorFlash启动方式 ***\n");
- else
- printf("*** NandFlash启动方式 ***\n");
- printf("****************************************\n");
- }
在abortboot函数中调用show_myinfo函数,修改的代码如下:
- static __inline__ int abortboot(int bootdelay)
- {
- int abort = 0;
- show_myinfo();
还可以在board.c中继续修改和添加自己的信息,修改version_string[]如下:
- const char version_string[] =
- U_BOOT_VERSION"<-->"CONFIG_IDENT_STRING;
在smdk2440.h中定义CONFIG_IDENT_STRING宏,代码如下:
- #define CONFIG_IDENT_STRING " zjw modify for SMDK2440 "
修改board.c中的display_banner函数,修改的代码如下:
- static int display_banner (void)
- {
- printf ("\n\n%s\n\n", version_string);
- printf ("##########********** Board Info **********##########\n");
- debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
- _armboot_start, _bss_start, _bss_end);
修改board.c中的start_armboot函数,修改的代码如下:
- printf ("##########******************************##########\n\n");
- /* main_loop() can return to retry autoboot, if so just run it again. */
- for (;;) {
- main_loop ();
- }
最后重新编译u-boot,下载到NandFlas中运行,就会出现如本节最上面的图片一样的效果。
阅读(1203) | 评论(0) | 转发(1) |