Tiny6410 SD卡启动裸机程序

1. 启动流程

根据"S3C6410 Internal ROM Booting"手册,6410的启动流程如下:
在这里插入图片描述
① iROM(BL0)自动进行初始化启动:初始化系统时钟、D-TCM,、设备控制器、启动设备(SD/MMC Card, OneNand, Nand)。
② iROM将启动设备中的bootloader中的4KB代码加载到SRAM中,这8KB boot loader叫做BL1。
③ BL1: 初始化系统时钟、串口、SDRAM,然后将剩余的bootloader(BL2)加载到SDRAM中。
④ 最后,跳转到BL2的起始地址,为用户系统做好环境准备。

2. SD卡启动设备的块分配

在这里插入图片描述
博主的启动设备为SDHC卡(8GB), 代码应该拷贝到倒数1042个扇区(sectors)开始的地方。 用fdisk命令查看一下SD卡的扇区:

[root@localhost 22]# fdisk -l

Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00053920

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      616447      307200   83  Linux
/dev/sda2          616448      618495        1024   83  Linux
/dev/sda3          618496    37814271    18597888   83  Linux
/dev/sda4        37814272    41943039     2064384    5  Extended
/dev/sda5        37816320    41943039     2063360   82  Linux swap / Solaris

Disk /dev/sdb: 7948 MB, 7948206080 bytes
255 heads, 63 sectors/track, 966 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe62818a6

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    15521791     7759872    c  W95 FAT32 (LBA)

2.1 根据扇区计算拷贝位置

计算一下代码应该拷贝的扇区位置为: 15523840 - 1042 = 15522798
使用dd命令将事先准备好的LED闪烁程序下载到SD卡的15522798扇区位置
注意:一定要带“iflag=dsync oflag=dsync”,否则程序不会运行!

[root@localhost 22.sdboot]# dd iflag=dsync oflag=dsync if=led.bin of=/dev/sdb seek=15522798 bs=512
0+1 records in
0+1 records out
162 bytes (162 B) copied, 0.0246958 s, 6.6 kB/s

2.2 根据字节计算拷贝位置

计算一下代码应该拷贝的字节位置:7948206080 - 1042*512 = 7947672576
使用dd命令将事先准备好的LED闪烁程序下载到SD卡的7947672576字节位置:
注意:一定要带“iflag=dsync oflag=dsync”,否则程序不会运行!

[root@localhost 22.sdboot]# dd iflag=dsync oflag=dsync if=led.bin of=/dev/sdb seek=7947672576 bs=1
162+0 records in
162+0 records out
162 bytes (162 B) copied, 0.820881 s, 0.2 kB/s

将SD卡插入开发板,将开关拨到SDBOOT位置,启动电源开关,可以看到4个LED闪烁。

3. 代码

3.1 start.S

/* start.S */

.global _start
_start: 	
	//外设基地址及大小告诉CPU
	ldr r0, =0x70000000		//ldr: load
	orr r0, r0, #0x13 		//0x13=b10011=256M, 参见arm1176jzfs内核参考手册Page3-130
	mcr p15,0,r0,c15,c2,4   //把r0的值(包括了外设基地址+外设大小)告诉cpu
	//关看门狗
	ldr r0, =0x7E004000		//watch dog timer base address
	mov r1, #0
	str r1, [r0]			//disable watch dog.  str: Store	
	//设置GPKCON0
	ldr r0, =0x7F008800		//GPKCON0 address
	ldr r1, =0x11110000		//GPK_4,5,6,7设置为输出, GPKn设置为0001时,GPKn引脚设置为输出
	str r1, [r0]
	mov r2, #0x1000			//LED循环计数
led_blink:
	ldr r0, =0x7F008808		//GPKDAT address
	mov r1, #0xF0			//设置GPK_4,5,6,7为高电平,Led熄灭
	str r1, [r0]	
	bl  delay	
	ldr r0, =0x7F008808
	mov r1, #0x00			//设置GPK_4,5,6,7为低电平,Led点亮
	str r1, [r0]	
	bl  delay
	sub r2, r2, #1			//r2=r2-1
	cmp r2, #0
	bne led_blink			//如果r2!=0,则跳转至led_blink处执行。bne:Branch Not Equal		
halt:
	b   halt				//b: Branch
delay:
	mov r0, #0x1000000	
delay_loop:		
	sub r0, r0, #1
	cmp r0, #0
	bne delay_loop
	mov pc, lr				//从delay子程序返回

3.2 链接脚本

/* led.lds */

SECTIONS
{
	. = 0x0C000000;			/*BL1 start address*/
	.text : {
				start.o
				* (.text)
	}
	.data : {
				* (.data)
	}
	.bss_start = .;
	.bss : {
				* (.bss)
	}
	.bss_end = .;
}

注意,BL1的起始地址为0x0C000000(见Memory Map)
在这里插入图片描述

3.3 Makefile

led.bin: start.o
	arm-linux-ld -Tled.lds -o led.elf $^
	arm-linux-objcopy -O binary led.elf led.bin
	arm-linux-objdump -D led.elf > led_elf.dis
%.o : %.S
	arm-linux-gcc -o $@ $< -c
%.o : %.c
	arm-linux-gcc -o $@ $< -c 
clean:
	rm *.o *.elf *.bin *.dis  -rf
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值