uboot启动流程-涉及lowlevel_init汇编函数

这篇具有很好参考价值的文章主要介绍了uboot启动流程-涉及lowlevel_init汇编函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.  uboot启动流程涉及函数

之前文章简单分析了 uboot启动流程的开始,从链接脚本文件 u-boot.lds 中,我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start函数。

_start函数调用了 reset 函数,reset 函数内部:最终调用了 save_boot_params_ret 函数。

save_boot_params_ret 函数:

①  将处理器设置为SVC模式,并且关闭FIQ和IRQ.

②  设置中断向量。

③  初始化CP15 (cpu_init_cp15),   调用了 cpu_init_crit 函数。

其中, cpu_init_crit 函数 调用了函数 lowlevel_init函数。

本文继续简单分析 lowlevel_init函数(即cpu_init_crit 函数 所调用的函数)做了什么?

本文继上一篇文章的分析,地址如下:

uboot启动流程涉及reset函数_凌肖战的博客-CSDN博客

二.     lowlevel_init 函数详解

lowlevel_init 函数在文件 arch/arm/cpu/armv7/lowlevel_init.S 中定义,内容如下:

18 ENTRY(lowlevel_init)
19 /*
20 * Setup a temporary stack. Global data is not available yet.
21 */
22 ldr sp, =CONFIG_SYS_INIT_SP_ADDR
23 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
24 #ifdef CONFIG_SPL_DM
25 mov r9, #0
26 #else
27 /*
28 * Set up global data for boards that still need it. This will be
29 * removed soon.
30 */
31 #ifdef CONFIG_SPL_BUILD
32 ldr r9, =gdata
33 #else
34 sub sp, sp, #GD_SIZE
35 bic sp, sp, #7
36 mov r9, sp
37 #endif
38 #endif
39 /*
40 * Save the old lr(passed in ip) and the current lr to stack
41 */
42 push {ip, lr}
43
44 /*
45 * Call the very early init function. This should do only the
46 * absolute bare minimum to get started. It should not:
47 *
48 * - set up DRAM
49 * - use global_data
50 * - clear BSS
51 * - try to start a console
52 *
53 * For boards with SPL this should be empty since SPL can do all 
54 * of this init in the SPL board_init_f() function which is 
55 * called immediately after this.
56 */
57 bl s_init
58 pop {ip, pc}
59 ENDPROC(lowlevel_init)
22 行设置 sp 指向 CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_INIT_SP_ADDR
include/configs/mx6ullevk.h 文件中,在 mx6ullevk.h 中定义如下:
234 #define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
235 #define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
236
237 #define CONFIG_SYS_INIT_SP_OFFSET \
238 (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
239 #define CONFIG_SYS_INIT_SP_ADDR \
240 (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
上面的宏 IRAM_BASE_ADDR IRAM_SIZE 在文件 arch/arm/include/asm/arch-mx6/imx-regs.h 中有定义,其实就是 IMX6UL/IM6ULL ocram 的首地址和大小,如下所示:
71 #define IRAM_BASE_ADDR 0x00900000
......
408 #if !(defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
409 defined(CONFIG_MX6SLL) || defined(CONFIG_MX6SL))
410 #define IRAM_SIZE 0x00040000
411 #else
412 #define IRAM_SIZE 0x00020000
413 #endif
如果 408 行的条件成立的话 IRAM_SIZE=0X40000 ,当定义了 CONFIG_MX6SX 、CONFIG_MX6U CONFIG_MX6SLL CONFIG_MX6SL 中的任意一个的话条件就不成立, .config文件 中定义了 CONFIG_MX6UL ,所以条件不成立, IRAM_SIZE=0X20000=128KB
可以得到如下值:
CONFIG_SYS_INIT_RAM_ADDR = IRAM_BASE_ADDR = 0x00900000
CONFIG_SYS_INIT_RAM_SIZE = 0x00020000 =128KB
还需要知道 GENERATED_GBL_DATA_SIZE 的值,在文件 include/generated/generic-asm-offsets.h 中有定义,如下:
9 #define GENERATED_GBL_DATA_SIZE 256
10 #define GENERATED_BD_INFO_SIZE 80
11 #define GD_SIZE 248
可以看出,GENERATED_GBL_DATA_SIZE=256。
综上所述, CONFIG_SYS_INIT_SP_ADDR 值如下:
CONFIG_SYS_INIT_SP_OFFSET = 0x00020000 – 256 = 0x1FF00
CONFIG_SYS_INIT_SP_ADDR = 0x00900000 + 0X1FF00 = 0X0091FF00
如下图所示,为 sp指针的值:

lowlevel_init,uboot,系统移植篇,linux,arm开发

此时 sp 指向 0X91FF00 ,这属于 IMX6UL/IMX6ULL 的内部 ram
通过 lowlevel_init.S文件可以看出
23 行对 sp 指针做 8 字节对齐处理!
34 行, sp 指针减去 GD_SIZE GD_SIZE 同样在 generic-asm-offsets.h 中定了,大小为
248
35 行对 sp 8 字节对齐,此时 sp 的地址为 0X0091FF00-248=0X0091FE08 ,此时 sp ,如下:

lowlevel_init,uboot,系统移植篇,linux,arm开发

lowlevel_init.S 文件中的 lowlevel_init 函数:

第 36 行将 sp 地址保存在 r9 寄存器中。
42 行将 ip lr 压栈
第 57 行调用 s_init 函数
58 行,将第 36 行入栈的 ip lr 进行出栈,并将 lr 赋给 pc

下一篇文章分析:

lowlevel_init函数调用的函数:s_init 函数文章来源地址https://www.toymoban.com/news/detail-729145.html

save_boot_params_ret函数调用的函数: _main

到了这里,关于uboot启动流程-涉及lowlevel_init汇编函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用QEMU模拟启动uboot

    uboot的相关知识,可以参考:uboot基本概念。 WSL: ubutu20.04 模拟开发板:vexpress-a9 uboot版本:u-boot-2023.10 2.1、安装 2.2、查看支持哪些开发板 结果如下: 注:此步非必须,也可自己从Arm GNU Toolchain下载,解压后添加到环境变量即可。 4.1、解压 4.2、编译 4.3、生成的u-boot.bin文件

    2024年02月06日
    浏览(45)
  • ARM uboot 启动 Linux 内核

    此处,我使用的是九鼎提供的 uboot : 进入 uboot 的 sd_fusing 目录,执行命令烧写 uboot : ./sd_fusing.sh /dev/sdb 。 按任意键,进入 uboot 命令行: 将 Linux kernel 拷贝到 30008000。

    2024年02月11日
    浏览(56)
  • pynq-1 viaodo配置和启动uboot

    Pynq-Z1 u-boot 移植笔记 Author: (2022.10.21) 创建vivado,生成bistream,因为前期不清楚芯片pynq-z1如何配置时钟和ddr部分,可以网上下载board file,然后在vivado安装目录下,新建board_file目录,将pynq-z1 board file放在此目录,就可以在vivado的board部分看到pynq-z1板卡,直接选中,然后新建

    2024年02月14日
    浏览(39)
  • ARM Linux 调试 -QEMU启动 Uboot/Kernel/Rootfs

    懒人方式: 直接去方锐/qemu克隆项目,执行script目录的脚本即可 1. build_env.sh安装环境 2. build_rootfs.sh 生成rootfs 3. build_kernel.sh编译kernel 4. qemu_run.sh开始调试 2.1busybox代码的下载编译 Busybox下载地址:https://busybox.net/downloads/ Download 1.36.0 Busybox 默认会安装到 ./_install 目录下 制作ro

    2024年02月02日
    浏览(61)
  • Android11 init.rc添加开机自启动service

             因项目需要,在开机启动的时候需要执行can初始化命令,但是在init.rc里面又不能直接执行shell命令,所以就需要添加一个service在开机的时候执行。         在device路径下添加可执行的命令并且编译出来,添加main.cpp和Android.mk:         main.cpp          

    2024年02月15日
    浏览(46)
  • 【水文】calico-node 启动失败 Init:CrashLoopBackOff

    查看日志报错如下  Defaulted container \\\"calico-node\\\" out of: calico-node, upgrade-ipam (init), install-cni (init), mount-bpffs (init) Error from server (BadRequest): container \\\"calico-node\\\" in pod \\\"calico-node-4j7td\\\" is waiting to start: PodInitializing 结果:kube-proxy没启动,每个人的环境不同,需要具体排查看日志。下面是分

    2024年02月11日
    浏览(68)
  • bootz启动 Linux内核过程中涉及的 do_bootm_states 函数

    uboot 启动Linux内核使用bootz命令。当然还有其它的启动命令,例如,bootm命令等等。 本文只分析 bootz命令启动 Linux内核的过程中涉及的几个重要函数。具体分析  do_bootm_states 函数执行过程。 本文继上一篇文章,地址如下: bootz启动 Linux内核过程中涉及的 bootz_start 函数-CSDN博客

    2024年02月04日
    浏览(76)
  • npm init vue@latest 创建项目启动报错记录

    问题描述: 解决方案: 1.在终端中输入sudo vim /etc/hosts ,回车然后输入密码 2.若出现如下图所示(若没有则直接输入i,然后进行后续操作),请输入E 然后输入i,移动到最后一行输入127.0.0.1 localhost 3.按esc退出编辑,然后输入:wq保存并推出 4.然后重启项目就可以了。

    2023年04月08日
    浏览(69)
  • ARM Linux 内核启动1 —— 汇编阶段

    1、Makefile 分析 (1) kernel 的 Makefile 写法和规则等,和 uboot 的 Makefile 是一样的,甚至 Makefile 中的很多内容都是一样的。 (2) kernel 的 Makefile 比 uboot 的 Makefile 要复杂,这里我们并不会一行一行的详细分析。 (3) Makefile 中只有一些值得关注的会强调一下,其他不强调的地方暂时可以

    2024年02月12日
    浏览(65)
  • 【Linux内核解析-linux-5.14.10-内核源码注释】内核启动kernel_init解释

    static int __ref kernel_init(void *unused) : 声明一个静态整型函数 kernel_init() ,该函数不会被其他文件访问,使用 __ref 标记表示该函数是可重定位的,并且该函数不需要任何参数。 wait_for_completion(kthreadd_done); : 等待 kthreadd 线程完成初始化, wait_for_completion() 函数会阻塞当前进程,直到

    2024年02月02日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包