ITOP4412裸機編程-點亮LED燈

參考博文
ITOP4412裸機開發—LED
tiny4412裸機程序之點燈

前言:

       這是我的第一篇博客,不足之處還請批評指正,涉及侵權問題請與我聯繫,轉載註明出處即可。
       本文介紹用SD卡啓動的裸機編程,學會這個裸機編程,移植uboot之類的也不再話下了,由於Exynos4412這個芯片有兩種封裝方式pop和scp,這兩個芯片對應着不同的BL1,盲目燒寫錯的BL1可能實現不了目標,詳細實現功能請向下翻閱,博主的板子是迅爲的精英板4412 pop1G封裝。
博主的板子

啓動原理:

overview
       圖片是迅爲提供的uboot文檔中截的,從圖中看開發板在上電時會經過以上三個步驟,就是圖中的圓圈中的123了,第一步,開發板上電會去執行IROM,這個IROM會由OM的控制決定從哪個介質開始引導加載程序。
編碼方式
       如圖由五位二進制編碼決定,詳細不再講,我們這裏講SD卡啓動,就將開發板的撥碼開關撥到SD卡啓動。第二步,程序會從SD卡中加載第一段代碼BL1到IRAM中;第三步,OS系統會被加載到DRAM中,至此引導結束。
       但是這個地方有個問題,第一步和第二步都對,但是第三步,BL1會從SD卡中的第18個扇區開始讀取16K代碼到internal SRAM中並跳轉到這段代碼的起始位置。如下圖第一個:IRAM結構

       加載的這個BL2實際上是uboot的前16K,uboot後面的大部分代碼會被BL2加載到DRAM中,然後跳轉到DRAM中uboot開始的位置開始執行,我們這裏講裸機程序,實際上就是把BL2替換成裸機程序,但是這個裸機程序必須小於14K,爲什麼要小於14K呢?如下圖BL2的結構:
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

       修改start.S

       這個彙編代碼0x1002330c是PS_HOLD_CONTROL寄存器,保證電源管理芯片正常工作,0x11000c80是GPX0組控制上下拉的寄存器,防止檢測TF是否插入導致復位。

#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

       修改s3c4412_gpio.h

#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

       修改Makefile

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

       修改myboot.lds

SECTIONS
{
	. = 0x02023400;
	.text : {
		start.o
		* (.text)
	}
	.rodata ALIGN(4) : {
		* (.rodata*)
	}

	.data ALIGN(4) : {
		* (.data*)
	}
	.bss ALIGN(4) : {
		* (.bss)
		* (COMMON)
	}
}

修改完上訴文件使用指令make生成led.bin下面要用到

燒錄SD卡:

       方法1:

       修改mkbl2.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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 <source file> <destination file> <size> \n");
        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

sdb
清零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:

方法2非常簡單,使用shell腳本,一行指令製作BL2並燒錄進SD卡,下載sd_fuse壓縮包,解壓後用ssh上傳到leds文件夾內,插入SD卡使用下列腳本命令燒錄。

cd sd_fuse/itop4412
./sd_fusing.sh /dev/sdb ../../led.bin

現象:

LED亮

源碼獲取:

可以加入羣聊:667039215找羣主獲取
CSDN獲取:leds壓縮包
                    sd_fuse壓縮包
github下載:git clone https://github.com/HOU1354696096/ITOP4412.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章