一、原理
菜单其实就是一个uboot中的命令,和其他的命令没有什么差别。
uboot启动时,如果进入uboot命令模式,先运行这个命令,就会打印出一个菜单界面。
在uboot的命令模式,通过键入“menu”命令,同样可以调出这个界面。
二、操作步骤
1、在common目录下创建cmd_menu.c
内容如下:
#include <common.h> #include <command.h> #ifdef CONFIG_CMD_MENU #define USE_TFTP_DOWN 1 #define USE_USB_DOWN 2 extern char console_buffer[]; /* * Reads and returns a character from the serial port * - Times out after delay iterations checking for presence of character * - Sets *error_p to UART error bits or - on timeout * - On timeout, sets *error_p to -1 and returns 0 */ static char awaitkey(unsigned long delay, int* error_p) { int i; char c; if (delay == -1) { while (1) { if (tstc()) /* we got a key press */ return getc(); } } else { for (i = 0; i < delay; i++) { if (tstc()) /* we got a key press */ return getc(); udelay (10*1000); } } if (error_p) *error_p = -1; return 0; } static int bBootFrmNORFlash(void) { volatile unsigned int *pdw = (volatile unsigned int *)0; unsigned int dwVal; dwVal = *pdw; *pdw = 0x12345678; if (*pdw != 0x12345678) { return 1; } else { *pdw = dwVal; return 0; } } void main_menu_usage(char menu_type) { if (bBootFrmNORFlash()) printf("\r\n##### Boot for Nor Flash Main Menu #####\r\n"); else printf("\r\n##### Boot for Nand Flash Main Menu #####\r\n"); if( menu_type == USE_USB_DOWN) { printf("##### EmbedSky USB download mode #####\r\n\n"); } else if( menu_type == USE_TFTP_DOWN) { printf("##### EmbedSky TFTP download mode #####\r\n\n"); } if( menu_type == USE_USB_DOWN) { printf("[1] Download u-boot or STEPLDR.nb1 or other bootloader to Nand Flash\r\n"); } else if( menu_type == USE_TFTP_DOWN) { printf("[1] Download u-boot.bin to Nand Flash\r\n"); } printf("[2] Download Eboot (eboot.nb0) to Nand Flash\r\n"); printf("[3] Download Linux Kernel (zImage.bin) to Nand Flash\r\n"); if( menu_type == USE_USB_DOWN) { #ifdef CONFIG_SURPORT_WINCE printf("[4] Download WinCE NK.bin to Nand Flash\r\n"); #endif printf("[5] Download CRAMFS image to Nand Flash\r\n"); } else if( menu_type == USE_TFTP_DOWN) { printf("[4] Download stepldr.nb1 to Nand Flash\r\n"); printf("[5] Set TFTP parameters(PC IP,TQ2440 IP,Mask IP...)\r\n"); } printf("[6] Download YAFFS image (root.bin) to Nand Flash\r\n"); printf("[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it\r\n"); printf("[8] Boot the system\r\n"); printf("[9] Format the Nand Flash\r\n"); printf("[0] Set the boot parameters\r\n"); printf("[a] Download User Program (eg: uCOS-II or TQ2440_Test)\r\n"); printf("[b] Download LOGO Picture (.bin) to Nand Flash \r\n"); printf("[l] Set LCD Parameters \r\n"); if( menu_type == USE_USB_DOWN) { printf("[n] Enter TFTP download mode menu \r\n"); } if (bBootFrmNORFlash()) printf("[o] Download u-boot to Nor Flash\r\n"); if( menu_type == USE_TFTP_DOWN) printf("[p] Test network (TQ2440 Ping PC's IP) \r\n"); printf("[r] Reboot u-boot\r\n"); printf("[t] Test Linux Image (zImage)\r\n"); if( menu_type == USE_USB_DOWN) { printf("[q] quit from menu\r\n"); } else if( menu_type == USE_TFTP_DOWN) { printf("[q] Return main Menu \r\n"); } printf("Enter your selection: "); } void tftp_menu_shell(void) { char c; char cmd_buf[200]; while (1) { main_menu_usage(USE_TFTP_DOWN); c = awaitkey(-1, NULL); printf("%c\n", c); switch (c) { case '1': { strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; nand erase bios; nand write.jffs2 0x30000000 bios $(filesize)"); run_command(cmd_buf, 0); break; } case '2': { sprintf(cmd_buf, "tftp 0x30000000 eboot.nb0; nand erase eboot; nand write.jffs2 0x30000000 eboot $(filesize)"); run_command(cmd_buf, 0); break; } case '3': { strcpy(cmd_buf, "tftp 0x30000000 zImage.bin; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)"); run_command(cmd_buf, 0); break; } case '4': { strcpy(cmd_buf, "tftp 0x30000000 stepldr.nb1; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)"); run_command(cmd_buf, 0); break; } case '5': { char param_buf1[25]; char param_buf2[25]; char param_buf3[25]; printf("Enter the TFTP Server(PC) IP address:(xxx.xxx.xxx.xxx)\n"); readline(NULL); strcpy(param_buf1,console_buffer); sprintf(cmd_buf, "setenv serverip %s",param_buf1); run_command(cmd_buf, 0); printf("Enter the SKY2440/TQ2440 IP address:(xxx.xxx.xxx.xxx)\n"); readline(NULL); strcpy(param_buf2,console_buffer); sprintf(cmd_buf, "setenv ipaddr %s",param_buf2); run_command(cmd_buf, 0); printf("Enter the Mask IP address:(xxx.xxx.xxx.xxx)\n"); readline(NULL); strcpy(param_buf3,console_buffer); sprintf(cmd_buf, "setenv netmask %s",param_buf3); run_command(cmd_buf, 0); printf("Save TFTP IP parameters?(y/n)\n"); if (getc() == 'y' ) { printf("y"); getc() == '\r'; printf("\n"); sprintf(cmd_buf, "saveenv"); run_command(cmd_buf, 0); } else { printf("Not Save it!!!\n"); } break; } case '6': { strcpy(cmd_buf, "tftp 0x30000000 root.bin; nand erase root; nand write.yaffs 0x30000000 root $(filesize)"); run_command(cmd_buf, 0); break; } case '7': { char tftpaddress[12]; char filename[32]; printf("Enter downloads to SDRAM address:\n"); readline(NULL); strcpy(tftpaddress, console_buffer); printf("Enter program name:\n"); readline(NULL); strcpy(filename, console_buffer); sprintf(cmd_buf, "tftp %s %s", tftpaddress, filename); printf("tftp %s %s\n", tftpaddress, filename); run_command(cmd_buf, 0); sprintf(cmd_buf, "go %s", tftpaddress); run_command(cmd_buf, 0); break; } case '8': { printf("Start Linux ...\n"); strcpy(cmd_buf, "boot_zImage"); run_command(cmd_buf, 0); break; } case '9': { strcpy(cmd_buf, "nand scrub "); run_command(cmd_buf, 0); // erase_menu_shell(); break; } case 'A': case 'a': { char filename[32]; printf("Enter program name:\n"); readline(NULL); strcpy(filename, console_buffer); sprintf(cmd_buf, "tftp 0x30000000 %s; nand erase 0x0 $(filesize+1); nand write.jffs2 0x30000000 0x0 $(filesize+1)", filename); run_command(cmd_buf, 0); break; } case 'B': case 'b': { strcpy(cmd_buf, "tftp 0x30000000 logo.bin; nand erase logo; nand write.jffs2 0x30000000 logo $(filesize)"); run_command(cmd_buf, 0); break; } case 'O': case 'o': { if (bBootFrmNORFlash()) { strcpy(cmd_buf, "tftp 0x30000000 uboot.bin; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)"); run_command(cmd_buf, 0); } break; } case 'P': case 'p': { char *serverip; serverip=getenv("serverip"); printf("TQ2440 ping PC IP:ping %s\n",serverip); sprintf(cmd_buf, "ping %s",serverip); run_command(cmd_buf, 0); break; } case 'R': case 'r': { strcpy(cmd_buf, "reset"); run_command(cmd_buf, 0); break; } case 'T': case 't': { strcpy(cmd_buf, "tftp 0x30008000 zImage.bin; test_zImage"); run_command(cmd_buf, 0); break; } case 'Q': case 'q': { return; break; } default: ; } } } int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { tftp_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" ); #endif /* #ifdef CONFIG_CMD_MENU */
2、修改common/Makefile
COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \
cmd_ace.o cmd_autoscript.o \
......
virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_menu.o
3、修改common/main.c,调用菜单命令(menu)
if (bootdelay >= 0 && s && !abortboot (bootdelay)) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif # ifndef CFG_HUSH_PARSER run_command (s, 0); # else parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ # endif } #ifdef CONFIG_CMD_MENU run_command("menu", 0); #endif
4、修改include/configs/TQ2440.h
/*********************************************************** * Command definition ***********************************************************/ #define CONFIG_COMMANDS \ (CONFIG_CMD_DFL | \ CFG_CMD_CACHE | \ CFG_CMD_NAND | \ /*CFG_CMD_EEPROM |*/ \ /*CFG_CMD_I2C |*/ \ /*CFG_CMD_USB |*/ \ CFG_CMD_REGINFO | \ CFG_CMD_DATE | \ CFG_CMD_REGINFO | \ CFG_CMD_PING | \ CFG_CMD_ELF) #define CONFIG_CMD_MENU 1
参考网页:uboot中的快捷菜单的制作说明