S5P6818裸机开发(2)-S5P6818 Boot Header解析

1、S5P6818 Boot Header

 手册上对Boot Header部分是这么描述的,所有的启动模式都会检查512字节的引导头,引导头假设第一次接收或者从启动设备都是加载到SRAM中,地址为0xFFFF0000。首先,当接收到512字节时,签名值必须是0x4849534E,如果不相等,则会从下一个启动设备重新启动。

意思就是,在你的程序前面必须有512字节的指定数据,这其实是厂家提供的一个文件,你只需把这些数据添加到你的bin文件之前

2、Boot Header中都有什么

在我的这块开发板提供的uboot源码中,找到了这个文件 “nsih.txt”,这个虽然是个txt文件,但里面的有效内容都是机器码,//开头的均为注释,其他的为有效部分。简单来说,你只需要通过文件操作把你的bin文件和这个里面的机器码组合到一个文件即可,事实是可不止这一个文件,这里之所以这么说,是因为这一个文件已经能够满足我们简单的裸机开发,后续的文章会更加详细全面的讲解。下面我们来看一下nsih.txt都描述了什么

//------------------------------------------------------------------------------							
//	Copyright (C) 2012 Nexell Co., All Rights Reserved						
//	Nexell Co. Proprietary < Confidential						
// 							
//	NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE						
//	AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING						
//	BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS						
//	FOR A PARTICULAR PURPOSE.						
// 							
//	Module		: Boot Header				
//	File		: NSIH.txt				
//	Description	: system initialize info					
//	Author		: Firmware Team				
//	History		:				
//				Hans 2014.01.13 Excel Generator			
//				Hans 2013.06.23 Create			
//------------------------------------------------------------------------------							
// Excel sheet version - 0.3.00							
//------------------------------------------------------------------------------							
// This must be synchronized with SecondBoot.h 							
//------------------------------------------------------------------------------ 							
// Nexell System Infomation Header 							
//------------------------------------------------------------------------------ 							
// Vector Code Area 							
E59FF018	// 0x000 : MOV PC, ResetV 						
E59FF018	// 0x004 : MOV PC, UndefV 						
E59FF018	// 0x008 : MOV PC, SWIV 						
E59FF018	// 0x00C : MOV PC, PAbortV 						
E59FF018	// 0x010 : MOV PC, DAbortV 						
E59FF018	// 0x014 : MOV PC, NotUsed 						
E59FF018	// 0x018 : MOV PC, IRQV 						
E59FF018	// 0x01C : MOV PC, FIQV 						
							
FFFF0200	// 0x020 : SRAMBASE + Header 						
FFFF0204	// 0x024 : SRAMBASE + Header 						
FFFF0208	// 0x028 : SRAMBASE + Header 						
FFFF020C	// 0x02C : SRAMBASE + Header 						
FFFF0210	// 0x030 : SRAMBASE + Header 						
FFFF0214	// 0x034 : SRAMBASE + Header 						
FFFF0218	// 0x038 : SRAMBASE + Header 						
FFFF021C	// 0x03C : SRAMBASE + Header 						
							
//------------------------------------------------------------------------------ 							
// Main Bootloader Load Info 							
//------------------------------------------------------------------------------ 							
00008000	// 0x040 : Device Read Address from 2ndboot Device.						
00040000	// 0x044 : Load Size for 2ndboot.						
FFFF0000	// 0x048 : Load Address for 2ndboot.						
FFFF0000	// 0x04C : Launch Address for 2ndboot.						
							
00000000	// 0x050	[7:0] - Channel number					
00000000	// 0x054	Boot From SDMMC	[31:24] - 0: USB, 1: SPI, 2: NAND, 3:SDMMC, 4: SDFS				
00000000	// 0x058						
							
//------------------------------------------------------------------------------							
// CLKPWR registers							
//------------------------------------------------------------------------------							
100CC801	// 0x05C : PLL0		800MHz	P:3	M:200	S:1	
100CC801	// 0x060 : PLL1		800MHz	P:3	M:200	S:1	
100CC301	// 0x064 : PLL2		780MHz	P:3	M:195	S:1	K:0
100CC801	// 0x068 : PLL3		800MHz	P:3	M:200	S:1	K:0
							
00000104	// 0x06C : PLL2 SPREAD 						
00000104	// 0x070 : PLL3 SPREAD 						
							
00000601	// 0x074 : CPU G0		PLL1	/FCLK:800	/HCLK:200		
00000208	// 0x078 : BUS		PLL0	/BCLK:400	/PCLK:200		
00208003	// 0x07C : MEM		PLL3	/MDCLK:800	/MCLK:800	/MBCLK:400	/MPCLK:200
00000208	// 0x080 : GR3D		PLL0	/GR3DBCLK:400			
00000208	// 0x084 : MPEG		PLL0	/MPEGBCLK:400	/MPEGPCLK:200		
00000208	// 0x088 : DISP		PLL0	/DISPBCLK:400	/DISPPCLK:200		
00000028	// 0x08C : HDMI		PLL0	/HDMIPCLK:133.333333333333			
00000601	// 0x090 : CPU G1		PLL1	/FCLK:800	/HCLK:200		
00000208	// 0x094 : CCI4		PLL0	/CCI4BCLK:400	/CCI4PCLK:200		
							
