您的位置:首页 > 其它

U-Boot添加命令的方法

2013-12-19 20:52 411 查看
下面以添加menu命令为例分析U-Boot添加命令的方法。

  (1)在common目录下新建cmd_menu.c文件

习惯上把通用命令源代码放在common目录下,与开发板专有命令有关的源代码则放在board/目录下,命名方式只是习惯而已。为了方便阅读和查询习惯以“cmd_<</span>命 令名>.c”为文件名。

(2)定义“menu”命令
在cmd_menu.c中使用如下的代码定义“menu”命令:




1 U_BOOT_CMD(

2

3 menu, 3, 0, do_menu,

4

5 "menu - display a menu, to select the items to do something\n",

6

7 " - display a menu, to select the items to do something"

8

9 );





其中U_BOOT_CMD命令格式如下:

1 U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)


  各个参数的意义如下:

name:命令名,非字符串,但在U_BOOT_CMD中用“#”符号转化为字符串
maxargs:命令的最大参数个数
rep:是否自动重复(按Enter键是否会重复执行)
cmd:该命令对应的响应函数
usage:简短的使用说明(字符串)
help:较详细的使用说明(字符串)
在内存中保存命令的help字段会占用一定的内存,通过配置U-Boot可以选择是否保存help字段。若在include/configs/mx51_bbg.h中定义了CONFIG_SYS_LONGHELP宏,则在U-Boot中使用help命令查看某个命令的帮助信息时将显示usage和help字段的内容,否则就只显示usage字段的内容。

U_BOOT_CMD宏在include/command.h中定义:

1 #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

2   cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}


“##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串。




1 struct cmd_tbl_s {

2 char *name;

3 int maxargs;

4 int repeatable;

5 int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);

6 char *usage;

7 #ifdef CONFIG_SYS_LONGHELP

8 char *help;

9 #endif

10 #ifdef CONFIG_AUTO_COMPLETE

11

12 int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);

13 #endif

14 };

15 typedef struct cmd_tbl_s cmd_tbl_t;





一个cmd_tbl_t结构体变量包含了调用一条命令的所需要的信息。

其中Struct_Section在include/command.h中定义如下:

1 #define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))


