arm9_uboot启动内核

在u-boot-1.1.6/common/main.c中的main_loop中

s = getenv ("bootcmd");// bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
run_command (s, 0);

在u-boot-1.1.6/common/cmd_nand.c中

 if (s != NULL &&
            (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
            if (read) {
                /* read */
                nand_read_options_t opts;
                memset(&opts, 0, sizeof(opts));
                opts.buffer = (u_char*) addr;
                opts.length = size;
                opts.offset = off;
                opts.quiet      = quiet;
                ret = nand_read_opts(nand, &opts);
            }

在u-boot-1.1.6/common/cmd_bootm.c中image_header_t *hdr = &header;

image_header_t *hdr = &header;

switch (hdr->ih_os) {
    default:            /* handled by (original) Linux case */
    case IH_OS_LINUX:
#ifdef CONFIG_SILENT_CONSOLE
        fixup_silent_linux();
#endif
        do_bootm_linux  (cmdtp, flag, argc, argv,
                 addr, len_ptr, verify);
        break;
    case IH_OS_NETBSD:
        do_bootm_netbsd (cmdtp, flag, argc, argv,
                 addr, len_ptr, verify);
        break;

我們知道内核image是由头与内核组成;头在u-boot-1.1.6/include/image.h定义;而内核加载地址0x30008000 再减去0x30007FC0刚好等于头的大小64;

#define IH_NMLEN        32    /* Image Name Length        */

/*
 * all data in network byte order (aka natural aka bigendian)
 */

typedef struct image_header {
    uint32_t    ih_magic;    /* Image Header Magic Number    */
    uint32_t    ih_hcrc;    /* Image Header CRC Checksum    */
    uint32_t    ih_time;    /* Image Creation Timestamp    */
    uint32_t    ih_size;    /* Image Data Size        */
    uint32_t    ih_load;    /* Data     Load  Address        */  //加载地址为:0x30008000
    uint32_t    ih_ep;        /* Entry Point Address        */
    uint32_t    ih_dcrc;    /* Image Data CRC Checksum    */
    uint8_t        ih_os;        /* Operating System        */
    uint8_t        ih_arch;    /* CPU architecture        */
    uint8_t        ih_type;    /* Image Type            */
    uint8_t        ih_comp;    /* Compression Type        */
    uint8_t        ih_name[IH_NMLEN];    /* Image Name        */
} image_header_t;

 而do_bootm_linux函数在u-boot-1.1.6/lib_arm/armlinux.c文件中定义

static struct tag *params;

void (*theKernel)(int zero, int arch, uint params);

image_header_t *hdr = &header;
bd_t *bd = gd->bd;

char *commandline = getenv ("bootargs"); //bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200

theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); //头结构里面的内核入口地址

setup_start_tag (bd);//设置参数
setup_serial_tag (&params);
setup_revision_tag (&params);
setup_memory_tags (bd);
setup_commandline_tag (bd, commandline);
setup_initrd_tag (bd, initrd_start, initrd_end);
setup_videolfb_tag ((gd_t *) gd);
setup_end_tag (bd);

cleanup_before_linux ();

theKernel (0, bd->bi_arch_number, bd->bi_boot_params); //启动内核;gd->bd->bi_arch_number = MACH_TYPE_S3C2440; gd->bd->bi_boot_params = 0x30000100

static void setup_start_tag (bd_t *bd)//随便拎出几个设置函数看一下
{
params = (struct tag *) bd->bi_boot_params; //;//这就是参数保存的起始地址

params->hdr.tag = ATAG_CORE; //#define ATAG_CORE 0x54410001
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 (bd_t *bd)
{
int i;

for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM; //#define ATAG_MEM 0x54410002
params->hdr.size = tag_size (tag_mem32);

params->u.mem.start = bd->bi_dram[i].start; //0x30000000 /* SDRAM Bank #1 */
params->u.mem.size = bd->bi_dram[i].size;  //0x04000000 /* 64 MB */

params = tag_next (params);
}
}

static void setup_commandline_tag (bd_t *bd, char *commandline)
{
char *p;

if (!commandline)
return;

/* eat leading white space */
for (p = commandline; *p == ' '; p++);

/* skip non-existent command lines so the kernel will still
* use its default command line.
*/
if (*p == '\0')
return;

params->hdr.tag = ATAG_CMDLINE; //#define ATAG_CMDLINE 0x54410003
params->hdr.size =
(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;

strcpy (params->u.cmdline.cmdline, p);

params = tag_next (params);
}

static void setup_end_tag (bd_t *bd)
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}

在u-boot-1.1.6/include/asm/u-boot.h文件中,定义了存储u-boot启动项结构体bd_t

typedef struct bd_info {
    int            bi_baudrate;    /* serial console baudrate */
    unsigned long    bi_ip_addr;    /* IP Address */
    unsigned char    bi_enetaddr[6]; /* Ethernet adress */
    struct environment_s           *bi_env;
    ulong            bi_arch_number;    /* unique id for this board */
    ulong            bi_boot_params;    /* where this board expects params */
    struct                /* RAM configuration */
    {
    ulong start;
    ulong size;
    }             bi_dram[CONFIG_NR_DRAM_BANKS];
#ifdef CONFIG_HAS_ETH1
    /* second onboard ethernet port */
    unsigned char   bi_enet1addr[6];
#endif
} bd_t;

在u-boot-1.1.6/include/asm-arm/setup.h中定义了u-boot传递给内核的参数的结构体

struct tag {
    struct tag_header hdr;
    union {
        struct tag_core        core;
        struct tag_mem32    mem;
        struct tag_videotext    videotext;
        struct tag_ramdisk    ramdisk;
        struct tag_initrd    initrd;
        struct tag_serialnr    serialnr;
        struct tag_revision    revision;
        struct tag_videolfb    videolfb;
        struct tag_cmdline    cmdline;

        /*
         * Acorn specific
         */
        struct tag_acorn    acorn;

        /*
         * DC21285 specific
         */
        struct tag_memclk    memclk;
    } u;
};

struct tag_header {
u32 size;
u32 tag;
};

 
 

 

转载于:https://www.cnblogs.com/lzd626/p/11567001.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值