//------------------------------------------------------------------------------							
// MCU-D registers							
//------------------------------------------------------------------------------							
// Mem Controller Configuration 							
03100301	// 0x098	/Chip Num:1	/Chip Row:15	/Bus Width:16	/Chip Col:10		
004007C0	// 0x09C	256MB x 2ea (16bit) x 1CS					
06000B08	// 0x0A0	/CWL:8	/CL:11	/MR1_AL:0	/MR0_WR:6		
							
// DDR PHY delay timing Configuration 							
0C0C0C0C	// 0x0A4						
04040404	// 0x0A8						
							
// DDR AC Timing Configuration 							
0000401B	// 0x0AC	/tPZQ:16411					
00620618	// 0x0B0	/Refresh Interval:7.8us					
6836650E	// 0x0B4	/tRFC:104	/tRRD:3	/tRP:6	/tRCD:6	/tRC:20	/tRAS:14
3630580B	// 0x0B8	/tWTR:3	/tWR:6	/tRTP:3			
31000A26	// 0x0BC	/tFAW:12	/tXSR:256	/tXP:10	/tCKE:2		
							
// DDR3 device - Drive strength value.							
00020102	// 0x0C0	[23:16] MR1_RTT_Nom - 001: RZQ/4, 010: RZQ/2, 011: RZQ/6, 100: RZQ/12, 101: RZQ/8, [15:0] MR1_ODS - 0: RZQ/6, 1 : RZQ/7, [7:0] MR2_RTT_WR - 0: ODT disable, 1: RZQ/4, 2: RZQ/2					
							
// DDR PHY Controller - Drive strength value.							
06060606	// 0x0C4	[31:24] Byte3, [23:16] Byte2, [15:8] Byte1, [7:0] Byte0 - 240ohm / (n + 1), n = (1 ~ 7)					
06060606	// 0x0C8	[31:24] CA, [23:16] CS, [15:8] CKE, [7:0] CK - 240ohm / (n + 1), n = (1 ~ 7)					
00000104	// 0x0CC	[15:8] ZQ_ODT, [7:0] ZQ_DDS - 240ohm / (n + 1), n = (1 ~ 7)					
							
// Leveling & Training.							
00000004	// 0x0D0	WR_CAL[4], RD_CAL[3], GT_LVL[2], CA_CAL[1], WR_LVL[0]					
							
//------------------------------------------------------------------------------ 							
// STUB							
//------------------------------------------------------------------------------ 							
00000000	// 0x0D4						
00000000	// 0x0D8						
00000000	// 0x0DC						
00000000	// 0x0E0						
00000000	// 0x0E4						
00000000	// 0x0E8						
00000000	// 0x0EC						
00000000	// 0x0F0						
00000000	// 0x0F4						
00000000	// 0x0F8						
00000000	// 0x0FC						
00000000	// 0x100						
00000000	// 0x104						
00000000	// 0x108						
00000000	// 0x10C						
00000000	// 0x110						
00000000	// 0x114						
00000000	// 0x118						
00000000	// 0x11C						
00000000	// 0x120						
00000000	// 0x124						
00000000	// 0x128						
00000000	// 0x12C						
00000000	// 0x130						
00000000	// 0x134						
00000000	// 0x138						
00000000	// 0x13C						
00000000	// 0x140						
00000000	// 0x144						
00000000	// 0x148						
00000000	// 0x14C						
00000000	// 0x150						
00000000	// 0x154						
00000000	// 0x158						
00000000	// 0x15C						
00000000	// 0x160						
00000000	// 0x164						
00000000	// 0x168						
00000000	// 0x16C						
00000000	// 0x170						
00000000	// 0x174						
00000000	// 0x178						
00000000	// 0x17C						
00000000	// 0x180						
00000000	// 0x184						
00000000	// 0x188						
00000000	// 0x18C						
00000000	// 0x190						
00000000	// 0x194						
00000000	// 0x198						
00000000	// 0x19C						
00000000	// 0x1A0						
00000000	// 0x1A4						
00000000	// 0x1A8						
00000000	// 0x1AC						
00000000	// 0x1B0						
00000000	// 0x1B4						
00000000	// 0x1B8						
00000000	// 0x1BC						
00000000	// 0x1C0						
00000000	// 0x1C4						
00000000	// 0x1C8						
00000000	// 0x1CC						
00000000	// 0x1D0						
00000000	// 0x1D4						
00000000	// 0x1D8						
00000000	// 0x1DC						
00000000	// 0x1E0						
00000000	// 0x1E4						
00000000	// 0x1E8						
00000000	// 0x1EC						
00000000	// 0x1F0						
00000000	// 0x1F4						
00000000	// 0x1F8						
							
