全部博文(65)
分类: LINUX
2009-03-04 16:52:11
/*
*By Neil Chiao (neilchiao at gmail.com)
*转载请注明出处:
*/
1)命令的编译,连接原理
U-boot连接时用的文件如:./board/sdmk2410/u-boot.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
//放各种command的地址__u_boot_cmd_start
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
在定义命令时,都会使用宏U_BOOT_CMD把命令放到__u_boot_cmd_start地址中,如./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"
" passing arguments 'arg ...'; when booting a Linux kernel,\n"
" 'arg' can be the address of an initrd image\n"
);
此宏的定义在./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}
2)U-boot命令运行原理
板子启动时,进入U-boot mode,U-boot最后进入main_loop等待输入命令。输入命令后的处理在./common/command.c文件中实现,如查找是否有输入的命令的函数find_cmd:
cmd_tbl_t *find_cmd (const char *cmd)
{
cmd_tbl_t *cmdtp;
cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;
const char *p;
int len;
int n_found = 0;
len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);
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;
n_found++;
}
}
if (n_found == 1) {
return cmdtp_temp;
}
return NULL;
}
./common/Makefile把相关命令的源文件cmd_*.c编译好,LD连接时用U_BOOT_CMD把*.o放到.u_boot_cmd段。 run_command时,find_cmd函数就到__u_boot_cmd_start和__u_boot_cmd_end之间找命令,找到后运行。
相关命令到底是哪些命令,由宏CONFIG_COMMANDS决定,如./include/configs/sdmk2410.h文件中:
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_EEPROM | \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
对于相关命令如eeprom相关命令,其实现的源文件cmd_eeprom.c根据sdmk2410.h中的CONFIG_COMMANDS宏定义来决定是否编译这个命令。
#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
……
要修改的相关文件如下:
|-- common
| |-- Makefile
| `-- cmd_test_zwx.c
`-- include
|-- cmd_confdefs.h
`-- configs
`-- sdmk2410.h
1、编写实现命令的源代码
cmd_test_zwx.c:
4 #include
5 #include
6 #include
7
8 #if (CONFIG_COMMANDS & CFG_CMD_TEST_ZWX)
9 int do_test_zwx()
10 {
11 printf("just for test!\n");
12 }
13
14 U_BOOT_CMD(
15 test-zwx,CFG_MAXARGS,1,do_test_zwx,
16 "Test program.\n"
17 );
18 #endif
2、修改common目录下的makefile
Makefile的变量COBJS中加入:cmd_test_zwx.o
3、修改cmd_confdefs.h文件
加入: #define CFG_CMD_TEST_ZWX 0x0040000000000000U
4、相关开发板的头文件中加入如kdm2440.h
123 #define CONFIG_COMMANDS \
124 (CONFIG_CMD_DFL | \
125 CFG_CMD_PING | \
126 CFG_CMD_NET | \
127 CFG_CMD_REGINFO | \
128 CFG_CMD_JFFS2 |\
129 CFG_CMD_TEST_ZWX)