zoukankan      html  css  js  c++  java
  • X-004 FriendlyARM tiny4412 uboot移植之点亮指路灯

    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

    开发环境:win7 64 + VMware12 + Ubuntu14.04 64

    工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi

    要移植的u-boot版本:u-boot-2016-11

    Tiny4412开发板硬件版本为

        底板:  Tiny4412/Super4412SDK 1506

           核心板:Tiny4412 - 1412

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 

     

    在上一节中我们为tiny4412开发板添加相应目录文件,并且可以顺利编译通过生成.bin文件。接下来我们通过点亮tiny4412核心板上的LED灯开始调试u-boot

    1Tiny4412 LED硬件原理图与exynos4412相关引脚寄存器

    Tiny4412-1412-Schematic.pdf原理图上可以看到板子上的四个LED硬件连接如下图所示:

    clip_image002[1]

    clip_image004[1]

    LED1~LED4分别跟GPM4_0~GPM4_3相接。

        exynos4412 GPM4相关的寄存器如下:

    clip_image006[1]

    现在我们只是想简单的点亮exynos4412 GPM4管脚上的LED灯,需要设置GPM4CONGPM4DAT寄存器,这两个寄存器的相关描述如下:

    clip_image007[1]

    clip_image008[1]

    clip_image009[1]

     

     

     

     

    2、添加LED灯代码

        arch/arm/cpu/armv7/start.S中添加点亮LED的代码。

    diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S

    index 691e5d3..4496f2f 100755

    --- a/arch/arm/cpu/armv7/start.S

    +++ b/arch/arm/cpu/armv7/start.S

    @@ -47,6 +47,7 @@ save_boot_params_ret:

            orr     r0, r0, #0xc0           @ disable FIQ and IRQ

            msr     cpsr,r0

     

    +       bl light_led

     /*

      * Setup vector:

      * (OMAP4 spl TEXT_BASE is not 32 byte aligned.

    @@ -63,6 +64,8 @@ save_boot_params_ret:

            mcr     p15, 0, r0, c12, c0, 0  @Set VBAR

     #endif

     

    +

    +

            /* the mask ROM code should have PLL and others stable */

     #ifndef CONFIG_SKIP_LOWLEVEL_INIT

            bl      cpu_init_cp15

    @@ -272,3 +275,18 @@ ENTRY(cpu_init_crit)

            b       lowlevel_init           @ go setup pll,mux,memory

     ENDPROC(cpu_init_crit)

     #endif

    +

    +       .globl light_led

    +light_led:

    +       ldr     r0,=0x110002E0      @ set GPM4CON Register

    +       ldr     r1,=0x00001111      @ Configurate GPM4_0<A1>GPM4_1<A2>GPM4_2<A2>GPM4_3 output

    +       str     r1,[r0]

    +

    +       ldr     r0,=0x110002E4       @ set GPM4DAT Register

    +@      mov     r1,#0xFE             @ light All led1 on

    +@      mov     r1,#0xFD             @ light All led2 on

    +@      mov     r1,#0xFB             @ light All led3 on

    +@      mov     r1,#0xF7             @ light All led4 on

    +       mov r1,#0xF0                     @ light All led on

    +       str     r1,[r0]

    +       mov pc, lr

     

     

     

    3、修改board/samsung/tiny4412/tools/mktiny4412spl.c文件,用于生成BL2

    (在《X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件》中已经修改好了mktiny4412spl.c文件,这步可以省略)

    diff --git a/board/samsung/tiny4412/tools/mktiny4412spl.c b/board/samsung/tiny4412/tools/mktiny4412spl.c

    index 3ed20ef..c3a3e29 100755

    --- a/board/samsung/tiny4412/tools/mktiny4412spl.c

    +++ b/board/samsung/tiny4412/tools/mktiny4412spl.c

    @@ -1,5 +1,6 @@

     /*

    - * Copyright (C) 2011 Samsung Electronics

    + *       2016

    + *  Author  AP0904225 <ap0904225@qq.com>

      *

      * SPDX-License-Identifier:    GPL-2.0+

      */

    @@ -13,11 +14,9 @@

     #include <sys/stat.h>

     

     #define BUFSIZE                        (16*1024)

    -#define IMG_SIZE               (16*1024)

    -#define SPL_HEADER_SIZE                16

    +#define IMG_SIZE               ( (14*1024)- 4 )

     #define FILE_PERM              (S_IRUSR | S_IWUSR | S_IRGRP

                                    | S_IWGRP | S_IROTH | S_IWOTH)

    -#define SPL_HEADER             "S5PC210 HEADER  "

     /*

     * Requirement:

     * IROM code reads first 14K bytes from boot device.

    @@ -37,7 +36,8 @@ int main(int argc, char **argv)

            int i, len;

            unsigned char buffer[BUFSIZE] = {0};

            int ifd, ofd;

    -       unsigned int checksum = 0, count;

    +       unsigned int checksum = 0;

    +       unsigned int count = 0;

     

            if (argc != 3) {

                    printf(" %d Wrong number of arguments ", argc);

    @@ -52,7 +52,7 @@ int main(int argc, char **argv)

            }

     

            ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);

    -       if (ifd < 0) {

    +       if (ofd < 0) {

                    fprintf(stderr, "%s: Can't open %s: %s ",

                            argv[0], argv[2], strerror(errno));

                    if (ifd)

    @@ -63,12 +63,9 @@ int main(int argc, char **argv)

            len = lseek(ifd, 0, SEEK_END);

            lseek(ifd, 0, SEEK_SET);

     

    -       memcpy(&buffer[0], SPL_HEADER, SPL_HEADER_SIZE);

    -

    -       count = (len < (IMG_SIZE - SPL_HEADER_SIZE))

    -               ? len : (IMG_SIZE - SPL_HEADER_SIZE);

    +       count = (len < IMG_SIZE )? len : IMG_SIZE; //14K-4

     

    -       if (read(ifd, buffer + SPL_HEADER_SIZE, count) != count) {

    +       if (read(ifd, buffer, count) != count) {

                    fprintf(stderr, "%s: Can't read %s: %s ",

                            argv[0], argv[1], strerror(errno));

     

    @@ -80,14 +77,11 @@ int main(int argc, char **argv)

                    exit(EXIT_FAILURE);

            }

     

    -       for (i = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)

    -               checksum += buffer[i+16];

    -

    -       *(ulong *)buffer ^= 0x1f;

    -       *(ulong *)(buffer+4) ^= checksum;

    -

    -       for (i = 1; i < SPL_HEADER_SIZE; i++)

    -               buffer[i] ^= buffer[i-1];

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

    +       {

    +               checksum += (unsigned char)(buffer[i]);

    +       }

    +       *(unsigned int*)(buffer+i) = checksum;

     

            if (write(ofd, buffer, BUFSIZE) != BUFSIZE) {

                    fprintf(stderr, "%s: Can't write %s: %s ",

     

     

    4、拷贝sd_fuse文件夹到u-boot根目录下

        sd_fuse文件夹下包含的文件有:

        4.1exynos4412启动所需的二进制固件:E4412_N.bl1.binE4412_tzsw.bin

        4.2fast_fuse.sh

    #

    # Copyright (C) 2011 Samsung Electronics Co., Ltd.

    #              http://www.samsung.com/

    #

    # This program is free software; you can redistribute it and/or modify

    # it under the terms of the GNU General Public License version 2 as

    # published by the Free Software Foundation.

    #

    ####################################

     

    if [ -z $1 ]

    then

        echo "usage: ./sd_fusing.sh <SD Reader's device file>"

        exit 0

    fi

     

    if [ -b $1 ]

    then

        echo "$1 reader is identified."

    else

        echo "$1 is NOT identified."

        exit 0

    fi

     

    ####################################

    #<verify device>

     

    BDEV_NAME=`basename $1`

    BDEV_SIZE=`cat /sys/block/${BDEV_NAME}/size`

     

    if [ ${BDEV_SIZE} -le 0 ]; then

        echo "Error: NO media found in card reader."

        exit 1

    fi

     

    if [ ${BDEV_SIZE} -gt 32000000 ]; then

        echo "Error: Block device size (${BDEV_SIZE}) is too large"

        exit 1

    fi

     

    ####################################

    # check files

     

    E4412_UBOOT=../../u-boot.bin

    MKBL2=../mkbl2

     

    if [ ! -f ${E4412_UBOOT} ]; then

        echo "Error: u-boot.bin NOT found, please build it & try again."

        exit -1

    fi

     

    if [ ! -f ${MKBL2} ]; then

        echo "Error: can not find host tool - mkbl2, stop."

        exit -1

    fi

     

    #<make bl2>

    ${MKBL2} ${E4412_UBOOT} bl2.bin 14336

     

    ####################################

    # fusing images

     

    bl2_position=17

    uboot_position=49

     

    #<BL2 fusing>

    echo "---------------------------------------"

    echo "BL2 fusing"

    dd iflag=dsync oflag=dsync if=./bl2.bin of=$1 seek=$bl2_position

     

    #<u-boot fusing>

    echo "---------------------------------------"

    echo "u-boot fusing"

    dd iflag=dsync oflag=dsync if=${E4412_UBOOT} of=$1 seek=$uboot_position

     

    #<flush to disk>

    sync

     

    ####################################

    #<Message Display>

    echo "---------------------------------------"

    echo "U-boot image is fused (at `date +%T`) successfully."

    echo "Eject SD card and insert it again."

        4.3sd_fdisk.c

    /*

     * Copyright (c) 2010 Samsung Electronics Co., Ltd.

     *              http://www.samsung.com/

     *

     * This program is free software; you can redistribute it and/or modify

     * it under the terms of the GNU General Public License version 2 as

     * published by the Free Software Foundation.

     */

     

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

     

    #define     BLOCK_SIZE          512

    #define     BLOCK_END           0xFFFFFFFF

    #define     _10MB               (10*1024*1024)

    #define     _100MB              (100*1024*1024)

    #define     _8_4GB              (1023*254*63)

     

    #define     CHS_MODE            0

    #define     LBA_MODE            !(CHS_MODE)

     

    typedef struct

    {

        int     C_start;

        int     H_start;

        int     S_start;

     

        int     C_end;

        int     H_end;

        int     S_end;

     

        int     available_block;

        int     unit;

        int     total_block_count;

        int     addr_mode;  // LBA_MODE or CHS_MODE

    } SDInfo;

     

    typedef struct

    {

        unsigned char bootable;

        unsigned char partitionId;

     

        int     C_start;

        int     H_start;

        int     S_start;

     

        int     C_end;

        int     H_end;

        int     S_end;

     

        int     block_start;

        int     block_count;

        int     block_end;

    } PartitionInfo;

     

    /////////////////////////////////////////////////////////////////

    int calc_unit(int length, SDInfo sdInfo)

    {

        if (sdInfo.addr_mode == CHS_MODE)

            return ( (length / BLOCK_SIZE / sdInfo.unit + 1 ) * sdInfo.unit);

     

        else

            return ( (length / BLOCK_SIZE) );

    }

     

    /////////////////////////////////////////////////////////////////

    void encode_chs(int C, int H, int S, unsigned char *result)

    {

        *result++ = (unsigned char) H;

        *result++ = (unsigned char) ( S + ((C & 0x00000300) >> 2) );

        *result   = (unsigned char) (C & 0x000000FF);

    }

     

    /////////////////////////////////////////////////////////////////

    void encode_partitionInfo(PartitionInfo partInfo, unsigned char *result)

    {

        *result++ = partInfo.bootable;

     

        encode_chs(partInfo.C_start, partInfo.H_start, partInfo.S_start, result);

        result +=3;

     

        *result++ = partInfo.partitionId;

     

        encode_chs(partInfo.C_end, partInfo.H_end, partInfo.S_end, result);

        result += 3;

     

        *((int *)result) = partInfo.block_start;

        result += 4;   

       

        *((int *)result) = partInfo.block_count;

    }

     

    /////////////////////////////////////////////////////////////////

    void get_SDInfo(int block_count, SDInfo *sdInfo)

    {

        int C, H, S;

     

        int C_max = 1023, H_max = 255, S_max = 63;

        int H_start = 1, S_start = 1;

        int diff_min = 0, diff = 0;

       

        if(block_count >= _8_4GB)

            sdInfo->addr_mode = LBA_MODE;

        else

            sdInfo->addr_mode = CHS_MODE;

     

        if (sdInfo->addr_mode == CHS_MODE)

        {

            diff_min = C_max;

     

            for (H = H_start; H <= H_max; H++)

                for (S  = S_start; S <= S_max; S++)

                {

                    C = block_count / (H * S);

     

                    if ( (C <= C_max) )

                    {

                        diff = C_max - C;

                        if (diff <= diff_min)

                        {

                            diff_min = diff;

                            sdInfo->C_end = C;

                            sdInfo->H_end = H;

                            sdInfo->S_end = S;

                        }

                    }

                }

        }

        else

        {

            sdInfo->C_end = 1023;

            sdInfo->H_end = 254;

            sdInfo->S_end = 63;

        }

     

        sdInfo->C_start         = 0;

        sdInfo->H_start         = 1;

        sdInfo->S_start         = 1;

     

        sdInfo->total_block_count   = block_count;

        sdInfo->available_block     = sdInfo->C_end * sdInfo->H_end * sdInfo->S_end;

        sdInfo->unit            = sdInfo->H_end * sdInfo->S_end;

    }

     

    /////////////////////////////////////////////////////////////////

    void make_partitionInfo(int LBA_start, int count, SDInfo sdInfo, PartitionInfo *partInfo)

    {

        int     temp = 0;

        int     _10MB_unit;

       

        partInfo->block_start   = LBA_start;

     

        if (sdInfo.addr_mode == CHS_MODE)

        {

            partInfo->C_start   = partInfo->block_start / (sdInfo.H_end * sdInfo.S_end);

            temp            = partInfo->block_start % (sdInfo.H_end * sdInfo.S_end);

            partInfo->H_start   = temp / sdInfo.S_end;

            partInfo->S_start   = temp % sdInfo.S_end + 1;

     

            if (count == BLOCK_END)

            {

                _10MB_unit = calc_unit(_10MB, sdInfo);

                partInfo->block_end = sdInfo.C_end * sdInfo.H_end * sdInfo.S_end - _10MB_unit - 1;

                partInfo->block_count   = partInfo->block_end - partInfo->block_start + 1;

       

                partInfo->C_end = partInfo->block_end / sdInfo.unit;

                partInfo->H_end = sdInfo.H_end - 1;

                partInfo->S_end = sdInfo.S_end;

            }

            else

            {

                partInfo->block_count   = count;

       

                partInfo->block_end = partInfo->block_start + count - 1;

                partInfo->C_end     = partInfo->block_end / sdInfo.unit;

       

                temp            = partInfo->block_end % sdInfo.unit;

                partInfo->H_end     = temp / sdInfo.S_end;

                partInfo->S_end     = temp % sdInfo.S_end + 1;

            }

        }

        else

        {

            partInfo->C_start   = 0;

            partInfo->H_start   = 1;

            partInfo->S_start   = 1;

     

            partInfo->C_end     = 1023;

            partInfo->H_end     = 254;

            partInfo->S_end     = 63;

       

            if (count == BLOCK_END)

            {

                _10MB_unit = calc_unit(_10MB, sdInfo);

                partInfo->block_end = sdInfo.total_block_count - _10MB_unit - 1;

                partInfo->block_count   = partInfo->block_end - partInfo->block_start + 1;

     

            }

            else

            {

                partInfo->block_count   = count;

                partInfo->block_end = partInfo->block_start + count - 1;

            }

        }

    }

     

    /////////////////////////////////////////////////////////////////

    int get_sd_block_count(char *devicefile)

    {

        FILE    *fp;

        char    buf[128];

     

        int block_count = 0;

        int nbytes = 0;

     

        char *t = "/sys/block/";

        char sd_size_file[64];

     

        strcpy(sd_size_file, t);

        strcat(sd_size_file, &devicefile[5]);

        strcat(sd_size_file, "/size");

     

        fp = fopen(sd_size_file, "rb");

        nbytes = fread(buf, 1, 128, fp);

        fclose(fp);

     

        block_count = atoi(buf);

       

        return block_count;

    }

     

     

    /////////////////////////////////////////////////////////////////

    int main(int argc, char *argv[])

    {

        FILE        *fp;

     

        int     total_block_count;

        int     block_start = 0, block_offset = 0;

     

        SDInfo      sdInfo;

        PartitionInfo   partInfo[4];

     

        unsigned char   mbr[512];

     

        if (argc != 2)

        {

            printf("Usage: sd_fdisk <device_file> ");

            return -1;

        }

    ///////////////////////////////////////////////////////////

        memset((unsigned char *)&sdInfo, 0x00, sizeof(SDInfo));

     

    ///////////////////////////////////////////////////////////

        total_block_count = get_sd_block_count(argv[1]);

        get_SDInfo(total_block_count, &sdInfo);

    /*

    ///////////////////////////////////////////////////////////

    // 반드시 Unit단위로 먼저 계산한다.

        block_start = calc_unit(_10MB, sdInfo);

        block_offset    = calc_unit(_100MB, sdInfo);

     

    ///////////////////////////////////////////////////////////

        partInfo[0].bootable    = 0x00;

        partInfo[0].partitionId = 0x83;

     

        make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[0]);

     

    ///////////////////////////////////////////////////////////

        block_start += block_offset;

       

        partInfo[1].bootable    = 0x00;

        partInfo[1].partitionId = 0x83;

     

        make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[1]);

     

    ///////////////////////////////////////////////////////////

        block_start += block_offset;

        partInfo[2].bootable    = 0x00;

        partInfo[2].partitionId = 0x83;

     

        make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[2]);

    */

    ///////////////////////////////////////////////////////////

    //  block_start += block_offset;

        block_start = calc_unit(_10MB, sdInfo);

     

        block_offset += BLOCK_END;

        partInfo[3].bootable    = 0x00;

        partInfo[3].partitionId = 0x0C;

     

        make_partitionInfo(block_start, BLOCK_END, sdInfo, &partInfo[3]);

     

    ///////////////////////////////////////////////////////////

        memset(mbr, 0x00, sizeof(mbr));

        mbr[510] = 0x55; mbr[511] = 0xAA;

     

    //  encode_partitionInfo(partInfo[0], &mbr[0x1CE]);

    //  encode_partitionInfo(partInfo[1], &mbr[0x1DE]);

    //  encode_partitionInfo(partInfo[2], &mbr[0x1EE]);

        encode_partitionInfo(partInfo[3], &mbr[0x1BE]);

       

        fp = fopen("sd_mbr.dat", "wb");

        fwrite(mbr, 1, sizeof(mbr), fp);

        fclose(fp);

     

        return 0;

    }

        4.4sd_fusing.sh

    #

    # Copyright (C) 2011 Samsung Electronics Co., Ltd.

    #              http://www.samsung.com/

    #

    # This program is free software; you can redistribute it and/or modify

    # it under the terms of the GNU General Public License version 2 as

    # published by the Free Software Foundation.

    #

    ####################################

     

    if [ -z $1 ]

    then

        echo "usage: ./sd_fusing.sh <SD Reader's device file>"

        exit 0

    fi

     

    if [ -b $1 ]

    then

        echo "$1 reader is identified."

    else

        echo "$1 is NOT identified."

        exit 0

    fi

     

    ####################################

    #<verify device>

     

    BDEV_NAME=`basename $1`

    BDEV_SIZE=`cat /sys/block/${BDEV_NAME}/size`

     

    if [ ${BDEV_SIZE} -le 0 ]; then

        echo "Error: NO media found in card reader."

        exit 1

    fi

     

    if [ ${BDEV_SIZE} -gt 32000000 ]; then

        echo "Error: Block device size (${BDEV_SIZE}) is too large"

        exit 1

    fi

     

    ####################################

    # check files

     

     

     

    ####################################

    # fusing images

     

    signed_bl1_position=1

    bl2_position=17

    uboot_position=49

    tzsw_position=705

     

    #<BL1 fusing>

    echo "---------------------------------------"

    echo "BL1 fusing"

    dd iflag=dsync oflag=dsync if=./E4412_N.bl1.bin of=$1 seek=$signed_bl1_position

     

    #<tiny4412-spl.bin fusing>

    echo "---------------------------------------"

    echo "tiny4412-spl.bin fusing"

    dd iflag=dsync oflag=dsync if=./spl/tiny4412-spl.bin of=$1 seek=$bl2_position

     

    #<u-boot fusing>

    #echo "---------------------------------------"

    #echo "u-boot fusing"

    #dd iflag=dsync oflag=dsync if=${E4412_UBOOT} of=$1 seek=$uboot_position

     

    #<TrustZone S/W fusing>

    #echo "---------------------------------------"

    #echo "TrustZone S/W fusing"

    #dd iflag=dsync oflag=dsync if=./E4412_tzsw.bin of=$1 seek=$tzsw_position

     

    #<flush to disk>

    sync

     

    ####################################

    #<Message Display>

    echo "---------------------------------------"

    echo "U-boot image is fused successfully."

    echo "Eject SD card and insert it again."

     

    5u-boot根目录下添加编译脚本文件build-tiny4412.sh

    echo "*******clean*********"

    make distclean

     

    echo "------------config tiny4412------------"

    make ARCH=arm tiny4412_defconfig

     

    echo "----------------building--------------------"

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

     

    u-boot根目录下执行build-tiny4412.sh编译完成后,会生成spl/tiny4412-spl.bin,通过SD卡烧写脚本sd_fusing.shE4412_N.bl1.bintiny4412-spl.bin烧写到相应的位置。把SD卡插到tiny4412开发板的SD卡槽上,选择从SD卡启动,开发板上电后应该可以看到点亮了相应的LED灯。

     

     

     

     

     

     

     

     

  • 相关阅读:
    [Install] TeamViewer
    [2017
    [2017 ACL] 对话系统
    [2018 ACL Short and System] 对话系统
    Git分支创建与合并
    Git常用命令
    JSONObject转换分析
    数据库行锁实现
    Jenkins安装
    Tomcat热部署,Web工程中线程没有终止
  • 原文地址:https://www.cnblogs.com/LoTGu/p/6078989.html
Copyright © 2011-2022 走看看