• uboot——官网下载直接移植(二)


    1:做好上一章的准备工作,下面我们开始移植uboot

    首先修改交叉编译工具链:在主Makefile文件中的交叉编译工具链修改为:

    # set default to nothing for native builds
    ifeq ($(HOSTARCH),$(ARCH))
    CROSS_COMPILE ?=
    else
    CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
    endif

    下面把烧录文件移植到uboot中;

    把三星移植好的uboot中的sd_fusing 复制到新的uboot的根目录中,烧录sd卡

    输出信息如下,说明校验头失败;

    分析sd_fusing目录下的C110-EVT1-mkbl1.c文件

    这段代码中是把uboot的前8k中的前16个字节的内容当做头来使用,相当于把uboot_inand.bin的前8k复制到SD-bl1-8k.bin,但是这前8k的前16个字节用作一个header 从bit8-bit11用作校验头,以前uboot中前16字节特意设置为0;

    我们可以修改这个代码,也修改修改uboot中的前16字节,一下为修改之后的代码:

    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main (int argc, char *argv[])
    {
        FILE        *fp;
        char        *Buf, *a, *b;
        int        BufLen;
        int        nbytes, fileLen;
        unsigned int    checksum;
        int        i;
    
    //////////////////////////////////////////////////////////////
        if (argc != 4)
        {
            printf("Usage: mkbl1 <source file> <destination file> <size> 
    ");
            return -1;
        }
    
    //////////////////////////////////////////////////////////////
        BufLen = atoi(argv[3]);
        Buf = (char *)malloc(BufLen + 16);
        memset(Buf, 0x00, BufLen + 16);
        
    //////////////////////////////////////////////////////////////
        fp = fopen(argv[1], "rb");
        if( fp == NULL)
        {
            printf("source file open error
    ");
            free(Buf);
            return -1;
        }
    
        fseek(fp, 0L, SEEK_END);
        fileLen = ftell(fp);
        fseek(fp, 0L, SEEK_SET);
    
        if ( BufLen > fileLen )
        {
            printf("Usage: unsupported size
    ");
            free(Buf);
            fclose(fp);
            return -1;
        }
    
        /*
        **    bhc add
        */
        b = Buf + 16;
        
        nbytes = fread(b, 1, BufLen, fp);
    
        if ( nbytes != BufLen )
        {
            printf("source file read error
    ");
            free(Buf);
            fclose(fp);
            return -1;
        }
    
        fclose(fp);
    
    //////////////////////////////////////////////////////////////
        a = b;
        for(i = 0, checksum = 0; i < BufLen - 16; i++)
            checksum += (0x000000FF) & *a++;
        
        /*
        **    bhc add
        */
        a = Buf;
        *( (unsigned int *)a ) = 0x2000;
        
        a = Buf + 8;    
        *( (unsigned int *)a ) = checksum;
    
    //////////////////////////////////////////////////////////////
        fp = fopen(argv[2], "wb");
        if (fp == NULL)
        {
            printf("destination file open error
    ");
            free(Buf);
            return -1;
        }
    
        a    = Buf;
        nbytes    = fwrite( a, 1, BufLen, fp);
    
        if ( nbytes != BufLen )
        {
            printf("destination file write error
    ");
            free(Buf);
            fclose(fp);
            return -1;
        }
    
        free(Buf);
        fclose(fp);
    
        return 0;
    }

    实验现象同修改uboot前16字节一样,说明校验和对了,通过这个实验我们可以知道,irom除了校验和一致以外,第一字节的值应该为0x2000;

    按照三星修改的uboot头文件设置:

    至于第一个为什么是0x2000按照三星irom_application_note中的说法第一个为uboot的大小,但是实际值也不是这样的;

    修改以后重新编译如下所示:

    下面我们来看一下start.S中的代码 

    最前面一段为设置异常向量表;

    .globl _start
    _start:  
        b    reset
        ldr    pc, _undefined_instruction
        ldr    pc, _software_interrupt
        ldr    pc, _prefetch_abort
        ldr    pc, _data_abort
        ldr    pc, _not_used
        ldr    pc, _irq
        ldr    pc, _fiq
    #ifdef CONFIG_SPL_BUILD
    _undefined_instruction: .word _undefined_instruction
    _software_interrupt:    .word _software_interrupt
    _prefetch_abort:    .word _prefetch_abort
    _data_abort:        .word _data_abort
    _not_used:        .word _not_used
    _irq:            .word _irq
    _fiq:            .word _fiq
    _pad:            .word 0x12345678 /* now 16*4=64 */
    #else
    _undefined_instruction: .word undefined_instruction
    _software_interrupt:    .word software_interrupt
    _prefetch_abort:    .word prefetch_abort
    _data_abort:        .word data_abort
    _not_used:        .word not_used
    _irq:            .word irq
    _fiq:            .word fiq
    _pad:            .word 0x12345678 /* now 16*4=64 */
    #endif    /* CONFIG_SPL_BUILD */

    以及一些用到的全局变量的初始化

    .globl _TEXT_BASE
    _TEXT_BASE:
    #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
        .word    CONFIG_SPL_TEXT_BASE
    #else
        .word    CONFIG_SYS_TEXT_BASE
    #endif
    
    /*
     * These are defined in the board-specific linker script.
     */
    .globl _bss_start_ofs
    _bss_start_ofs:
        .word __bss_start - _start
    
    .globl _bss_end_ofs
    _bss_end_ofs:
        .word __bss_end - _start
    
    .globl _end_ofs
    _end_ofs:
        .word _end - _start
    
    #ifdef CONFIG_USE_IRQ
    /* IRQ stack memory (calculated at run-time) */
    .globl IRQ_STACK_START
    IRQ_STACK_START:
        .word    0x0badc0de
    
    /* IRQ stack memory (calculated at run-time) */
    .globl FIQ_STACK_START
    FIQ_STACK_START:
        .word 0x0badc0de
    #endif
    
    /* IRQ stack memory (calculated at run-time) + 8 bytes */
    .globl IRQ_STACK_START_IN
    IRQ_STACK_START_IN:
        .word    0x0badc0de

    下面是真正的执行程序部分:

    reset:
        bl    save_boot_params
        /*
         * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
         * except if in HYP mode already
         */
        mrs    r0, cpsr
        and    r1, r0, #0x1f        @ mask mode bits
        teq    r1, #0x1a        @ test for HYP mode
        bicne    r0, r0, #0x1f        @ clear all mode bits
        orrne    r0, r0, #0x13        @ set SVC mode
        orr    r0, r0, #0xc0        @ disable FIQ and IRQ
        msr    cpsr,r0

     save_boot_params 这个函数实际上就是直接 return 0;

    ENTRY(save_boot_params)
      bx lr @ back to my caller      //直接转到lr

    下面是设置为svc模式,禁止fir、irq中断;

    下面是两个关键性的函数

    bl cpu_init_cp15 

    cp15协处理器的初始化


    bl cpu_init_crit 在看一下这个函数:

    1 ENTRY(cpu_init_crit)
    2     /*
    3      * Jump to board specific initialization...
    4      * The Mask ROM will have already initialized
    5      * basic memory. Go here to bump up clock rate and handle
    6      * wake up conditions.
    7      */
    8     b    lowlevel_init        @ go setup pll,mux,memory
    9 ENDPROC(cpu_init_crit)

    这个函数中就一个

    b lowlevel_init

     --------------------------------------

     进入lowlevel_init函数中,在这里我们要进行串口的初始化并打印信息O

    然后在进行dram的初始化,并打印信息K

    dram初始化的时候记得把相关头文件复制过去就可以了;

    然后返回_start函数中,进行重定位、清bss跳转到第二阶段

    这里要注意:串口输出需要一个时间,所以要打印之前首先放一个delay函数;确定他发送完

    注意在lowlevel_init函数中存在一些无关的代码如下面,io复位等,这些代码有可能会陷入死循环,跳转不出去,这些代码直接去掉;

    返回到_start函数中并设置打印信息A

     

    如下图:打印出了A,下面进行重定位

    因为要调用c语言函数,所以首先要设置栈;

    然后判断是否需要重定位,如果需要则重定位;

    在链接脚本中设置的链接地址是从0x00000000开始的,但是

  • 相关阅读:
    JQuery 中 某个标签 remove 时添加特效方法
    JQuery each 方法
    JQuery 中 animate() 方法使用
    final关键字
    坑爹之Server Farm
    正确使用Google英文版
    SQLServer2014下载地址
    微软这是要作死啊
    Why not me ?
    页面无法调试?
  • 原文地址:https://www.cnblogs.com/biaohc/p/6476866.html
Copyright © 2020-2023  润新知