Uboot-1.1.2 之bootm命令定义
2008-09-09 09:02
399 查看
bootm命令宏定义如下:
U_BOOT_CMD(
bootm, CFG_MAXARGS, 1, do_bootm,
"bootm - boot application image from memoryn",
"[addr [arg ...]]n - boot application image stored in memoryn"
"tpassing arguments 'arg ...'; when booting a Linux kernel,n"
"t'arg' can be the address of an initrd imagen"
);
该命令的执行函数是do_bootm函数,参数最大数量为CFG_MAXARGS(一般16)个。
5.2.2 do_bootm函数源码分析
ulong load_addr = CFG_LOAD_ADDR;
// 默认加载地址, 如果用户没有指定地址就使用这个
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong iflag;
ulong addr;
ulong data, len, checksum;
ulong *len_ptr;
uint unc_len = 0x400000;
int i, verify;
char *name, *s;
int (*appl)(int, char *[]);
image_header_t *hdr = &header;
s = getenv ("verify"); // 检查是否需要校验计算
verify = (s && (*s == 'n')) ? 0 : 1;
if (argc < 2) { // 启动参数数量<2
addr = load_addr; // 如果没有提供加载地址则直接使用预定义的地址
} else {
addr = simple_strtoul(argv[1], NULL, 16); // 取得设定的地址CFG_LOAD_ADDR
}
SHOW_BOOT_PROGRESS (1); // 第一阶段
printf ("## Booting image at %08lx ...n", addr); // 显示启动地址
// 从加载地址处拷贝image_header_t结构体数据到header中, 用于计算头部校验
memmove (&header, (char *)addr, sizeof(image_header_t));
if (ntohl(hdr->ih_magic) != IH_MAGIC) { // 检查摩数值是否符合要求
puts ("Bad Magic Numbern");
SHOW_BOOT_PROGRESS (-1);
return 1;
}
SHOW_BOOT_PROGRESS (2); // 第二阶段
data = (ulong)&header; // 接下来对image_header_t头进行校验
len = sizeof(image_header_t);
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0; // 先将CRC校验数据清零
// 将计算得到的校验值与原校验值比较, 相等则通过
if (crc32 (0, (char *)data, len) != checksum) {
puts ("Bad Header Checksumn");
SHOW_BOOT_PROGRESS (-2);
return 1;
}
SHOW_BOOT_PROGRESS (3); // 第三阶段
/* for multi-file images we need the data part, too */
print_image_hdr ((image_header_t *)addr); // 打印映像文件头部信息
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
if (verify) { // 接下来对数据进行校验(如果需要)
puts (" Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRCn");
SHOW_BOOT_PROGRESS (-3);
return 1;
}
puts ("OKn");
}
SHOW_BOOT_PROGRESS (4); // 第四阶段
len_ptr = (ulong *)data;
if (hdr->ih_arch != IH_CPU_ARM) { // 检查代码是否符合本机的架构(ARM)
printf ("Unsupported Architecture 0x%xn", hdr->ih_arch);
SHOW_BOOT_PROGRESS (-4);
return 1;
}
SHOW_BOOT_PROGRESS (5); // 第五阶段
switch (hdr->ih_type) { // 代码的类型
case IH_TYPE_STANDALONE: // 标准的可执行程序
name = "Standalone Application";
/* A second argument overwrites the load address */
if (argc > 2) {
hdr->ih_load = simple_strtoul(argv[2], NULL, 16);
}
break;
case IH_TYPE_KERNEL: // 内核映像
name = "Kernel Image"; // 对应引导linux内核来说就是这个
break;
case IH_TYPE_MULTI:
name = "Multi-File Image";
len = ntohl(len_ptr[0]);
/* OS kernel is always the first image */
data += 8; /* kernel_len + terminator */
for (i=1; len_ptr[i]; ++i)
data += 4;
break;
default: printf ("Wrong Image Type for %s commandn", cmdtp->name);
SHOW_BOOT_PROGRESS (-5);
return 1;
}
SHOW_BOOT_PROGRESS (6); // 第六阶段
iflag = disable_interrupts();
switch (hdr->ih_comp) { // 压缩类型判定, 解压到指定的地址
case IH_COMP_NONE:
if(ntohl(hdr->ih_load) == addr) {
printf (" XIP %s ... ", name);
} else {
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
}
break;
case IH_COMP_GZIP: // gzip压缩
printf (" Uncompressing %s ... ", name);
// 执行解压到加载地址
if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
(uchar *)data, &len) != 0) {
puts ("GUNZIP ERROR - must RESET board to recovern");
SHOW_BOOT_PROGRESS (-6);
do_reset (cmdtp, flag, argc, argv);
}
break;
#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2: // bzip2格式的压缩文件
printf (" Uncompressing %s ... ", name);
i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
&unc_len, (char *)data, len,
CFG_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf ("BUNZIP2 ERROR %d - must RESET board to recovern", i);
SHOW_BOOT_PROGRESS (-6);
udelay(100000);
do_reset (cmdtp, flag, argc, argv);
}
break;
#endif /* CONFIG_BZIP2 */
default:
if (iflag)
enable_interrupts();
printf ("Unimplemented compression type %dn", hdr->ih_comp);
SHOW_BOOT_PROGRESS (-7);
return 1;
}
puts ("OKn");
SHOW_BOOT_PROGRESS (7); // 第七阶段
switch (hdr->ih_type) { // 再次检查代码类型, 用于启动
case IH_TYPE_STANDALONE: // 如果是标准应用程序
if (iflag)
enable_interrupts();
// 加载文件, 但是如果环境变量中autostart=no则不启动程序
if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {
char buf[32];
sprintf(buf, "%lX", len);
setenv("filesize", buf);
return 0;
}
appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep); // 执行应用程序
(*appl)(argc-1, &argv[1]);
return 0;
case IH_TYPE_KERNEL: // 内核映像文件在下面执行
case IH_TYPE_MULTI:
break;
default:
if (iflag)
enable_interrupts();
printf ("Can't boot image type %dn", hdr->ih_type);
SHOW_BOOT_PROGRESS (-8);
return 1;
}
SHOW_BOOT_PROGRESS (8); // 第七阶段
switch (hdr->ih_os) { // 检查操作系统类型
default: /* handled by (original) Linux case */
case IH_OS_LINUX: // linux则调用do_bootm_linux执行
do_bootm_linux (cmdtp, flag, argc, argv,
addr, len_ptr, verify);
break;
…
}
SHOW_BOOT_PROGRESS (-9);
return 1;
}
U_BOOT_CMD(
bootm, CFG_MAXARGS, 1, do_bootm,
"bootm - boot application image from memoryn",
"[addr [arg ...]]n - boot application image stored in memoryn"
"tpassing arguments 'arg ...'; when booting a Linux kernel,n"
"t'arg' can be the address of an initrd imagen"
);
该命令的执行函数是do_bootm函数,参数最大数量为CFG_MAXARGS(一般16)个。
5.2.2 do_bootm函数源码分析
ulong load_addr = CFG_LOAD_ADDR;
// 默认加载地址, 如果用户没有指定地址就使用这个
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong iflag;
ulong addr;
ulong data, len, checksum;
ulong *len_ptr;
uint unc_len = 0x400000;
int i, verify;
char *name, *s;
int (*appl)(int, char *[]);
image_header_t *hdr = &header;
s = getenv ("verify"); // 检查是否需要校验计算
verify = (s && (*s == 'n')) ? 0 : 1;
if (argc < 2) { // 启动参数数量<2
addr = load_addr; // 如果没有提供加载地址则直接使用预定义的地址
} else {
addr = simple_strtoul(argv[1], NULL, 16); // 取得设定的地址CFG_LOAD_ADDR
}
SHOW_BOOT_PROGRESS (1); // 第一阶段
printf ("## Booting image at %08lx ...n", addr); // 显示启动地址
// 从加载地址处拷贝image_header_t结构体数据到header中, 用于计算头部校验
memmove (&header, (char *)addr, sizeof(image_header_t));
if (ntohl(hdr->ih_magic) != IH_MAGIC) { // 检查摩数值是否符合要求
puts ("Bad Magic Numbern");
SHOW_BOOT_PROGRESS (-1);
return 1;
}
SHOW_BOOT_PROGRESS (2); // 第二阶段
data = (ulong)&header; // 接下来对image_header_t头进行校验
len = sizeof(image_header_t);
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0; // 先将CRC校验数据清零
// 将计算得到的校验值与原校验值比较, 相等则通过
if (crc32 (0, (char *)data, len) != checksum) {
puts ("Bad Header Checksumn");
SHOW_BOOT_PROGRESS (-2);
return 1;
}
SHOW_BOOT_PROGRESS (3); // 第三阶段
/* for multi-file images we need the data part, too */
print_image_hdr ((image_header_t *)addr); // 打印映像文件头部信息
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
if (verify) { // 接下来对数据进行校验(如果需要)
puts (" Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRCn");
SHOW_BOOT_PROGRESS (-3);
return 1;
}
puts ("OKn");
}
SHOW_BOOT_PROGRESS (4); // 第四阶段
len_ptr = (ulong *)data;
if (hdr->ih_arch != IH_CPU_ARM) { // 检查代码是否符合本机的架构(ARM)
printf ("Unsupported Architecture 0x%xn", hdr->ih_arch);
SHOW_BOOT_PROGRESS (-4);
return 1;
}
SHOW_BOOT_PROGRESS (5); // 第五阶段
switch (hdr->ih_type) { // 代码的类型
case IH_TYPE_STANDALONE: // 标准的可执行程序
name = "Standalone Application";
/* A second argument overwrites the load address */
if (argc > 2) {
hdr->ih_load = simple_strtoul(argv[2], NULL, 16);
}
break;
case IH_TYPE_KERNEL: // 内核映像
name = "Kernel Image"; // 对应引导linux内核来说就是这个
break;
case IH_TYPE_MULTI:
name = "Multi-File Image";
len = ntohl(len_ptr[0]);
/* OS kernel is always the first image */
data += 8; /* kernel_len + terminator */
for (i=1; len_ptr[i]; ++i)
data += 4;
break;
default: printf ("Wrong Image Type for %s commandn", cmdtp->name);
SHOW_BOOT_PROGRESS (-5);
return 1;
}
SHOW_BOOT_PROGRESS (6); // 第六阶段
iflag = disable_interrupts();
switch (hdr->ih_comp) { // 压缩类型判定, 解压到指定的地址
case IH_COMP_NONE:
if(ntohl(hdr->ih_load) == addr) {
printf (" XIP %s ... ", name);
} else {
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
}
break;
case IH_COMP_GZIP: // gzip压缩
printf (" Uncompressing %s ... ", name);
// 执行解压到加载地址
if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
(uchar *)data, &len) != 0) {
puts ("GUNZIP ERROR - must RESET board to recovern");
SHOW_BOOT_PROGRESS (-6);
do_reset (cmdtp, flag, argc, argv);
}
break;
#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2: // bzip2格式的压缩文件
printf (" Uncompressing %s ... ", name);
i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
&unc_len, (char *)data, len,
CFG_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf ("BUNZIP2 ERROR %d - must RESET board to recovern", i);
SHOW_BOOT_PROGRESS (-6);
udelay(100000);
do_reset (cmdtp, flag, argc, argv);
}
break;
#endif /* CONFIG_BZIP2 */
default:
if (iflag)
enable_interrupts();
printf ("Unimplemented compression type %dn", hdr->ih_comp);
SHOW_BOOT_PROGRESS (-7);
return 1;
}
puts ("OKn");
SHOW_BOOT_PROGRESS (7); // 第七阶段
switch (hdr->ih_type) { // 再次检查代码类型, 用于启动
case IH_TYPE_STANDALONE: // 如果是标准应用程序
if (iflag)
enable_interrupts();
// 加载文件, 但是如果环境变量中autostart=no则不启动程序
if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {
char buf[32];
sprintf(buf, "%lX", len);
setenv("filesize", buf);
return 0;
}
appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep); // 执行应用程序
(*appl)(argc-1, &argv[1]);
return 0;
case IH_TYPE_KERNEL: // 内核映像文件在下面执行
case IH_TYPE_MULTI:
break;
default:
if (iflag)
enable_interrupts();
printf ("Can't boot image type %dn", hdr->ih_type);
SHOW_BOOT_PROGRESS (-8);
return 1;
}
SHOW_BOOT_PROGRESS (8); // 第七阶段
switch (hdr->ih_os) { // 检查操作系统类型
default: /* handled by (original) Linux case */
case IH_OS_LINUX: // linux则调用do_bootm_linux执行
do_bootm_linux (cmdtp, flag, argc, argv,
addr, len_ptr, verify);
break;
…
}
SHOW_BOOT_PROGRESS (-9);
return 1;
}
相关文章推荐
- uboot 命令分析(一) — bootm
- uboot 命令分析(一) — bootm
- Uboot-1.1.2 for PXA270源码分析-do_bootm_linux函数源码分析[转]
- uboot下用do_run()函数来执行U_BOOT_CMD定义的命令
- uboot之bootm以及go命令的实现
- uboot 命令分析(一) — bootm
- uboot使用bootm启动内核命令
- uboot之bootm命令分析
- uboot 命令分析(一) — bootm
- uboot 命令分析(一) — bootm
- uboot命令之bootm详解
- Uboot通过bootm命令向内核传递MAC地址
- uboot 命令分析(一) — bootm
- Uboot-1.1.2 do_bootm_linux函数源码分析
- uboot引导linux内核命令bootm
- Uboot通过bootm命令向内核传递MAC地址
- uboot 的命令定义注意点,u-boot, cfg_cmd,cmd_confdefs.h
- 嵌入式 uboot命令及内核启动参数
- uboot基本命令详解
- Apacheserver自己定义404页面的两种方法以及.htaccess的重要命令总结