Porting:uboot简介、移植、代码阅读、uboot添加启动logo

来源:互联网 发布:编发软件 编辑:程序博客网 时间:2024/05/29 09:51
1、u-boot简介
     开源软件,德国的denx小组维护。
     中国开源社区// 提供了很多国人写的程序,嵌入式较少。
     start.s ---->
     u-boot本质就是一个裸板程序。
     u-boot属于bootloader的一种。
     bootloader的功能:' 初始化硬件 + 加载启动操作系统。
     u-boot号称通用的bootloader
            支持的硬件平台:arm/powerpc/mips/x86 ...
            能够加载的操作系统:linux/vxworks/qnx ...

如题:
    如果给你一块开发板,需要一直u-boot,你怎么做?

2、u-boot的移植步骤

2.1 获取u-boot源码
     1)从denx官网上下载(强烈不建议,需要修改的软件难度极高)
     2)从芯片厂家获取(上游厂家)
          eg:三星公司 - S5P6818芯片 - 自行设计demo板 - 移植u-boot - 移植内核
          现在很多芯片厂家将移植好的源码,放在github.com
          cvs/svn:版本控制软件
          git:林纳斯,分布式版本控制软件
          u-boot源码:// env/uboot.tar.bz2

2.2 编译u-boot源码
     $:'cd jy/porting/day02/porting
     $:'cp /mnt/hgfs/porting/env/uboot.tar.bz2
     $:'tar -xvf *.bz2
     $:'cd uboot/
     $:'find ./ -type f | wc -l  
     // 统计文件数量 3229
     $:'make clean
     // 清除编译过程中生成的文件
     $:'make distclean
     // 清除配置阶段生成的文件 + 编译阶段生成的文件
     $:'make x6818_config
     // 配置makefile后可以make执行编译,方法来自README中写的命令行命令:make NAME_config
     $:'make -j4
     // 开4个线程同时编译
     验证ubootpak.bin是否可以再开发板上正常运行
     $:'cp ubootpak.bin /tftpboot/
     #:'tftp 48000000 ubootpak.bin
     #:'update_mmc 2 2ndboot 48000000 200 <filesize>

2.3 阅读uboot源码
     // arch/arm/cpu/slsiap/s5p6818/prototype/prototype 删除此软连接文件
     linux:vim + ctags
        $:'rm arch/arm/cpu/slsiap/s5p6818/prototype/prototype
        $:'ctags -R *
        ctrl + ]
        ctrl + t
     windows:source insight
        编辑、阅读C代码的利器
     寻找入口点:
        $:'rm u-boot
        $:'make V=1
        // 显示编译连接详细过程
     arm-cortex_a9-linux-gnueabi-ld.bfd   -pie  --gc-sections -Bstatic -Ttext 0x43C00000 -o u-boot -T u-boot.lds arch/arm/cpu/slsiap/start.o --start-group  arch/arm/cpu/built-in.o
        $:'vi u-boot.lds
        $:'vi arch/arm/cpu/slsiap/s5p6818/start.S  // 大写ls
         start.S汇编代码分析:
            reset
                >>设置管理模式
                >>关看门狗  // 本质是个CPU复位定时器
                    /* disable watchdog */
                    ldr r0, =0xC0019000
                    mov r1, #0
                    str r1, [r0]
                >>清空BSS段
                        __bss_start:BSS起始地址
                        __bss_end:BSS结束地址
                board_init_f // common/board_f.c完成了一系列硬件的初始化
                board_init_r // common/board_r.c  
                     ---> run_main_loop
             总结:uboot在启动第一个阶段了一系列硬件初始化
                 必要硬件初始化
                    cpu
                      cache清除 使能
                      关看门狗
                      关中断
                      使能MMU
                    各种模式下的栈空间设置  
                    内存的初始化
                       加载操作系统做准备 
                    EMMC硬件的初始化
                    清空BSS段
                    调用c函数 run_main_loop          
             run_main_loop
             {
                main_loop()
                {
                    bootdelay_process()
                    {
                        s = getenv("bootdelay");
                        bootdelay = s ? (int)simple_strtol 
                        s = getenv("bootcmd");
                        return s;
                    }
                    autoboot_command(s)
                    {
                        if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay))
                        {
                           //执行bootcmd中的两条命令
                           run_command_list(s, -1, 0);
                        } 
                    }
                    cli_loop()
                    {
                       cli_simple_loop()
                       {
                           /*接收用户命令console_buffer*/
                           len = cli_readline(CONFIG_SYS_PROMPT);
                           strcpy(lastcommand, console_buffer); 
                           /*匹配命令 执行命令*/
                           run_command_repeatable(lastcommand, flag)                        
                       }
                    }
                }
             }
      
      移植工作的关键文件:include/configs/x6818.h (开发板的配置文件)

