一、裸机开发,点亮led
参考文章
1.准备程序清单
1-1.烧写SD卡的工具
jw@pc:sd_fuse$ ls
Makefile mkbl2 sd_fdisk sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
jw@pc:sd_fuse$ ls tiny4412/
bl2.bin E4412_N.bl1.bin E4412_tzsw.bin fast_fuse.sh sd_fusing.sh
1-2.裸机程序
jw@pc:10th$ ls
led.bin led.dis led.elf led.lds led.o led.S Makefile sd_fuse
/* led.S */
.text
.globl _start
_start:
ldr r0, =0x110002E0 //GPM4CON Register
ldr r1, =0x00001111 //Configurate GPM4_0<A1>GPM4_1<A2>GPM4_2<A2>GPM4_3 output
str r1, [r0]
mov r1, #0xF0 //light All led on
ldr r0, =0x110002E4 //GPM4DAT Register
str r1, [r0]
halt_loop:
b halt_loop
/* led.lds */
SECTIONS {
. = 0x02023400; /* 为什么链接地址是0x02023400,这个可以在irom手册上看到。
官方提供的BL1会默认将BL2加载到这个位置。 */
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data*) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
# Makefile
CC=arm-none-linux-gnueabi-
led.bin : led.S
$(CC)gcc -c -o led.o led.S
$(CC)ld -Tled.lds -N led.o -o led.elf
$(CC)objcopy -O binary -S led.elf led.bin
$(CC)objdump -D -m arm led.elf > led.dis
clean:
rm -f *.dis *.bin *.elf *.o
2.操作过程
2-1.生成可led.bin
jw@pc:10th$ make
arm-none-linux-gnueabi-gcc -c -o led.o led.S
arm-none-linux-gnueabi-ld -Tled.lds -N led.o -o led.elf
arm-none-linux-gnueabi-objcopy -O binary -S led.elf led.bin
arm-none-linux-gnueabi-objdump -D -m arm led.elf > led.dis
jw@pc:10th$ ls
led.bin led.dis led.elf led.lds led.o led.S Makefile sd_fuse
2-2.烧写进SD卡
查找sd卡对应的文件名
jw@pc:10th$ df -h
....省略
/dev/mmcblk0p1 7.3G 1.5G 5.8G 21% /media/jw/FRIENDLYARM
jw@pc:10th$ cd sd_fuse/tiny4412/
jw@pc:tiny4412$ sudo ./sd_fusing.sh /dev/mmcblk0
[sudo] jw 的密码:
/dev/mmcblk0 reader is identified.
Error: u-boot.bin NOT found, please build it & try again.
./sd_fuse/tiny4412/sd_fusing.sh: 50: exit: Illegal number: -1
报错了,提示没有找到u-boot.bin。
但是我只想烧写一个led.bin给bl2区域,并不想烧写uboot。bin,那就还得修改一下脚本文件才行。
jw@pc:tiny4412$ vim ./sd_fusing.sh
在变量E4412_UBOOT的定义那里修改一下,在45行左右。改成:
E4412_UBOOT=$2
保存退出,重新执行sdfuse
我为什么这么修改?没有该变量make就执行不下去,因此用传入参数$2代替。。
因为程序执行不到uboot.bin的位置,所以我也不担心会出什么问题。程序只会执行bl1,再执行bl2。
jw@pc:tiny4412$ sudo ./sd_fusing.sh /dev/mmcblk0 ../../led.bin
[sudo] jw 的密码:
/dev/mmcblk0 reader is identified.
make bl2.bin
Usage: unsupported size
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.0274908 s, 298 kB/s
---------------------------------------
BL2 fusing
dd: 打开'./bl2.bin' 失败: 没有那个文件或目录
---------------------------------------
u-boot fusing
记录了0+1 的读入
记录了0+1 的写出
40 bytes copied, 0.00198806 s, 20.1 kB/s
---------------------------------------
TrustZone S/W fusing
记录了184+0 的读入
记录了184+0 的写出
94208 bytes (94 kB, 92 KiB) copied, 0.384884 s, 245 kB/s
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.
拔出SD卡,插入开发板启动,发现没有led的现象。为什么?
回顾烧写过程打印的信息,可以看到:
......
Usage: unsupported size
......
BL2 fusing
dd: 打开'./bl2.bin' 失败: 没有那个文件或目录
意思是打开bl2.bin出错,导致没有烧写进SD卡。进去sd_fusing.sh里面找到错误信息的出处:
E4412_UBOOT=$2
MKBL2=../mkbl2
....
#<make bl2>
${MKBL2} $(E4412_UBOOT) bl2.bin 14336
上面的意思就是执行脚本命令:…/mkbl2 led.bin bl2.bin 14336
…/mkbl2是什么程序呢?参数都是什么意思呢?回到父目录下,看它的源代码
jw@pc:tiny4412$ cd ..
jw@pc:sd_fuse$ ls
Makefile mkbl2 sd_fdisk sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
jw@pc:sd_fuse$ vim V310-EVT1-mkbl2.c
研究了一下参考文章,找到出错信息所在。意思是:sizeof(led.bin) < 14336 所以出错。修改一下V310-EVT1-mkbl2.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 <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *fp;
unsigned char src;
char *Buf, *a;
int BufLen;
int nbytes, fileLen;
unsigned int checksum = 0;
int i;
if (argc != 4)
{
printf("Usage: mkbl1 <source file> <destination file> <size> \n");
return -1;
}
BufLen = atoi(argv[3]);
Buf = (char *)malloc(BufLen);
memset(Buf, 0x00, BufLen);
fp = fopen(argv[1], "rb");
if( fp == NULL)
{
printf("source file open error\n");
free(Buf);
return -1;
}
fseek(fp, 0L, SEEK_END);
fileLen = ftell(fp);
fseek(fp, 0L, SEEK_SET);
if ( BufLen > fileLen )
{
printf("Usage: unsupported size\n");
free(Buf);
fclose(fp);
return -1;
}
nbytes = fread(Buf, 1, BufLen, fp);
if ( nbytes != BufLen )
{
printf("source file read error\n");
free(Buf);
fclose(fp);
return -1;
}
fclose(fp);
for(i = 0;i < (14 * 1024) - 4;i++)
{
checksum += (unsigned char)(Buf[i]);
}
*(unsigned int*)(Buf+i) = checksum;
fp = fopen(argv[2], "wb");
if (fp == NULL)
{
printf("destination file open error\n");
free(Buf);
return -1;
}
a = Buf;
nbytes = fwrite( a, 1, BufLen, fp);
if ( nbytes != BufLen )
{
printf("destination file write error\n");
free(Buf);
fclose(fp);
return -1;
}
free(Buf);
fclose(fp);
return 0;
}
修改好后,make clean–>make
jw@pc:sd_fuse$ make clean
jw@pc:sd_fuse$ make
jw@pc:sd_fuse$ ls
Makefile mkbl2 sd_fdisk sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
jw@pc:sd_fuse$ vim V310-EVT1-mkbl2.c
重新烧写SD卡
jw@pc:10th$ cd sd_fuse/tiny4412/
jw@pc:tiny4412$ sudo ./sd_fusing.sh /dev/mmcblk0 ../../led.bin
/dev/mmcblk0 reader is identified.
make bl2.bin
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.0262508 s, 312 kB/s
---------------------------------------
BL2 fusing
记录了28+0 的读入
记录了28+0 的写出
14336 bytes (14 kB, 14 KiB) copied, 0.0894957 s, 160 kB/s
---------------------------------------
u-boot fusing
记录了0+1 的读入
记录了0+1 的写出
40 bytes copied, 0.00472071 s, 8.5 kB/s
---------------------------------------
TrustZone S/W fusing
记录了184+0 的读入
记录了184+0 的写出
94208 bytes (94 kB, 92 KiB) copied, 0.360238 s, 262 kB/s
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.
可以看到BL1与BL2都少些成功了。BL2里面就存放着led灯的程序。uboot区域的内容不会被执行,不用管它,之前只是随便找了个bin代替uboot.bin而已。