微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 自己写bootloader

自己写bootloader

时间:11-21 来源:互联网 点击:
启动汇编文件

#define S3C2440_MPLL_200MHZ ((0x5c<12)|(0x01<4)|(0x02))

#define S3C2440_MPLL_400MHZ ((0x5c<12)|(0x01<4)|(0x01))

#define MEM_CTL_BASE 0x48000000

.text

.global _start

_start:

// 1、关看门狗 //

ldr r0, =0x53000000

mov r1, #0

str r1, [r0]

// 2、设置系统时钟 //

ldr r0, =0x4c000014

//mov r1, #0x03 // FCLK:HCLK:PCLK=1:2:4, HdivN=1,PdivN=1

mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8

str r1, [r0]

// 如果HdivN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” //

mrc p15, 0, r1, c1, c0, 0 // 读出控制寄存器 //

orr r1, r1, #0xc0000000 // 设置为“asynchronous bus mode” //

mcr p15, 0, r1, c1, c0, 0 // 写入控制寄存器 //

ldr r0, =0x4c000004

ldr r1, =S3C2440_MPLL_400MHZ

str r1, [r0]

// 启动ICACHE //

mrc p15, 0, r0, c1, c0, 0 @ read control reg

orr r0, r0, #(1<12)

mcr p15, 0, r0, c1, c0, 0 @ write it back

// 3、初始化SDARM //

ldr r0, =MEM_CTL_BASE

adr r1, sdarm_config

add r3, r0,#(13*4)

1:

ldr r2, [r1],#4

str r2, [r0],#4

cmp r0, r3

bne 1b

// 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 //

ldr sp, =0x34000000 //让SP指向最高的内存,栈是往下增长的

bl nand_init //即使是nor启动也要初始化nand flash,因为内核是存在nandflash上面的,还 //要去nandflash上面把内核读出来。

mov r0, #0

ldr r1, =_start //链接地址在链接脚本中注明,即程序运行时应该在的地方,0x33f80000

ldr r2, =__bss_start

sub r2, r2, r1

bl copy_code_to_sdram

bl clear_bss

// 5、执行main函数 //

ldr lr, =halt

ldr pc, =main //跳到main函数中运行,不用bl指令是因为该指令会跳到sdarm中执行

halt:

halt

sdarm_config:

.long 0x22011110 //BWSCON

.long 0x00000700 //BANKCON0

.long 0x00000700 //BANKCON1

.long 0x00000700 //BANKCON2

.long 0x00000700 //BANKCON3

.long 0x00000700 //BANKCON4

.long 0x00000700 //BANKCON5

.long 0x00018005 //BANKCON6

.long 0x00018005 //BANKCON7

.long 00x008C04F4 //REFRESH

.long 00x000000B1 //BANKSIZE

.long 00x00000030 //MRSRB6

.long 00x00000030 //MRSRB7

==============================================================

nand flash初始化文件:

// NAND FLASH控制器 //

#define NFCONF (*((volatile unsigned long *)0x4E000000))

#define NFCONT (*((volatile unsigned long *)0x4E000004))

#define NFCMMD (*((volatile unsigned char *)0x4E000008))

#define NFADDR (*((volatile unsigned char *)0x4E00000C))

#define NFDATA (*((volatile unsigned char *)0x4E000010))

#define NFSTAT (*((volatile unsigned char *)0x4E000020))

void nand_init(void)

{

#define TACLS 0

#define TWRPH0 3

#define TWRPH1 0

// 设置时序 //

NFCONF = (TACLS<12)|(TWRPH0<8)|(TWRPH1<4);

// 使能NAND Flash控制器, 初始化ECC, 禁止片选 //

NFCONT = (1<4)|(1<1)|(1<0);

}

void nand_select(void)

{

NFCONT &= ~(1<1);

}

void del_select(void)

{

NFCONT |= (1<1);

}

void nand_cmd(unsigned char cmd)

{

volatile int i=0;

NFCMMD = cmd;

for(i=0; i<10; i++);

}

void nand_wait_ready(void)

{

while (!(NFSTAT & 1));

}

unsigned char nand_data(void)

{

return NFDATA;

}

void nand_addr(unsigned int addr)

{

unsigned int col = addr % 2048;

unsigned int page = addr / 2048;

unsigned int i=0;

NFADDR = col & 0xff;

for(i=0; i<10; i++);

NFADDR = (col>>8) & 0xff;

for(i=0; i<10; i++);

NFADDR = page & 0xff;

for(i=0; i<10; i++);

NFADDR = (page>>8) & 0xff;

for(i=0; i<10; i++);

NFADDR = (page>>16) & 0xff;

for(i=0; i<10; i++);

}

//addr--->0,下面的nand_read函数从nand flash的0地址读数据放在buf地方

//buf---->_start 即链接地址在链接脚本中注明,程序运行时应该在的地方,0x33f80000,把程序拷贝过去

//len----->__bss_start-_start

void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)

{

int col = addr 48;

int i = 0;

// 选中片选 //

nand_select();

while(i

{

// 发读命令 //

nand_cmd(0x00);

// 发地址 //

nand_addr(addr);

// 发读命令 //

nand_cmd(0x30);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top