• BootLoader 详解(3)


    BootLoader的stage2

     stage2的代码是C语言来实现的,以便于实现更复杂的功能和取得更好的代码可读性和移植性。它与普通C语言程序不同的是,在编译和链接BootLoader这样的程序时,不能使用glibc库中的任何支持函数。这就带来了一个问题,从哪里跳转到main()函数呢?直接把main()函数的起始地址作为stage2执行映像的入口点。但这样做有2个缺点:1)无法通过main()函数传递函数参数; 2)无法处理main()函数返回的情况。一种更为巧妙的方法是利用trampoline(弹簧床)的概念。用汇编写一段trampoline小程序,并将这段小程序作为stage2可执行映像的执行入口点。然后可以在trampoline汇编程序中用CPU跳转指令跳入main()函数中执行;当main()函数返回时,CPU执行路径再次回到我们的trampoline程序。下面给出一个简单的trampoline程序(来自blob):

    .text

    .globl_trampoline_trampoline:

          bl  main      

          /*if main return ,we just call it again */

          b _trampoline

    在vivi中,用循环解决的

    @ get read to call C functions
    ldr sp, DW_STACK_START @ setup stack pointer
    mov fp, #0 @ no previous frame, so fp=0
    mov a2, #0 @ set argv to NULL

    bl main @ call main

    mov pc, #FLASH_BASE @ otherwise, reboot

      1.初始化本阶段要使用到的硬件设备

       (1).初始化至少一个串口,以便和终端进行I/O输出信息;(2)初始化计时器等

        初始化完成后,可以输出一些打印信息,如程序名、版本号等等。

       2.检测系统的内存映射( memory map )

        所谓系统内存映射就是指在整个4GB物理地址中有哪些地址范围被分配用来寻址系统的RAM单元。比如,在SA-1100CPU中,从0xc0000000开始的512M地址空间被     用作系统的RAM地址空间,而在Samsung S3C44B0X CPU中,从0x0c000000到0x10000000之间的64M地址空间被用作系统的RAM地址空间。CPU预留出一大段              足够的地址空间给系统RAM,但是搭建具体的嵌入式系统时却不一定会实现CPU预留的全部RAM地址空间。也就是说,具体的嵌入式系统往往只把CPU预留的全部RAM地              址空间中的一部分映射到RAm单元上,让剩下的部分预留的RAM处于未使用状态。因此stage2在干点什么之前要检测整个系统的内存映射情况,即哪些处于unuse状态。

       3.加载内核映像和根文件系统映像

       (1)规划内存占用的布局

          包括2方面:内核映像所占用的内存范围。  跟文件系统所占用的内存范围。

          在规划占用内存占用的布局时,主要考虑基址和映像的大小两个方面。

          对于内核映像,一般将其拷贝到从(MEM_START + 0x8000)这个基址开始大约1MB大小的空间内U村范围(嵌入Linux内核一般不会超过1MB)。在             MEM_START+0x8000之前的32KB为什么空出来呢?这主要是Linux内核在这段内存中放置一些全局数据结构,如:启动参数和内核页表等信息。而对于

                    根文件系统映像,则将一般将其拷贝到MEM_START+0x00100000开始的地方。

       (2)从flash上拷贝

          ARM  CPU在统一的内存地址空间中寻址Flash等固态设备的,因此从Flash上读取数据与从RAM单元中读取数据是一样的,一个简单的循环就行了。

          while( count ){

              *dest++  = *src++; 

              count  -=  4; 

          }

          4.设置内核的启动参数

       在调用内核之前,应该做一步准备工作,即:设置Linux内核的启动参数。

  • 相关阅读:
    Golang解析、验证、修改URL之Host、Port、Path
    Golang检测Linux服务器端口占用
    Go MongoDB官方数据库驱动之增删改查
    PostgreSQL学习笔记(二)—— 概览
    PostgreSQL学习笔记(一)—— macOS下安装
    Go基础编程实践(十)—— 数据库
    Servlet的request和response
    JSP和Servlet异常处理转发
    运行servlet跳转页面变成了下载界面,或者中文乱码
    SQL Server事务(二)
  • 原文地址:https://www.cnblogs.com/ATMvip/p/3245290.html
Copyright © 2020-2023  润新知