网站建设所学内容怎么自己做一个网页

当前位置: 首页 > news >正文

网站建设所学内容,怎么自己做一个网页,微商营销宝app下载,广州正规网站建设哪家好bootz 启动 Linux 内核 images 全局变量 不管是 bootz 还是 bootm 命令#xff0c;在启动 Linux 内核的时候都会用到一个重要的全局变量#xff1a;images#xff0c; images 在文件 cmd/bootm.c 中有如下定义#xff1a; images 是 bootm_headers_t 类型的全局变量在启动 Linux 内核的时候都会用到一个重要的全局变量images images 在文件 cmd/bootm.c 中有如下定义 images 是 bootm_headers_t 类型的全局变量 bootm_headers_t 是个 boot 头结构体在文件include/image.h 中的定义如下 第 335 行的 os 成员变量是 image_info_t 类型的为系统镜像信息。 第 352~362 行这 11 个宏定义表示 BOOT 的不同阶段。 接下来看一下结构体 image_info_t也就是系统镜像信息结构体此结构体在文件include/image.h 中的定义如下 全局变量 images 会在 bootz 命令的执行中频繁使用到相当于 Linux 内核启动的“灵魂”。 do_bootz 函数 bootz 命令的执行函数为 do_bootz在文件 cmd/bootm.c 中有如下定义 第 629 行调用 bootz_start 函数 bootz_start 函数执行过程稍后分析。 第 636 行调用函数 bootm_disable_interrupts 关闭中断。 第 638 行设置 images.os.os 为 IH_OS_LINUX也就是设置系统镜像为 Linux表示我们要启动的是 Linux 系统后面会用到 images.os.os 来挑选具体的启动函数。 第 639 行调用函数 do_bootm_states 来执行不同的 BOOT 阶段这里要执行的 BOOT 阶段有 BOOTM_STATE_OS_PREP 、BOOTM_STATE_OS_FAKE_GO 和BOOTM_STATE_OS_GO。 bootz_start 函数 bootz_srart 函数也定义在文件 cmd/bootm.c 中函数内容如下 第 584 行调用函数 do_bootm_states执行 BOOTM_STATE_START 阶段。 第 593 行设置 images 的 ep 成员变量也就是系统镜像的入口点使用 bootz 命令启动系统的时候就会设置系统在 DRAM 中的存储位置这个存储位置就是系统镜像的入口点因 此 images-ep0X80800000。 第 598 行调用 bootz_setup 函数此函数会判断当前的系统镜像文件是否为 Linux 的镜像文件并且会打印出镜像相关信息 bootz_setup 函数稍后会讲解。 第 608 行调用函数 bootm_find_images 查找 ramdisk 和设备树(dtb)文件但是我们没有用到 ramdisk因此此函数在这里仅仅用于查找设备树(dtb)文件此函数稍后也会讲解。 先来看一下 bootz_setup 函数此函数定义在文件 arch/arm/lib/bootm.c 中函数内容如下 第 370 行宏 LINUX_ARM_ZIMAGE_MAGIC 就是 ARM Linux 系统魔术数。 第 376 行从传递进来的参数 image(也就是系统镜像首地址)中获取 zimage 头。 zImage 头结构体为 zimage_header。 第 377~380 行判断 image 是否为 ARM 的 Linux 系统镜像如果不是的话就直接返回并且打印出“Bad Linux ARM zImage magic!”。 第 382、 383 行初始化函数 bootz_setup 的参数 start 和 end。 第 385 行打印启动信息如果 Linux 系统镜像正常的话就会输出如图所示的信息 接下来看一下函数 bootm_find_images此函数定义在文件 common/bootm.c 中函数内容如下 第 230~235 行是跟查找 ramdisk但是我们没有用到 ramdisk因此这部分代码不用管。 第 237~244 行是查找设备树(dtb)文件找到以后就将设备树的起始地址和长度分别写到images 的 ft_addr 和 ft_len 成员变量中。我们使用 bootz 启动 Linux 的时候已经指明了设备树在 DRAM 中的存储地址因此 images.ft_addr0X83000000长度根据具体的设备树文件而定比如我现在使用的设备树文件长度为 0X8C81因此 images.ft_len0X8C81。 bootz_start 函数就讲解到这里 bootz_start 主要用于初始化 images 的相关成员变量。 do_bootm_states 函数 do_bootz 最 后 调 用 的 就 是 函 数 do_bootm_states 而 且 在 bootz_start 中 也 调 用 了do_bootm_states 函数 看 来 do_bootm_states 函数 还 是 个 香 饽 饽 。此函 数 定 义 在 文件 common/bootm.c 中函数代码如下 第 604、 605 行处理 BOOTM_STATE_START 阶段 bootz_start 会执行这一段代码这里调用函数 bootm_start此函数定义在文件 common/bootm.c 中函数内容如下 接着回到do_bootm_states函数中继续分析函数 do_bootm_states。第 658 行非常重要通过函数 bootm_os_get_boot_func 来查找系统启动函数参数 images-os.os 就是系统类型根据这 个系统类型来选择对应的启动函数在 do_bootz 中设置 images.os.os IH_OS_LINUX。函数返回值就是找到的系统启动函数这里找到的 Linux 系统启动函数为 do_bootm_linux关于此函 数查找系统启动函数的过程稍后分析。因此 boot_fndo_bootm_linux后面执行 boot_fn函数的地方实际上是执行的 do_bootm_linux 函数。 第 676 行处理 BOOTM_STATE_OS_PREP 状态调用函数 do_bootm_linux do_bootm_linux也是调用 boot_prep_linux 来完成具体的处理过程。 boot_prep_linux 主要用于处理环境变量 bootargs bootargs 保存着传递给 Linux kernel 的参数。 第 679~689 行是处理 BOOTM_STATE_OS_FAKE_GO 状态的但是要我们没用使能 TRACE功能因此宏 CONFIG_TRACE 也就没有定义所以这段程序不会编译。 第 699 行调用函数 boot_selected_os 启动 Linux 内核此函数第 4 个参数为 Linux 系统镜像头第 5 个参数就是 Linux 系统启动函数 do_bootm_linux。 boot_selected_os 函数定义在文件 common/bootm_os.c 中函数内容如下 第 480 行调用 boot_fn 函数也就是 do_bootm_linux 函数来启动 Linux 内核。 bootm_os_get_boot_func 函数 do_bootm_states 会调用 bootm_os_get_boot_func 来查找对应系统的启动函数此函数定义在文件 common/bootm_os.c 中函数内容如下 第 495~508 行是条件编译在本 uboot 中没有用到因此这段代码无效只有 509 行有效。 在 509 行中 boot_os 是个数组这个数组里面存放着不同的系统对应的启动函数。 boot_os 也定义在文件 common/bootm_os.c 中如下所示 第 438 行就是 Linux 系统对应的启动函数 do_bootm_linux。 do_bootm_linux 函数 经过前面的分析我们知道了 do_bootm_linux 就是最终启动 Linux 内核的函数此函数定义在文件 arch/arm/lib/bootm.c函数内容如下 第351行如果参数flag等于BOOTM_STATE_OS_GO或者BOOTM_STATE_OS_FAKE_GO的话就执行 boot_jump_linux 函数。 boot_selected_os 函数在调用 do_bootm_linux 的时候会将 flag 设置为 BOOTM_STATE_OS_GO。 第 352 行执行函数 boot_jump_linux此函数定义在文件 arch/arm/lib/bootm.c 中函数内容如下 第 274~292 行是 64 位 ARM 芯片对应的代码 Cortex-A7 是 32 位芯片因此用不到。 第 293 行变量 machid 保存机器 ID如果不使用设备树的话这个机器 ID 会被传递给 Linux内核 Linux 内核会在自己的机器 ID 列表里面查找是否存在与 uboot 传递进来的 machid 匹配的 项目如果存在就说明 Linux 内核支持这个机器那么 Linux 就会启动如果使用设备树的话这个 machid 就无效了设备树存有一个“兼容性”这个属性 Linux 内核会比较“兼容性”属 性的值(字符串)来查看是否支持这个机器。 第 295 行函数 kernel_entry看名字“内核_进入”说明此函数是进入 Linux 内核的也就是最终的大 boos此函数有三个参数 zero arch params第一个参数 zero 同样为 0第 二个参数为机器 ID 第三个参数 ATAGS 或者设备树(DTB)首地址 ATAGS 是传统的方法用于传递一些命令行信息啥的如果使用设备树的话就要传递设备树(DTB)。 第 299 行获取 kernel_entry 函数函数 kernel_entry 并不是 uboot 定义的而是 Linux 内核定义的 Linux 内核镜像文件的第一行代码就是函数 kernel_entry而 images-ep 保存着 Linux 内核镜像的起始地址起始地址保存的正是 Linux 内核第一行代码 第 313 行调用函数 announce_and_cleanup 来打印一些信息并做一些清理工作此函数定义在文件 arch/arm/lib/bootm.c 中函数内容如下 第 74 行在启动 Linux 之前输出“Starting kernel …”信息如图所示 第 87 行调用 cleanup_before_linux 函数做一些清理工作。 继续回到函数 boot_jump_linux第 315~318 行是设置寄存器 r2 的值为什么要设置 r2 的值呢 Linux 内核一开始是汇编代码因此函数 kernel_entry 就是个汇编函 数。向汇编函数传递参数要使用 r0、 r1 和 r2(参数数量不超过 3 个的时候)所以 r2 寄存器就是函数 kernel_entry 的第三个参数。 第 316 行如果使用设备树的话 r2 应该是设备树的起始地址而设备树地址保存在 images的 ftd_addr 成员变量中。 第 317 行如果不使用设备树的话 r2 应该是 uboot 传递给 Linux 的参数起始地址也就是环境变量 bootargs 的值。 第 328 行调用 kernel_entry 函数进入 Linux 内核此行将一去不复返 uboot 的使命也就完成了 总结一下 bootz 命令的执行过程如图所示