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\n", 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\n",

                        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\n",

                        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\n",

 

 

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>\n");

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

 

 

 

 

 

 

 

 

posted @ 2016-11-18 20:04  LoTGu  阅读(1692)  评论(0编辑  收藏  举报