u-boot-1.1.6 TQ2440
因为/common/cmd_bootm.c支持的是启动uImage,而我使用的是zImage,所以决定该写一个可以支持zImage的命令。
u-boot启动过程三步:
1.拷贝内核到SDRAM指定地址(0x30008000)
2.设置传递给linux的参数(0x30000100)
3.跳转到linux内核首地址
在common/下新建boot_zImage.c,并在common/Makefile cobj添加boot_zImage.o,文件内容如下:
#include <common.h>
#include <command.h>
#include <def.h>
#include <image.h>
#include <zlib.h>
#include <asm/byteorder.h>
#include <s3c2410.h>
#include "asm-arm/mach-types.h"
static struct tag *params;
extern int nand_read_ll_lp(unsigned char *, unsigned long , int );
static void setup_start_tag(void)//设置起始标记
{
params = (struct tag *)0x30000100;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size(tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next(params);
}
static void setup_memory_tags(void)//设置内存标记
{
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size(tag_mem32);
params->u.mem.start = 0x30000000;
params->u.mem.size = 64*1024*1024;
params = tag_next(params);
}
static void setup_commandline_tag(char *cmdline)//设置命令行标记
{
int len = strlen(cmdline) + 1;
params->hdr.tag = ATAG_CMDLINE;
params->hdr.size = (sizeof (struct tag_header) + len + 3) >> 2;
strcpy (params->u.cmdline.cmdline, cmdline);
params = tag_next(params);
}
static void setup_end_tag(void)//设置结束标记
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}
static void do_boot_zImage(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
nand_read_ll_lp((unsigned char *)0x30008000,(unsigned long)0x200000, (int)0x300000);//拷贝内核到内存
void (*theKernel)(int zero, int arch, unsigned int params);//定义一个函数指针
setup_start_tag();//设置传递给内核参数起始标记
setup_memory_tags();//设置传递给内核参数内存标记
setup_commandline_tag("noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0");//设置传递给内核参数命令行标记
setup_end_tag();//设置传递给内核参数结束标记
theKernel = (void (*)(int, int, unsigned int))0x30008000;//函数指针指向内核
theKernel(0, 168, 0x30000100);//函数指针跳转到内核--第二个参数是机器码 第三个参数是内核参数起始地址
}
U_BOOT_CMD(boot_zImage,3,0,do_boot_zImage,"boot_zImage- boot Linux 's zImage\n"," - boot Linux 's zImage");
这样我们再u-boot的命令行,可以输入boot_zImage来实现启动zImage内核,也可以把环境变量bootcmd设置为boot_zImage来实现超时自启动。