u-boot(四)命令實現
阿新 • • 發佈:2018-11-26
目錄
title: u-boot(四)命令實現
tags: linux
date: 2018-09-25 23:13:05
---
u-boot(四)命令實現
命令是如何實現的?
- 輸入命令
- 執行函式,根據命令去尋找函式
所以會有一個命令的結構體[name,fun]
分析run_command
函式原型如下 int run_command (const char *cmd, int flag)
處理
, 空格,;
等解析引數
parse_line (finaltoken, argv)
example: md.w 0 ------>argv[0]= "md.w", argv[1]=" 0" ``` /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } ```
命令搜尋
if ((cmdtp = find_cmd(argv[0])) == NULL)
,可以發現結構體struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ int repeatable; /* autorepeat allowed? */ /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); char *usage; /* Usage message (short) */ #ifdef CFG_LONGHELP char *help; /* Help message (long) */ #endif #ifdef CONFIG_AUTO_COMPLETE /* do auto completion on the arguments */ int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]); #endif };
- repeatable 可重複,指的是直接按回車是否繼續執行上次命令
- usage,短的help,指的是直接輸入help檢視的所有命令顯示的幫助
- help,具體的help,指的是help cmd 檢視的具體的資訊
檢視函式,可以發現是在
__u_boot_cmd_start
和__u_boot_cmd_end
中遍歷,這個地址是在連結指令碼中定義的,也就是命令這個東西,有一個特殊的屬性,定位到某個地址.. = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .;
搜尋這個段屬性
.u_boot_cmd
,在include\command.h
有這麼一個巨集#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
再搜尋下這個巨集
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \ cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
再搜尋一下這個
U_BOOT_CMD
,可以發現其實就是命令了,搜尋下命令bootm
,在common\cmd_bootm.c
中U_BOOT_CMD( bootm, CFG_MAXARGS, 1, do_bootm, "bootm - boot application image from memory\n",//注意,下面的幾個是沒有逗號,是整體 "[addr [arg ...]]\n - boot application image stored in memory\n" "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" "\t'arg' can be the address of an initrd image\n" );
嘗試著展開這個巨集,可以發現就是定義了一個段屬性特殊的結構體,也就是命令結構體
cmd_tbl_t __u_boot_cmd_bootm Struct_Section= { "bootm", CFG_MAXARGS, 1, do_bootm, "bootm - boot application image from memory\n", //下面的字串是一個整體 "[addr [arg ...]]\n - boot application image stored in memory\n" "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" "\t'arg' can be the address of an initrd image\n" }
小結
U-boot 的命令是用結構體儲存的,這些結構體是用特殊的段屬性集合到一塊區域裡面去,分散在各個檔案中
命令解析的時候是去這個段去搜索的,這個段屬性的地址是從
__u_boot_cmd_start
到__u_boot_cmd_end
,在連結指令碼中定義的.命令結構體
struct cmd_tbl_s ;
自定義一個命令
參考common/cmd_bootm.c
的標頭檔案,編寫原始碼cmd_hello.c
程式碼
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>
int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i ;
printf ("hello world %d \n,", argc);
//列印下引數
for(i=0;i<argc;i++)
{
printf ("argv[%d] is %s \n",i,argv[i]);
}
return 0;
}
U_BOOT_CMD(
hello, CFG_MAXARGS, 1, do_hello,
"this is short help for hello just test\n",
"this is long help for hello just test\n"
);
makefile
修改common
的makefile
,只需要在COBJS上加上cmd_hello.o