第二阶段相关文件
****boot.c setup.h Makefile1 start.S
**
操作
**
1 串口初始化=》 串口显示内核输出,以免死循环
2从nand复制代码到flash
3设置启动参数
4、指针指向入口地址,跳转到**
**
优化启动速度
**
1、提高时钟频率 ,改变时钟比例 200M->400M
2、采用Icache
()2440 (cpu) 指令Icache 数据Dcache
如果不用cache ,cpu会一条一条指令从sdram(内存)中读取, 每执行一条指令,都用重新访问SDRAM
当使用cache后,CPU会取出一小块放入Icache里,下一个执行时,先看cache里面有没有,没有再访问,有则直接cache
(Dcache 使用的前提是MMU)
问题与解决
当uboot下载后没反应,应首先考虑是否是串口通信的问题,->start.S -》Init.s ->最后才boot.c
-**
Makefile
**
CC = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
CFLAGS := -Wall -O2
CPPFLAGS := -nostdinc -fno-builtin
objs := start.o init.o boot.o
boot.bin:$(objs)
${LD} -Tboot.lds -o boot_elf $^
${OBJCOPY} -O binary -S boot_elf $@
${OBJDUMP} -D -m arm boot_elf > boot.dis
%.o:%.c
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
%.o:%.S
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o *.bin *_elf *.dis
编译时加这个-fno-builtin可以解决-fno-builtin
main
void (*theKernel)(int zero,int arch,unsigned int params); /*定义一个函数指针*/
volatile unsigned int *p=(volatile unsigned int *)0x30008000;
/*0.设置串口,内核启动时,会从串口打印一些信息,
*因此要帮内核初始化,但是内核一开始没有初始化串口,内核不输出,则会一直死循环*/
uart0_init();
puts("Copy kernel from nand\n\r");
/*a.从NAND FLASH里把内核读入内存*/
nand_read(0x60000+64,(unsigned char *)0x30008000,0x200000);/*源地址:64字节的头部+0x60000(内核烧到哪里),目的地:0x30008000,多大:2M 2的10次方=1K 2的20次方=M*/
puts("Set boot params\n\r");
/*b.设置参数,参考uboot*/
setup_start_tag();
setup_memory_tags();
setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
setup_end_tag();
puts("Boot kernel\n\r");
/*c.跳转执行,参考uboot*/
theKernel = (void (*)(int,int,unsigned int))0x30008000;/*函数指针,指向这里,一执行等于跳转到0x30008000执行*/
theKernel(0,362,0x30000100); /* mov pc,#0x30008000*/
/*==》这条指令相当于汇编
* mov r0,#0;
* ldr r1,=362;
* ldr r2,=0x30000100;
*/
puts("Error!!\n\r");
/*如果一切正常,不会执行到这里*/
return -1;
参考 Armlinux->c