首页 > 系统相关 >Uboot启动Linux内核

Uboot启动Linux内核

时间:2024-03-21 15:33:54浏览次数:28  
标签:BOOTM Uboot image bootm STATE 内核 Linux images os

参考资料来源: https://www.bilibili.com/video/BV12E411h71h?p=22&vd_source=432ba293ecfc949a4174ab91ccc526d6 正点原子Linux驱动开发指南  

image全局变量:

在bootm.c中,存在一个全局变量
bootm_headers_t images;         /* pointers to os/initrd/fdt images */
结构体定义如下:
image全局变量:
在bootm.c中,存在一个全局变量
bootm_headers_t images;         /* pointers to os/initrd/fdt images */
结构体定义如下:
 typedef struct image_info {
         ulong           start, end;             /* start/end of blob */
         ulong           image_start, image_len; /* start of image within blob, len of image */
         ulong           load;                   /* load addr for the image */
         uint8_t         comp, type, os;         /* compression, type of image, os type */
         uint8_t         arch;                   /* CPU architecture */
 } image_info_t;

   /*
  * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
  * routines.
  */
 typedef struct bootm_headers {
         /*
          * Legacy os image header, if it is a multi component image
          * then boot_get_ramdisk() and get_fdt() will attempt to get
          * data from second and third component accordingly.
          */
         image_header_t  *legacy_hdr_os;         /* image header pointer */
         image_header_t  legacy_hdr_os_copy;     /* header copy */
         ulong           legacy_hdr_valid;

 #if defined(CONFIG_FIT)
         const char      *fit_uname_cfg; /* configuration node unit name */

         void            *fit_hdr_os;    /* os FIT image header */
         const char      *fit_uname_os;  /* os subimage node unit name */
         int             fit_noffset_os; /* os subimage node offset */

         void            *fit_hdr_rd;    /* init ramdisk FIT image header */
         const char      *fit_uname_rd;  /* init ramdisk subimage node unit name */
         int             fit_noffset_rd; /* init ramdisk subimage node offset */

         void            *fit_hdr_fdt;   /* FDT blob FIT image header */
         const char      *fit_uname_fdt; /* FDT blob subimage node unit name */
         int             fit_noffset_fdt;/* FDT blob subimage node offset */

         void            *fit_hdr_setup; /* x86 setup FIT image header */
         const char      *fit_uname_setup; /* x86 setup subimage node name */
         int             fit_noffset_setup;/* x86 setup subimage node offset */
 #endif

 #ifndef USE_HOSTCC
         image_info_t    os;             /* os image info */
         ulong           ep;             /* entry point of OS */

         ulong           rd_start, rd_end;/* ramdisk start/end */

         char            *ft_addr;       /* flat dev tree address */
         ulong           ft_len;         /* length of flat device tree */

         ulong           initrd_start;
         ulong           initrd_end;
         ulong           cmdline_start;
         ulong           cmdline_end;
         bd_t            *kbd;
 #endif
         int             verify;         /* getenv("verify")[0] != 'n' */

 #define BOOTM_STATE_START       (0x00000001)
 #define BOOTM_STATE_FINDOS      (0x00000002)
 #define BOOTM_STATE_FINDOTHER   (0x00000004)
 #define BOOTM_STATE_LOADOS      (0x00000008)
 #define BOOTM_STATE_RAMDISK     (0x00000010)
 #define BOOTM_STATE_FDT         (0x00000020)
 #define BOOTM_STATE_OS_CMDLINE  (0x00000040)
 #define BOOTM_STATE_OS_BD_T     (0x00000080)
 #define BOOTM_STATE_OS_PREP     (0x00000100)
 #define BOOTM_STATE_OS_FAKE_GO  (0x00000200)    /* 'Almost' run the OS */
 #define BOOTM_STATE_OS_GO       (0x00000400)
         int             state;

 #ifdef CONFIG_LMB
         struct lmb      lmb;            /* for memory mgmt */
 #endif
 } bootm_headers_t;
imx6ull的zImage地址0x80800000,dtb地址为0x83000000  

bootz命令的执行流程:

 int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
         int ret;

         /* Consume 'bootz' */
         argc--; argv++;

         if (bootz_start(cmdtp, flag, argc, argv, &images))
                 return 1;

         /*
          * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
          * disable interrupts ourselves
          */
         bootm_disable_interrupts();

         images.os.os = IH_OS_LINUX;
         ret = do_bootm_states(cmdtp, flag, argc, argv,
                               BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
                               BOOTM_STATE_OS_GO,
                               &images, 1);

         return ret;
 }
  bootz执行流程:
bootz
    ->bootz_start
        ->do_bootm_states ->执行BOOTM_STATE_START阶段
            ->bootm_start 对images全局变量清零
        ->images->ep = 0x80800000
        ->bootz_setup 判断zImage是否符合要求
        ->bootm_find_images
            ->boot_get_fdt    找到设备树,然后将设备树起始地址和长度,写入到images的ft_addr和ft_len成员变量中
    ->bootm_disable_interrupts    关闭中断
    ->do_bootm_states    根据不同的BOOT状态执行不同的代码段
        ->bootm_os_get_boot_func    查找linux启动函数。找到linux内核启动函数,赋值给boot_fn
            ->do_bootm_linux
                ->boot_prep_linux    启动之前的一些工作,bootargs传给linux kernel
                ->boot_jump_linux
                    ->announce_and_cleanup    Starting kernel
                    ->kernel_entry    调用zImage里面的0x80800000处的函数
 

