自己写bootloader
#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、关看门狗 //
// 2、设置系统时钟 //
// 启动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 //
1:
// 4. 重定位 : 把
bootloader本身的代码从flash复制到它的链接地址去 //
bl copy_code_to_sdram
bl clear_bss
// 5、执行main函数 //
ldr lr, =halt
ldr pc, =main
//跳到main函数中运行,不用bl指令是因为该指令会跳到sdarm中执行
halt:
sdarm_config:
==============================================================
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)
{
}
void nand_select(void)
{
}
void del_select(void)
{
}
void nand_cmd(unsigned char cmd)
{
}
void nand_wait_ready(void)
{
}
unsigned char nand_data(void)
{
}
void nand_addr(unsigned int addr)
{
}
//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 isBootFromNorFlash(void)
{
}
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
}
void clear_bss(void)
{
}
#define PCLK
50000000
// init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK
PCLK
//
UART0的时钟源设为PCLK
#define UART_BAUD_RATE
115200
// 波特率
#define UART_BRD
((UART_CLK
/ (UART_BAUD_RATE * 16)) - 1)
//
void
uart0_init(void)
{
}
//
void putc(unsigned char c)
{
}
void puts(char *str)
{
int i = 0;
while (str[i])
{
putc(str[i]);
i++;
}
}
void puthex(unsigned int val)
{
// 0x1234abcd //
int i;
int j;
puts("0x");
for (i = 0; i < 8; i++)
{
j = (val >> ((7-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc(0 + j);
else
putc(A + j - 0xa);
}
}
=================================================================
boot.c
#include "setup.h"
extern void uart0_init(void);
extern void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
extern void puts(char *str);
extern void puthex(unsigned int val);
static struct tag *params;
void setup_start_tag(void)
{
}
void setup_memory_tags(void)
{
}
int strlen(char *str)
{
}
void strcpy(char *dest, char *src)
{
}
void setup_commandline_tag(char *cmdline)
{
}
void setup_end_tag(void)
{
}
int main(void)
{
注意:第二个参数机器ID可以在u-boot函数:boot_jump_linux中unsigned long machid = gd->bd->bi_arch_number;中搜索“bi_arch_number”找到:board/samsung/smdk2440/smdk2410.c
中定义:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;根据MACH_TYPE_SMDK2410的定义找到:
#define MACH_TYPE_S3C2440
362
}
===============================================================
链接文件:
SECTIONS {
}
===============================================================
注:
最简单的bootloader的编写步骤:
1. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
2. 如果bootloader比较大,要把它重定位到SDRAM
3. 把内核从NAND FLASH读到SDRAM
4. 设置"要传给内核的参数"
5. 跳转执行内核
改进:
1. 提高CPU频率, 200MHZ ==> 400MHZ
2. 启动ICACHE
存储地址解析:
注意:nor flash启动的u-boot既可以烧写nor flash本身也可以烧写nand flash,但是如果是nand flash启动的话就没办法操作nor flash,因为nand flash启动的时候0地址对应片内内存,无法访问nor flash。
评论