<tips>
阅读代码的技巧:    $:'grep "要搜索的字符串" * -nRw
    判断哪个函数是要跳转到的位置?
    1)如果本文件中有该函数的实现;
    2)根据路径哪个和你的硬件越相关哪个就是;
    3)通用目录里那个可能是;
    4)哪个函数被编译了哪个就是,即函数所在的.c编译时生成了.o
         或在函数中加个打印信息,编译-在板子上运行,看是哪个文件。

<tips>
查看文件在内存各个空间的存储大小
    $:' size filename

3、uboot添加一个启动logo
显示logo的作用:
    1)商业宣传;
    2)增强用户体验;
3.1 LCD驱动程序
    1)根据外接LCD屏的特性,设置LCD控制器的时序参数;
    2)在内存中划分一片空间,作为现存使用;
    3)将显存的起始地址通知LCD控制器;
3.2 应用程序
【基本常识】
    显示图像就是将要显示的数据写入显存 SDRAM
    RGB三原色
    屏幕的分辨率(像素点个数) // eg:1024*600
    显存大小 // eg:1024*600*4Byte / 1024 / 1024 = 14M显存
    将屏幕上的P0(X0,Y0)修改为黑色:
    *((unsigned int*)(LCD_BASE)) + (1024*Y0 + X0) * 4 = 0x00000000
【图片转换为RGB格式】
    'Image2Lcd' - 文件夹不用安装直接用。
    可以将bmp/jpg格式转换为rgb类型的图片
    打开tarena_logo.bmp
    做如下设置:
        输出数据类型:C语言数组(*.c)
        扫描模式:水平扫描(默认)
        输出灰度:24bit真彩色
        最大宽度和高度: 320  200 (根据具体图像大小设置)->点击按钮
        其他选项全部去掉勾选。
        [保存]文件为tarena_logo.c
【编程将转换后的图片数据写入显存】
    图片显示在LCD屏的'中央位置'
    x = (1024 - 320) / 2 = 352
    y = (600 - 200) / 2 = 200
    起始像素点坐标(x,y)=(352,200)
    $:'cp /mnt/hgfs/porting/env/tarena_logo.c common/
    $:'vi common/lcd_logo.c
/** 代码演示 - lcd_logo.c **/#define LCD_BASE        0x46000000      // 显存的起始地址#define COL             1024            // 开发板LCD屏宽度#define ROW             600             // 开发板LCD屏高度// 起始像素点坐标#define X0              352#define Y0              200// 图片的宽度高度#define WIDTH           320#define HEIGHT          200// 描点void lcd_draw_pixel (int row, int col, int color) {    unsigned long* pixel = (unsigned long*)LCD_BASE;    *(pixel + (row * COL + col)) = color;}extern const unsigned char gImage_tarena_logo[];// 画图void lcd_draw_logo (void) {    int i = 0;    int j = 0;    unsigned char* p = (unsigned char*)gImage_tarena_logo;    unsigned int blue = 0;    unsigned int green = 0;    unsigned int red = 0;    unsigned int color = 0;    for (i = Y0; i < (Y0 + HEIGHT); i++) { // 一次循环描一行        for (j = X0; j < (X0 + WIDTH); j++) { // 每行像素点描点            blue = *p++;            green = *p++;            red = *p++;            color = red << 16 | green << 8 | blue << 0;            lcd_draw_pixel (i, j, color);        }       }   }
    $:'vi arch/arm/cpu/slsiap/common/cmd_draw_logo.c
/** 代码修改  - 409行 **/extern void lcd_draw_logo (void);#if (1)static void fill_lcd(U32 FrameBase, int XResol, int YResol, U32 PixelByte){    lcd_draw_logo ();#if 0   
    $:'vi common/Makefile
    每个子目录下的.c文件是否参与编译,取决于当前目录下的makefile文件。
/** 代码新增 - 第7,8行 **/  obj-y += tarena_logo.o  obj-y += lcd_logo.o
    $:'make x6818_config
    $:'make -j4
 3.3 实验步骤
     $:'cp ubootpak.bin /tftpboot/
     #:'tftp 48000000 ubootpak.bin
     #:'update_mmc 2 2ndboot 48000000 200 82670
0 0
原创粉丝点击