boot_jump_linux函数:

 static void boot_jump_linux(bootm_headers_t *images, int flag) {
 ...
         if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {    // 使用设备树
                 r0 = 2;
                 r2 = (unsigned int)images->ft_addr;
         } else {
                 r0 = 1;
                 r2 = (unsigned int)getenv("bootargs");
         }

         smp_set_core_boot_addr((unsigned long)kernel_entry, -1);
         smp_kick_all_cpus();

         if (!fake)
                 kernel_entry(r0, 0, r2);    // 使用设备树的情况下,r2表示设备树的起始地址
...  
}   
 

总体流程图:

0  

标签:BOOTM,Uboot,image,bootm,STATE,内核,Linux,images,os
From: https://www.cnblogs.com/lethe1203/p/18087503

相关文章

  • QGIS编译(跨平台编译)056:PDAL编译(Windows、Linux、MacOS环境下编译)
    点击查看专栏目录文章目录1、PDAL介绍2、PDAL下载3、Windows下编译4、linux下编译5、MacOS下编译1、PDAL介绍  PDAL(PointDataAbstractionLibrary)是一个开源的地理空间数据处理库,它专注于点云数据的获取、处理和分析。PDAL提供了丰富的工具和库,用于处理......
  • Linux安装Nacos
    1,先安装jdk,nacos需要依赖于jdk2,官网前往GitHub下载安装包官网:https://nacos.io/zh-cn/GitHub:https://github.com/alibaba/nacos12 3,创建nacos目录,并上传 4,解压压缩包,并查看tar-zxvfnacos包名1 5,编辑配置文件,修改端口#进入nacos配置文件目录cd/opt/nacos/conf#编辑naco......
  • linux centos使用rz、sz命令上传下载文件
    一般情况下,我们会使用终端软件,如XShell、SecureCRT或FinalShell、JumpServer堡垒机来连接远程服务器后,使用rz命令上传本地文件到远程服务器,再解压发版上线。一、安装使用安装rz和sz命令yum-yinstalllrzsz使用rz上传文件,会跳出文件选择窗口,选择好文件,点击确认即可r......
  • Linux 权限管理
    文章目录学习目标:-[]了解Linux中的权限-[]掌握修改权限的基础命令-[]掌握sudo及其配置文件的使用一、文件权限管理1、文件类型2、访问权限3文件访问者的分类4文件权限值的表示方法5基础命令chmod:修改文件、文件夹权限chown:修改文件、文件夹所有者、所属组......
  • Linux 网络管理
    在大多数领域与决心相比,天赋被高估了。时间长了决心就是你的天赋。文章目录前言一、关于网络配置的基础知识1.1网络配置文件说明1.2如何查看网卡名1.3网卡配置文件讲解二、VMware的三种网络模式2.1、第一种网络模式:Bridged(桥接模式)配置桥接模式的步骤2.1、第二种......
  • 嵌入式LINUX开发系列
    LINUX系列文章目录第一章ARM板子如何替换debian镜像源文章目录LINUX系列文章目录第一章ARM板子如何替换debian镜像源前言一、镜像源是什么?二、问题复现三、更换镜像源步骤总结前言当你做嵌入式开发过程中拿到一个开发板,遇到aptupdate,发现无法成功,镜像源无法使......
  • 初识 Linux 操作系统_实验案例一
    实验案例一:安装Ubuntu操作系统1、实验环境    BDQN公司部分员工使用的Windows操作系统的笔记本式计算机频繁遭受到病毒.木马的威胁,公司要求管理员小王近期将这些员工的系统更换为Ubuntu操作系统。在进行前期准备工作时,需要公司现有的系统管理员尽快掌握Ubuntu操作......
  • Linux离线安装Docker-Oracle_11g
    拉取oracle11g镜像dockerpullregistry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g创建11g容器dockerrun-d-p1521:1521--nameoracle11gregistry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g查看容器是否创建成功dockerps-a导出oracle容器,查看正在运......
  • linux apache 使用记录
    1、安装集成phpyuminstallhttpdyuminstallphpsystemctlrestarthttpd2、开启url重写功能修改/etc/httpd/conf/httpd.conf:A开启重写模块:LoadModulerewrite_modulemodules/mod_rewrite.soIncludeconf.modules.d/*.confB修改参数 AllowOverrideAllC网站根目录添......
  • Linux系统下的文件描述符fd详解
    文章目录文件描述符本作者从代码及源码的角度来总结探究文件描述符fd参考:韦东山Linux嵌入式视频文件描述符Linux系统下一切皆文件。文件描述符是操作系统中用来唯一标识一个已打开文件的整数。本质上来说就是索引,即根据索引值寻找到对应的文件,可对其进行相应......