参考博文:
ITOP4412裸机开发—LED
tiny4412裸机程序之点灯
这是我的第一篇博客,不足之处还请批评指正,涉及侵权问题请与我联系,转载注明出处即可。
本文介绍用SD卡启动的裸机编程,学会这个裸机编程,移植uboot之类的也不再话下了,由于Exynos4412这个芯片有两种封装方式pop和scp,这两个芯片对应着不同的BL1,盲目烧写错的BL1可能实现不了目标,详细实现功能请向下翻阅,博主的板子是迅为的精英板4412 pop1G
封装。
图片是迅为提供的uboot文档中截的,从图中看开发板在上电时会经过以上三个步骤,就是图中的圆圈中的123了,第一步,开发板上电会去执行IROM,这个IROM会由OM的控制决定从哪个介质开始引导加载程序。
如图由五位二进制编码决定,详细不再讲,我们这里讲SD卡启动,就将开发板的拨码开关拨到SD卡启动。第二步,程序会从SD卡中加载第一段代码BL1到IRAM中;第三步,OS系统会被加载到DRAM中,至此引导结束。
但是这个地方有个问题,第一步和第二步都对,但是第三步,BL1会从SD卡中的第18个扇区开始读取16K代码到internal SRAM中并跳转到这段代码的起始位置。如下图第一个:
加载的这个BL2实际上是uboot的前16K,uboot后面的大部分代码会被BL2加载到DRAM中,然后跳转到DRAM中uboot开始的位置开始执行,我们这里讲裸机程序,实际上就是把BL2替换成裸机程序,但是这个裸机程序必须小于14K,为什么要小于14K呢?如下图BL2的结构:
如图BL2的结构实际上是BL2的程序+4Byte的校验和+256Byte的签名+补全0=16K,因为BL1加载BL2到IRAM后要验证校验和是否正确,所以我们写好的裸机程序最终还要加上4字节的校验和后等于14K,官方提供的uboot中有制作校验和的源码,后面会介绍。
新建文件夹及文件
mkdir leds
cd leds
touch start.S s3c4412_gpio.h myboot.lds Makefile mkbl2.c
这个汇编代码0x1002330c是PS_HOLD_CONTROL寄存器,保证电源管理芯片正常工作,0x11000c08是GPX0组控制上下拉的寄存器,有个ONO(GPX0_2)在控制电源管理。
#include "s3c4412_gpio.h"
.global _start
.word 0x2000
.word 0x0
.word 0x0
.word 0x0
_start:
ldr r10,=0x1002330c
ldr r11,[r10]
orr r11,r11,#0x300
str r11,[r10]
ldr r10,=0x11000c08
ldr r11,=0x0
str r11,[r10]
ldr r10,=GPL2CON
mov r11,#(0x01<<0)
str r11,[r10]
ldr r10,=GPK1CON
mov r11,#(0x01<<4)
str r11,[r10]
1:
ldr r10,=GPK1DAT
mov r11,#0x02
str r11,[r10]
ldr r10,=GPL2DAT
mov r11,#0x01
str r11,[r10]
b 1b
#ifndef S3C4412_GPIO_H
#define S3C4412_GPIO_H
#define GPX1CON (0x11000000+0x0c20)
#define GPX1DAT (0x11000000+0x0c24)
#define GPX1PUD (0x11000000+0x0c28)
#define GPX1DRV (0x11000000+0x0c2c)
#define GPK1CON (0x11000000+0x0060)
#define GPK1DAT (0x11000000+0x0064)
#define GPK1PUD (0x11000000+0x0068)
#define GPK1DRV (0x11000000+0x006c)
#define GPL2CON (0x11000000+0x0100)
#define GPL2DAT (0x11000000+0x0104)
#define GPL2PUD (0x11000000+0x0108)
#define GPL2DRV (0x11000000+0x010c)
#endif
CROSS_COMPILE = arm-linux-gnueabihf-
%.o : %.S
$(CROSS_COMPILE)gcc -o $@ $< -c
%.o : %.c
$(CROSS_COMPILE)gcc -o $@ $< -c
.PHONY: all
all : led.elf
led.elf : start.o myboot.lds
$(CROSS_COMPILE)ld -T myboot.lds -o led.elf $^
$(CROSS_COMPILE)objcopy -O binary led.elf led.bin
$(CROSS_COMPILE)objdump -D led.elf > led.dis
.PHONY : clean
clean:
rm -rf *.o *.elf *.bin *.dis
SECTIONS
{
. = 0x02023400;
.text : {
start.o
* (.text)
}
.rodata ALIGN(4) : {
* (.rodata*)
}
.data ALIGN(4) : {
* (.data*)
}
.bss ALIGN(4) : {
* (.bss)
* (COMMON)
}
}
修改完上诉文件使用指令make生成led.bin下面要用到
#include
#include
#include
int main (int argc, char *argv[])
{
FILE *fp;
unsigned char src;
char *buf, *a;
int buf_len;
int nbytes, file_len;
unsigned int checksum = 0;
int i;
if (argc != 4) {
printf("Usage: mkbl2 );
return -1;
}
buf_len = atoi(argv[3]);
buf = (char *)malloc(buf_len);
memset(buf, 0x00, buf_len);
fp = fopen(argv[1], "rb");
if( fp == NULL) {
printf("source file open error\n");
free(buf);
return -1;
}
fseek(fp, 0L, SEEK_END);
file_len = ftell(fp);
fseek(fp, 0L, SEEK_SET);
nbytes = fread(buf, 1, file_len, fp);
if (nbytes != file_len) {
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, buf_len, fp);
if (nbytes != buf_len) {
printf("destination file write error\n");
free(buf);
fclose(fp);
return -1;
}
free(buf);
fclose(fp);
return 0;
}
用GCC编译工具编译上诉源码生成mkbl2校验和制作工具
gcc mkbl2.c -o mkbl2
制作BL2
./mkbl2 led.bin bl2.bin 14336
用ssh把bl1(E4412.S.BL1.SSCR.EVT1.1.bin)上传到leds文件夹内
插入SD卡并查看自己的盘符节点,我的是sdb,所以下面会用sdb,根据自己的实际情况更改盘符
df -l
清零SD卡中前1M的内容
dd if=/dev/zero of=/dev/sdb bs=512 seek=1 iflag=dsync oflag=dsync count=2048
烧写BL1
dd if=E4412.S.BL1.SSCR.EVT1.1.bin of=/dev/sdb bs=512 seek=1 iflag=dsync oflag=dsync
烧写BL2
dd if=bl2.bin of=/dev/sdb bs=512 seek=17 iflag=dsync oflag=dsync
SD卡制作完毕,拔掉SD插入开发板观察现象
方法2非常简单,使用shell脚本,一行指令制作BL2并烧录进SD卡,下载sd_fuse压缩包,解压后用ssh上传到leds文件夹内,插入SD卡使用下列脚本命令烧录。
cd sd_fuse/itop4412
./sd_fusing.sh /dev/sdb ../../led.bin
可以加入群聊:667039215找群主获取
CSDN获取: leds压缩包
sd_fuse获取:sd_fuse压缩包
github下载:git clone https://github.com/HOU1354696096/ITOP4412.git