zoukankan      html  css  js  c++  java
  • uboot加载内核

    1.bootcmd:这个参数包含了一些命令,这些命令将在u-boot进入主循环后执行示例:

           bootcmd=boot_logo;nand read 10000003c0000 300000;bootm          //需要注意的是在bootcmd变量的最后添加了bootm命令。

           意思是启动u-boot后,执行boot_logo显示logo信息,然后从nand flash中读内核映像到内存,然后启动内核。

    2.bootargs这个参数设置要传递给内核的信息,主要用来告诉内核分区信息和根文件系统所在的分区。示例:

           root=/dev/mtdblock5 rootfstype=jffs2console=ttyS0,115200 mem=35M mtdparts=nand.0:3840k(u-boot),4096k(kernel),123136k(filesystem)

           其中:

           root=/dev/mtdblock5 表示根文件系统在第五分区

           rootfstype=jffs2 表示根文件系统的类型是jffs2

           console=ttyS0,115200 表示终端为ttyS0,串口波特率为115200

           mem=35M 表示内存大小为35M

           mtdparts告诉内核MTD分区情况

    超时之前用户没有输入,uboot就会自动加载linux内核,其加载时将使用变量“bootcmd”和 “bootargs”,其值可以在在加载linux内核前在uboot的命令行中进行修改。

    在main_loop()函数中,执行了"bootcmd" 所定义的命令bootm,bootm命令执行过程中调用了bootm_start函数:

    common/cmd_bootm.c:

    static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
        void        *os_hdr;
        int        ret;
    
        memset ((void *)&images, 0, sizeof (images));
        images.verify = getenv_yesno ("verify");
    
        bootm_start_lmb();
    
        /* get kernel image header, start address and length  寻找可用的内核镜像*/
        os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,                 
                &images, &images.os.image_start, &images.os.image_len);   //返回指向内存中镜像头指针
        if (images.os.image_len == 0) {
            puts ("ERROR: can't get kernel image!
    ");
            return 1;
        }
    
        /* get image parameters */
        switch (genimg_get_format (os_hdr)) {
        case IMAGE_FORMAT_LEGACY:
            images.os.type = image_get_type (os_hdr);       //镜像类型
            images.os.comp = image_get_comp (os_hdr);       //压缩类型
            images.os.os = image_get_os (os_hdr);           //操作系统类型 
            images.os.end = image_get_image_end (os_hdr);   //当前镜像的尾地址  
            images.os.load = image_get_load (os_hdr);       //镜像数据的载入地址
            break;
    #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
            if (fit_image_get_type (images.fit_hdr_os,
                        images.fit_noffset_os, &images.os.type)) {
                puts ("Can't get image type!
    ");
                show_boot_progress (-109);
                return 1;
            }
    
            if (fit_image_get_comp (images.fit_hdr_os,
                        images.fit_noffset_os, &images.os.comp)) {
                puts ("Can't get image compression!
    ");
                show_boot_progress (-110);
                return 1;
            }
    
            if (fit_image_get_os (images.fit_hdr_os,
                        images.fit_noffset_os, &images.os.os)) {
                puts ("Can't get image OS!
    ");
                show_boot_progress (-111);
                return 1;
            }
    
            images.os.end = fit_get_end (images.fit_hdr_os);
    
            if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
                        &images.os.load)) {
                puts ("Can't get image load address!
    ");
                show_boot_progress (-112);
                return 1;
            }
            break;
    #endif
        default:
            puts ("ERROR: unknown image format type!
    ");
            return 1;
        }
    
        /* find kernel entry point */
        if (images.legacy_hdr_valid) {
            images.ep = image_get_ep (&images.legacy_hdr_os_copy);
    #if defined(CONFIG_FIT)
        } else if (images.fit_uname_os) {
            ret = fit_image_get_entry (images.fit_hdr_os,
                    images.fit_noffset_os, &images.ep);
            if (ret) {
                puts ("Can't get entry point property!
    ");
                return 1;
            }
    #endif
        } else {
            puts ("Could not find kernel entry point!
    ");
            return 1;
        }
    
        if (((images.os.type == IH_TYPE_KERNEL) ||
             (images.os.type == IH_TYPE_MULTI)) &&
            (images.os.os == IH_OS_LINUX)) {
            /* find ramdisk */
            ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
                    &images.rd_start, &images.rd_end);
            if (ret) {
                puts ("Ramdisk image is corrupt or invalid
    ");
                return 1;
            }
    
    #if defined(CONFIG_OF_LIBFDT)
    #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
            /* find flattened device tree */
            ret = boot_get_fdt (flag, argc, argv, &images,
                        &images.ft_addr, &images.ft_len);
            if (ret) {
                puts ("Could not find a valid device tree
    ");
                return 1;
            }
    
            set_working_fdt_addr(images.ft_addr);
    #endif
    #endif
        }
    
        images.os.start = (ulong)os_hdr;       //指向内存中镜像的头地址
        images.state = BOOTM_STATE_START;
    
        return 0;
    }

    接下来:

    //寻找内核映像、校验它的完整性和定位内核数据位置

    static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],bootm_headers_t *images, ulong *os_data, ulong *os_len){...}

    //校验早期格式内核映像

    static image_header_t *image_get_kernel (ulong img_addr, int verify){...}

    /* bootm - boot application image from image in memory引导应用程序在内存中的镜像 */
    int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

    {

    ...

     ret = bootm_load_os(images.os, &load_end, 1);  //将镜像的数据从images.os.image_start复制到images.os.load  打印:Loading Kernel Image ... OK 

    ...

    boot_fn = boot_os[images.os.os];  //根据操作系统的类型获取引导操作系统的函数

    ...

    }

    lib_arm/bootm.c:

    int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
    {
        bd_t    *bd = gd->bd;
        char    *s;
        int    machid = bd->bi_arch_number;
        void    (*theKernel)(int zero, int arch, uint params);
    
    #ifdef CONFIG_CMDLINE_TAG
        char *commandline = getenv ("bootargs");        //获取bootargs环境变量。
    #endif
    
        if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
            return 1;
    
        theKernel = (void (*)(int, int, uint))images->ep;
    
        s = getenv ("machid");
        if (s) {
            machid = simple_strtoul (s, NULL, 16);
            printf ("Using machid 0x%x from environment
    ", machid);
        }
    
        show_boot_progress (15);
    
        debug ("## Transferring control to Linux (at address %08lx) ...
    ",
               (ulong) theKernel);
    
    #if defined (CONFIG_SETUP_MEMORY_TAGS) || 
        defined (CONFIG_CMDLINE_TAG) || 
        defined (CONFIG_INITRD_TAG) || 
        defined (CONFIG_SERIAL_TAG) || 
        defined (CONFIG_REVISION_TAG) || 
        defined (CONFIG_LCD) || 
        defined (CONFIG_VFD)
        setup_start_tag (bd);
    #ifdef CONFIG_SERIAL_TAG
        setup_serial_tag (&params);
    #endif
    #ifdef CONFIG_REVISION_TAG
        setup_revision_tag (&params);
    #endif
    #ifdef CONFIG_SETUP_MEMORY_TAGS
        setup_memory_tags (bd);
    #endif
    #ifdef CONFIG_CMDLINE_TAG
        setup_commandline_tag (bd, commandline);      //将bootargs传给tag
    #endif
    #ifdef CONFIG_INITRD_TAG
        if (images->rd_start && images->rd_end)
            setup_initrd_tag (bd, images->rd_start, images->rd_end);
    #endif
    #if defined (CONFIG_VFD) || defined (CONFIG_LCD)
        setup_videolfb_tag ((gd_t *) gd);
    #endif
        setup_end_tag (bd);
    #endif
    
        /* we assume that the kernel is in place */
        printf ("
    Starting kernel ...
    
    ");
    
    #ifdef CONFIG_USB_DEVICE
        {
            extern void udc_disconnect (void);
            udc_disconnect ();
        }
    #endif
    
        cleanup_before_linux ();
    
        theKernel (0, machid, bd->bi_boot_params);       //执行内核代码
        /* does not return */
    
        return 1;
    }

    完毕!

  • 相关阅读:
    Best Time to Buy and Sell Stock III
    Valid Palindrome
    Longest Substring Without Repeating Characters
    Copy List with Random Pointer
    Add Two Numbers
    Recover Binary Search Tree
    Anagrams
    ZigZag Conversion
    Merge k Sorted Lists
    Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4253944.html
Copyright © 2011-2022 走看看