• linux移植u-boot(一)——U-Boot详解+自定义命令实战


    linux移植u-boot(一)——U-Boot详解+自定义命令实战

    2015-02-07

    一、Bootloader

        简单地说:Bootloader主要功能就是 在系统上电时开始执行,初始化硬件和设备,准备好软件环境,最后调用操作系统。

        具体的包含:关闭你看门狗WATCHDOG,改变系统时钟,初始化存储控制器

    ,将操作系统内核代码复制到内存中去运行。

        为了开发方便,可以增加网络功能,从PC上通过串口或者网络下载文件,烧写文件,将flash上的内核代码解压后运行等。

    Bootloader分为两种模式:

    (1):启动加载模式:上电后,Bootloader在板子上的某个固态存储设备上将操作系统加载到RAM中运行,没有用户的介入

    (2):下载模式:开发人员可以使用各种命令,允许在各种工作模式之间切换,通过串口或者网络来下载内核文件,并将他们直接放在内存中运行,这就是我们我们所说的U-BOOT。

     

    嵌入式linux操作系统从软件角度可以分为四个层次:

    1. 引导加载程序bootloader
    2. linux内核
    3. 文件系统
    4. 用户应用程序

     

    一般的u-boot分为单阶段,多阶段两种:

    多阶段u-boot具有更好的可移植性,可以用两个阶段来概括;

    第一阶段:使用汇编来实现,完成一些依赖于CPU体系结构的初始化,包括光比WATCHDOG,关中断,设置CPU的速度和时钟频率,RAM初始化。

        硬件设备初始化 => 为加载Bootloader的第二阶段代码准备RAM空间 => 复制Bootloader的第二阶段代码到RAM空间中 => 设置好栈 => 跳转到第二阶段代码的C入口。

    第二阶段:使用C语言来实现,可以实现更为复杂的功能。

        初始化本阶段要使用的硬件设备 => 检测系统内存映射 => 将内核映像和根文件系统映像从Flash上读到RAM空间中 => 为内核设置启动参数 => 调用内核。

     

        Bootlaoder与内核的交互(参数传递的标记方式)

    1. 设置标记ATAG_CORE, 已标记此为开始。
    2. 设置内核标记
    3. 设置命令行标记,就是一个字符串,用来控制内核的一些行为
    4. 设置标记ATAG_NONE,标记列表以其结束

        

    常用的bootloader包括LILO, GRUB, loadlin, ROLO, Etherboot, BLOB, U-Boot, RedBoot, Vivi等,此处我们研究U-Boot;

    二、U-Boot分析与移植

    U-Boot,全称Universal Boot Loader, 遵循GPL条款的开业代码项目。

    U-Boot下面有26个子目录:分为四类:

    1. 平台相关的或者开发板相关的 board、cpu、lib_i386类似
    2. 通用的函数 include、lib_generic、common
    3. 通用设备驱动程序 disk、drivers、dtt、fs、nand_spl、net、post、rtc
    4. U-Boot工具,示例程序,文档 doc、examples、tools

     

    U-Boot 的配置、编译、链接过程

    配置过程:

        配置文件为根目录下的mkconfig,

        例如,执行make smdk2410_config 实际上就是执行如下命令

            ./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0

        结果:

    1. 开发板名称BOARD_NAME 等于 $1
    2. 创建到平台/开发板的相关的头文件的链接
    3. 创建顶层Makefile包含的文件include/config.mk
    4. 创建开发板相关的头文件include/config.h $include <configs/$1.h>

    编译、链接

        make all

    总结一下U-Boot的编译流程

    1. 首先编译cpu/$(CPU)/start.S ,对不同的CPU,还可能编译cpu/$(CPU)下的其他文件。
    2. 然后,对平台/开发板相关的每个目录,每个通用目录都使用它们各自的Makefile生成的相应的库
    3. 将1、2步骤生成的.0、.a文件按照board/$(BOARDDIR)/config.mk 文件中制定的代码段起始地址,board/$(BOARDDIR)/U-Boot.lds 链接脚本进行链接
    4. 第3步得到的ELF格式的U-Boot,然后Makefile还会将其转化成二进制格式文件,S-Record格式。

     

    烧写内核映像文件uImage

    将uImage放在主机的上的tftp或nfs目录下,确保已经开启tftp或nfs服务。

    然后运行命令下载文件,擦除,烧写NAND Flash

    tftp 0x80800000 uImage

    nand erase 0x0 0x00200000

    nand write.jffs2 0x80800000 0x0 $(filesize)

    注:nand write.jffs2不要求文件的长度是页对齐(512字节对齐)

    也可以使用nand wirte 但是长度要是512字节对齐

     

    烧写文件系统映像

    tftp 080800000 yaffs.img

    nand erase 0xa00000 0x3600000

    nand write.yaffs 0x80800000 0xa00000 $(filesize)

    使用U-Boot 来烧写程序

    tftp 0x30000000 test.bin

    go 0x30000000

     

     

    注意:生成适用于EasyARM-iMX257的U-Boot文件需要按如下步骤进行操作:

    首先,进入u-boot-2009.08目录,清除原有的编译文件,其对应的终端命令如下:

    $ cd u-boot-2009.08

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- distclean

    其次,需要配置U-Boot的平台为mx25_3stack_config,对应的终端命令如下:

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- mx25_3stack_config

    Configuring for mx25_3stack board...

    然后,执行编译,对应的终端命令如下:

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

    编译完成后将在u-boot-2009.08目录下得到u-boot.bin文件。

     

     

    Loadb 0x80800000 -将uImage从串口发送到davinci的ddr2中0x80800000处。

    Protect off all -去掉写保护

    Erase 0x200000 0x204ffff -擦除nor flash中uImage占用的空间

    Cp.b 0x80800000 0x2050000 0x14b008 -将传送到ddr2中的uImage文件拷贝到flash中

    Save -保存flash的内容

    补充说明:

    如果板卡上已经有u-boot,需要升级为新版的u-boot时,则可以操作如下:

    使用超级终端的利用串口发送u-boot到davinci板卡,然后利用在线更新的方式完成u-boot烧写,具体步骤:

    1)Protect off all -去掉写保护

    2)Erase 0x2000000 0x204ffff -擦除nor flash中u-boot占用的空间

    3)Loadb 0x80800000 -将u-boot文件通过串口发送到davinci的ddr2

    4)Cp.b 0x80800000 0x2000000 0x17398 -将传送到ddr2中

    u-boot文件拷贝到flash中

    5)Save -保存flash的内容

     

     

     

    三、U-Boot增加自定义命令实例

    我们在u-boot下增加我们自定义hello命令。

    1. 首先我们在u-boot的common目录下增加一个cmd_hello.c文件

      参照其他命令的书写方式,代码如下

    #include <image.h>

    #include <malloc.h>

    #include <u-boot/zlib.h>

    #include <bzlib.h>

    #include <environment.h>

    #include <lmb.h>

    #include <linux/ctype.h>

    #include <asm/byteorder.h>

     

    int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

    {

        int i = 0;

        printf("hello,Lover雪!!! the argcs are ");

        for(i = 0 ; i<argc ; i++)

            printf("argv[%d]: %s ",i,argv[i]);

        return 0;

    }

     

    U_BOOT_CMD(

        hello,    CONFIG_SYS_MAXARGS,    1,    do_hello,

        "This is a user defined command hello,Lover雪!!!",

        "hello,long help ...... "

        );

     

    1. 修改common下面的makefile文件,告诉U-Boot编译我们自定义的C文件

    参考Makefile中其他文件的定义,加入一句

    COBJS-y += cmd_hello.o

     

    1. 重新make编译 u-boot

     

     

  • 相关阅读:
    处理ios键盘弹出按钮点击click失效
    vue-eahars生产编译报错
    vue页面嵌套其他页面判断是否生产https
    阿里云linux安装nginx,亲测有效
    translate函数
    html表单from练习
    html 表格标签
    selenium模块简单使用
    python字符串普通操作
    浏览器的cookie的值改成字典格式
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4279543.html
Copyright © 2020-2023  润新知