1》从源码分析
目录u-boot-1.1.6\common\command.c
下的源码:
for (cmdtp = &__u_boot_cmd_start;
cmdtp != &__u_boot_cmd_end;
cmdtp++) {
if (strncmp (cmd, cmdtp->name, len) == 0) {
if (len == strlen (cmdtp->name))
return cmdtp; /* full match */
cmdtp_temp = cmdtp; /* abbreviated command ? */
n_found++;
}
}
从__u_boot_cmd_start和__u_boot_cmd_end找到文件u-boot.lds中:
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
找到u_boot_cmd段
进一步找到:路径u-boot-1.1.6\include\command.h
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
从cmdtp
找到结构体的定义:
cmd_tbl_t *cmdtp;
cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start; /*Init value */
2》串口打印处的启动命令
bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
改为
nand read.jffs2 0x30007FC0 kernel; //从nand读出内核到0x30007FC0
bootm 0x30007FC0 //从0x30007FC0启动内核
3》搜索命令 bootm 找到:
在目录\u-boot-1.1.6\common\cmd_bootm.c中
找到一个宏U_BOOT_CMD定义内容:
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"
#ifdef CONFIG_OF_FLAT_TREE
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
#endif
);
搜索U_BOOT_CMD 找到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宏,如下:
name=bootm
Struct_Section=__attribute__ ((unused,section (".u_boot_cmd")))={#name, maxargs, rep, cmd, usage, help}
由此分析:
cmd_tbl_t __u_boot_cmd_bootm Struct_Section = __attribute__ ((unused,section (".u_boot_cmd")))={#name, maxargs, rep, cmd, usage, help}
//定义了一个cmd_tbl_t类型的结构体 __u_boot_cmd_bootm
//对结构体__u_boot_cmd_bootm强制段属性:.u_boot_cmd
//这样就和u-boot.lds文件中的
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
//对应起来
cmd_tbl_t __u_boot_cmd_bootm Struct_Section = __attribute__ ((unused,section (".u_boot_cmd")))=
{#name, maxargs, rep, cmd, usage, help}
{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"
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
//name=bootm
//maxargs=CFG_MAXARGS 最大参数
//rep=1 是否重复
//cmd=do_bootm
//usage="bootm - boot application image from memory\n"
//help=...
由以上的分析==>
//代码中所有用U_BOOT_CMD这个宏定义的参数,最终都会生成一个
//cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
//所以U_BOOT_CMD定义的命令最终都会通过u-boot.lds链接到内存中的
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
//段内。
实验增加一个命令hello 执行打印一个helloworld:
仿照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_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
改为
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<argv,i++)
{
printf ("#argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
U_BOOT_CMD(
hello, CFG_MAXARGS, 1, do_hello,
"hello - just for test hello \n",
"hello,long help.........................\n"
);
将cmd_hello.c拷贝到u-boot-1.1.6\common\目录下
修改common目录下的Makefile
virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_suspend.o cmd_hello.o
编译:
make disclean
make 100ask24x0_config
make