Sunday, February 21, 2010

Adding new U-Boot commands

U-Boot providing interactive commands to end user but it may be necessary to add extra commands. There is a standard command interface
and it is defined in include/command.h. Every command defined a cmd_tbl_t structure.

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}

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 CONFIG_SYS_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
};

The command structure defined the name of the command, max number of the arguments, autorepeat, implementation function, usage and help.

The command console is defined in common/command.c. The find_cmd() is used to match the correspnding command function.

Below is an example to show how to read the cpu id.

#define read_cpuid(reg) \
({ \
unsigned int __val; \
asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \
: "=r" (__val) \
: \
: "cc"); \
__val; \
})

int do_cpuid(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
printf("cpu id: %x\n", read_cpuid(0));
printf("cache type: %x\n", read_cpuid(1));
printf("chip id: %x\n", *(volatile unsigned int *)0xd4282c00);
return 0;
}

U_BOOT_CMD(
cpuid, 6, 1, do_cpuid,
"cpuid - read cpu id\n",
" - read cpu id\n"
);