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灯。

     

     

     

     

     

     

     

     

  • 相关阅读:
    Codeforces467C George and Job
    Codeforces205E Little Elephant and Furik and RubikLittle Elephant and Furik and Rubik
    Codeforce205C Little Elephant and Interval
    51nod1829 函数
    51nod1574 排列转换
    nowcoder35B 小AA的数列
    Codeforce893E Counting Arrays
    gym101612 Consonant Fencity
    CodeForces559C Gerald and Giant Chess
    CodeForces456D A Lot of Games
  • 原文地址:https://www.cnblogs.com/LoTGu/p/6078989.html
Copyright © 2011-2022 走看看