//------------------------------------------------------------------------------ 							
// Signature							
//------------------------------------------------------------------------------ 							
4849534E	// 0x1FC	"""NSIH"""					

第一部分:Vector Code Area

 这一部分是异常向量表,熟悉ARM架构的都应该清楚,ARM异常共有9种,分别是复位异常、未定义指令异常、软件中断异常、预取指终止异常、读取数据终止异常、保留、中断异常、快中断异常。这几种异常分别位于CPU的0地址起始位置,当发生异常时,就会跳转到对应的位置执行。

例如未定义指令异常 位于CPU地址 0x04处,当CPU读到一个未定义指令时,CPU会自动跳转到0x04处执行该处的指令,从而可以进入我们之前设计好的处理函数。

关于异常向量表,我们会在后期的文章中继续讲述,这里只是做一下简单说明。

第二部分:硬件参数

从异常向量表往下的部分就是配置参数,包括用户程序的起始地址,重定向的地址和大小,CPU的时钟参数,SDRAM的初始化参数等,当然还有一个非常重要的签名值 0x4849534E,这个签名值位于这512字节的最后4个字节,非常重要,当CPU没有检测到这个签名值时,就会自动转向下一个boot device。

3、一个简单的裸机程序编写

硬件:S5P6818开发板 LED引脚:GPIOE13 ,低电平亮

汇编代码:

/*点亮LED
**LED1 GPIOE13
**低电平点亮,高电平熄灭
*/

#define GPIOEOUT 0xC001E000
#define GPIOEOUTENB 0xC001E004
#define GPIOEALTFN0 0xC001E020


.text
.global _start
_start:
b 	reset
ldr	pc, _undefined_instruction
ldr	pc, _software_interrupt
ldr	pc, _prefetch_abort
ldr	pc, _data_abort
ldr	pc, _not_used
ldr	pc, _irq
ldr	pc, _fiq

_undefined_instruction:	.word undefined_instruction
_software_interrupt:	.word software_interrupt
_prefetch_abort:	.word prefetch_abort
_data_abort:		.word data_abort
_not_used:		.word not_used
_irq:			.word irq
_fiq:			.word fiq


reset:
    //初始化GPIOE13 为输出引脚
    ldr r0,=GPIOEALTFN0
    ldr r1,[r0]
    mov r2,#(3<<26)
    bic r1,r1,r2
    str r1,[r0]

    ldr r0,=GPIOEOUTENB
    ldr r1,[r0]
    orr r1,#(1<<13)
    str r1,[r0]

    //灭灯
    ldr r0,=GPIOEOUT
    ldr r1,[r0]
    orr r1,#(1<<13)
    str r1,[r0]

    b loop

undefined_instruction:
    b .
software_interrupt:
    b .
prefetch_abort:
    b .
data_abort:
    b .
not_used:
    b .
irq:
    b .
fiq:
    b .

loop:
    //亮灯
    ldr r0,=GPIOEOUT
    ldr r1,[r0]
    bic r1,#(1<<13)
    str r1,[r0]
    ldr r0,=9000000 //通过r0传递参数
    bl delay         //bl:跳转到子程序,并保存返回地址到lr

    //灭灯
    ldr r0,=GPIOEOUT
    ldr r1,[r0]
    orr r1,#(1<<13)
    str r1,[r0]
    ldr r0,=9000000
    bl delay  

    b loop

//延时
delay:
    sub r0,#1 //减1
    cmp r0,#0 //和0比较
    bne delay
    moveq pc,lr
.end

Makefile:

all:
	arm-linux-gcc led.S -c -march=armv4t -o led.o -nostdlib
	arm-linux-ld -Ttext 0x0 led.o -o led.elf
	arm-linux-objcopy -O binary led.elf led.bin
	arm-linux-objdump -D  led.elf > led.dis



clean:
	rm *.o *.elf *.bin *.dis

.PHONY:clean

make产生的led.bin文件

 提前准备好的boot header:从这个文件bootled.bin中提取了前512字节

 用户代码的bin文件和boot header的bin文件都准备好了,这里采用手动拼接的方法,也可以通过编程来实现,因为后面我们还会采用程序的方法来连接boot header和2ndboot,所以这里简单使用手动拼接的方法,bin编辑软件使用Hex Editor或者UltraEdit都可以,这里我使用Hex Editor

1、新建一个空白的bin文件

2、复制boot header部分,粘贴到新建的bin文件中0地址处

3、复制led.bin用户代码,紧接着在0x200位置粘贴

4、保存为led_m.bin到工程目录,就可以使用了

到此,一个简单的裸机程序就好了,要想在6818开发板上运行了,下一步就是烧写到SD卡,这个我们下一篇文章再讲。

 本篇中的代码文件:

        链接:https://pan.baidu.com/s/1Mm3CL2cMWKZTn45tQAul0w 
        提取码:x4qk

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值