凡是带有__attribute__ ((unused,section
(".u_boot_cmd"))属性声明的变量都将被存放在".u_boot_cmd"段中,并且即使该变量没有在代码中显式的使用编译器也不产生警告信息。
在U-Boot连接脚本u-boot.lds中定义了".u_boot_cmd"段:

1 . = .;

2 __u_boot_cmd_start = .;

3 .u_boot_cmd : { *(.u_boot_cmd) }

4 __u_boot_cmd_end = .;


这表明带有“.u_boot_cmd”声明的函数或变量将存储在“u_boot_cmd”段。这样只要将U-Boot所有命令对应的cmd_tbl_t变量加上“.u_boot_cmd”声明,编译器就会自动将其放在“u_boot_cmd”段,查找cmd_tbl_t变量时只要在__u_boot_cmd_start与__u_boot_cmd_end之间查找就可以了。

因此“menu”命令的定义经过宏展开后如下:

cmd_tbl_t __u_boot_cmd_menu __attribute__

((unused,section (".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"}


实质上就是用U_BOOT_CMD宏定义的信息构造了一个cmd_tbl_t类型的结构体。编译器将该结构体放在“u_boot_cmd”段,执行命令时就可以在“u_boot_cmd”段查找到对应的cmd_tbl_t类型结构体。

(3)实现命令的函数
即U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)中的cmd参数

在cmd_menu.c中添加“menu”命令的响应函数的实现。具体的实现代码略:

1 int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

2 {

3

4 }


(4)
将common/cmd_menu.c编译进u-boot.bin
在common/Makefile中把目标代码cmd_menu.o也加入一起编译:
在include/configs/mx51_bbg.h加入如代码:
#define CONFIG_BOOT_MENU 1
重新编译下载U-Boot就可以使用menu命令了

(5)menu命令执行的过程
在U-Boot中输入“menu”命令执行时,U-Boot接收输入的字符串“menu”,传递给run_command函数。run_command函数调用common/command.c中实现的find_cmd函数在__u_boot_cmd_start与__u_boot_cmd_end间查找命令,并返回menu命令的cmd_tbl_t结构。然后run_command函数使用返回的cmd_tbl_t结构中的函数指针调用menu命令的响应函数do_menu,从而完成了命令的执行。

(6)例子:USB下载,命令很简单。




1 #include

2 #include

3 extern char console_buffer[];

4 extern int readline (const char *const prompt);

5 extern char awaitkey(unsigned long delay, int* error_p);

6 extern void download_nkbin_to_flash(void);

7

19 static unsigned long memsize_parse2 (const char *const ptr, const char **retptr)

20 {

21  unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);

22     int sixteen = 1;

23  switch (**retptr) {

24   case 'G':

25   case 'g':

26    ret <<= 10;

27   case 'M':

28   case 'm':

29    ret <<= 10;

30   case 'K':

31   case 'k':

32    ret <<= 10;

33    (*retptr)++;

34             sixteen = 0;

35   default:

36    break;

37  }

38     if (sixteen)

39         return simple_strtoul(ptr, NULL, 16);

40

41   return ret;

42 }

43

44 void param_menu_usage()

45 {

46     printf("\r\n##### Parameter Menu #####\r\n");

47     printf("[v] View the parameters\r\n");

48     printf("[s] Set parameter \r\n");

49     printf("[d] Delete parameter \r\n");

50     printf("[w] Write the parameters to flash memeory \r\n");

51     printf("[q] Quit \r\n");

52     printf("Enter your selection: ");

53 }

54

55 void param_menu_shell(void)

56 {

57     char c;

58     char cmd_buf[256];

59     char name_buf[20];

60     char val_buf[256];

61

62      while (1)

63     {

64         param_menu_usage();

65         c = awaitkey(-1, NULL);

66         printf("%c\n", c);

67         switch (c)

68         {

69             case 'v':

70             {

71                 strcpy(cmd_buf, "printenv ");

72                 printf("Name(enter to view all paramters): ");

73                 readline(NULL);

74                 strcat(cmd_buf, console_buffer);

75                 run_command(cmd_buf, 0);

76                 break;

77             }

78

79              case 's':

80             {

81                 sprintf(cmd_buf, "setenv ");

82                 printf("Name: ");

83                 readline(NULL);

84                 strcat(cmd_buf, console_buffer);

85                 printf("Value: ");

86                 readline(NULL);

87                 strcat(cmd_buf, " ");

88                 strcat(cmd_buf, console_buffer);

89                 run_command(cmd_buf, 0);

90                 break;

91             }

92

93              case 'd':

94             {

95                 sprintf(cmd_buf, "setenv ");

96                 printf("Name: ");

97                 readline(NULL);

98                 strcat(cmd_buf, console_buffer);

99                 run_command(cmd_buf, 0);

100                 break;

101             }

102

103              case 'w':

104             {

105                 sprintf(cmd_buf, "saveenv");

106                 run_command(cmd_buf, 0);

107                 break;

108             }

109

110              case 'q':

111             {

112                 return;

113                 break;

114             }

115         }

116     }

117 }

118

119 void main_menu_usage(void)

120 {

121     printf("\r\n##### 100ask Bootloader for OpenJTAG #####\r\n");

122     printf("
Download u-boot to Nand Flash\r\n");

123  if (bBootFrmNORFlash())

124      printf("[o] Download u-boot to Nor Flash\r\n");

125     printf("[k] Download Linux kernel uImage\r\n");

126     printf("[j] Download root_jffs2 image\r\n");

127 //    printf("[c] Download root_cramfs image\r\n");
128     printf("[y] Download root_yaffs image\r\n");

129     printf("[d] Download to SDRAM & Run\r\n");

130     printf("[z] Download zImage into RAM\r\n");

131     printf("[g] Boot linux from RAM\r\n");

132     printf("[f] Format the Nand Flash\r\n");

133     printf("[s] Set the boot parameters\r\n");

134     printf("[b] Boot the system\r\n");

135     printf("[r] Reboot u-boot\r\n");

136     printf("[q] Quit from menu\r\n");

137     printf("Enter your selection: ");

138 }

139

140 void menu_shell(void)

141 {

142     char c;

143     char cmd_buf[200];

144     char *p = NULL;

145     unsigned long size;

146     unsigned long offset;

147     struct mtd_info *mtd = &nand_info[nand_curr_device];

148     while (1)

149     {

150         main_menu_usage();

151         c = awaitkey(-1, NULL);

152         printf("%c\n", c);

153         switch (c)

154         {

155    case 'n':

156    {

157                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase bootloader; nand write.jffs2 0x30000000 bootloader $(filesize)");

158                 run_command(cmd_buf, 0);

159                 break;

160    }

161             case 'o':

162             {

163                 if (bBootFrmNORFlash())

164                 {

165                     strcpy(cmd_buf, "usbslave 1 0x30000000; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");

166                     run_command(cmd_buf, 0);

167                 }

168     break;

169             }

170

171              case 'k':

172             {

173                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");

174                 run_command(cmd_buf, 0);

175                 break;

176             }

177             case 'j':

178             {

179                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase root; nand write.jffs2 0x30000000 root $(filesize)");

180                 run_command(cmd_buf, 0);

181                 break;

182             }

183 #if 0

184             case 'c':

185             {

186                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase root; nand write.jffs2 0x30000000 root $(filesize)");

187                 run_command(cmd_buf, 0);

188                 break;

189             }

190 #endif

191             case 'y':

192             {

193                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase root; nand write.yaffs 0x30000000 root $(filesize)");

194                 run_command(cmd_buf, 0);

195                 break;

196             }

197             case 'd':

198             {

199                 extern volatile U32 downloadAddress;

200                 extern int download_run;

201

202                  download_run = 1;

203                 strcpy(cmd_buf, "usbslave 1");

204                 run_command(cmd_buf, 0);

205                 download_run = 0;

206                 sprintf(cmd_buf, "go %x", downloadAddress);

207                 run_command(cmd_buf, 0);

208                 break;

209             }

210    case 'z':

211    {

212     strcpy(cmd_buf, "usbslave 1 0x30008000");

213     run_command(cmd_buf, 0);

214     break;

215    }

216    case 'g':

217    {

218     extern void do_bootm_rawLinux (ulong addr);

219     do_bootm_rawLinux(0x30008000);

220    }

221             case 'b':

222             {

223                 printf("Booting Linux ...\n");

224                 strcpy(cmd_buf, "nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0");

225                 run_command(cmd_buf, 0);

226                 break;

227             }

228             case 'f':

229             {

230                 strcpy(cmd_buf, "nand erase ");

231                 printf("Start address: ");

232                 readline(NULL);

233                 strcat(cmd_buf, console_buffer);

234                 printf("Size(eg. 4000000, 0x4000000, 64m and so on): ");

235                 readline(NULL);

236                 p = console_buffer;

237                 size = memsize_parse2(p, &p);

238                 sprintf(console_buffer, " %x", size);

239                 strcat(cmd_buf, console_buffer);

240                 run_command(cmd_buf, 0);

241                 break;

242             }

243             case 's':

244             {

245                 param_menu_shell();

246                 break;

247             }

248             case 'r':

249             {

250     strcpy(cmd_buf, "reset");

251     run_command(cmd_buf, 0);

252                 break;

253             }

254

255              case 'q':

256             {

257                 return;

258                  break;

259             }

260         }

261

262      }

263 }

264 int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

265 {

266     menu_shell();

267     return 0;

268 }

269 U_BOOT_CMD(

270  menu, 3, 0, do_menu,

271  "menu - display a menu, to select the items to do something\n",

272  " - display a menu, to select the items to do something"

273 );





TFTP下载




1 #include

2 #include

3

4 static char awaitkey(unsigned long delay, int* error_p)

5 {

6     int i;

7     char c;

8     if (delay == -1) {

9         while (1) {

10             if (tstc())

11                 return getc();

12         }

13     }

14     else {

15          for (i = 0; i < delay; i++) {

16       if (tstc())

17        return getc();

18             udelay (10*1000);

19         }

20     }

21     if (error_p)

22         *error_p = -1;

23     return 0;

24 }

25

26 void main_menu_usage(void)

27 {

28  printf("\r\n######## Hotips TFTP DownLoad for SMDK2440 ########\r\n");

29  printf("\r\n");

30  printf("[1] 下载 u-boot.bin       写入 Nand Flash\r\n");

31  printf("[2] 下载 Linux(uImage)    内核镜像写入 Nand Flash\r\n");

32  printf("[3] 下载 yaffs2(fs.yaffs) 文件系统镜像写入 Nand Flash\r\n");

33  printf("[4] 下载 Linux(uImage)    内核镜像到内存并运行\r\n");

34  printf("[5] 重启设备\r\n");

35  printf("[q] 退出菜单\r\n");

36  printf("\r\n");

37  printf("输入选择: ");

38 }

39

40

41 void menu_shell(void)

42 {

43     char c;

44     char cmd_buf[200];

45     while (1)

46     {

47       main_menu_usage();

48       c = awaitkey(-1, NULL);

49       printf("%c\n", c);

50       switch (c)

51       {

52   case '1':

53   {

54           strcpy(cmd_buf, "tftp 0x32000000 u-boot.bin; nand erase 0x0 0x60000; nand write 0x32000000 0x0 0x60000");

55           run_command(cmd_buf, 0);

56           break;

57   }

58         case '2':

59         {

60           strcpy(cmd_buf, "tftp 0x32000000 uImage; nand erase 0x80000 0x200000; nand write 0x32000000 0x80000 0x200000");

61           run_command(cmd_buf, 0);

62      break;

63         }

64         case '3':

65         {

66           strcpy(cmd_buf, "tftp 0x32000000 fs.yaffs; nand erase 0x280000; nand write.yaffs2 0x32000000 0x280000 $(filesize)");

67           run_command(cmd_buf, 0);

68           break;

69         }

70   case '4':

71         {

72           strcpy(cmd_buf, "tftp 0x32000000 uImage; bootm 0x32000000");

73           run_command(cmd_buf, 0);

74           break;

75         }

76   case '5':

77         {

78           strcpy(cmd_buf, "reset");

79           run_command(cmd_buf, 0);

80           break;

81         }

82         case 'q':

83         {

84           return;

85            break;

86         }

87       }

88     }

89 }

90 int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

91 {

92     menu_shell();

93     return 0;

94 }

95 U_BOOT_CMD(

96  menu, 1, 0, do_menu,

97  "Download Menu",

98  "U-boot Download Menu by Hotips\n"

99 );





对比两种下载方式我们清楚命令的添加和执行方式了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: