1. S3C2440大概的启动流程(NAND启动):
①设置CPU为SVC模式
②关闭看门狗
③屏蔽中断
④关闭MMU
⑤初始化时钟
⑥初始化内存(SDRAM)
⑦初始化栈指针(SP, R13)
⑧初始化NAND Flash
⑨拷贝代码从NAND到内存
⑩清除BSS段
最后,跳转至C语言的Main函数执行
2. 汇编语言源代码
.text .global _start _start: b reset ldr pc, _undifined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq _undifined_instruction: .word undifined_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 reset undifined_instruction: nop software_interrupt: nop prefetch_abort: nop data_abort: nop not_used: nop irq: sub lr, lr, #4 stmfd sp!, {r0-r12, lr} /* Save envrionment */ bl HandleIrq ldmfd sp!, {r0-r12, pc}^ /* Recover envrionment, ^ take spsr to cpsr */ fiq: nop .global reset reset: bl set_svc bl disable_watchdog bl disable_interrupt bl disable_mmu bl init_clock bl init_sdram bl init_stack bl nandflash_init bl light_led bl copy_to_ram bl clean_bss ldr pc, =gboot_main set_svc: mrs r0, cpsr bic r0, r0,#0x1f orr r0, r0,#0xd3 msr cpsr, r0 mov pc, lr #define pWTCON 0x53000000 disable_watchdog: ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] mov pc, lr disable_interrupt: mvn r1, #0x0 ldr r0, =0x4a000008 str r1, [r0] mov pc, lr disable_mmu: mcr p15,0,r0,c7,c7,0 mrc p15,0,r0,c1,c0,0 bic r0, r0, #0x00000007 mcr p15,0,r0,c1,c0,0 mov pc, lr #define CLKDIVN 0x4c000014 #define MPLLCON 0x4c000004 #define MPLL_405MHZ ((127<<12)|(2<<4)|(1<<0)) init_clock: ldr r0, =CLKDIVN mov r1, #0x5 //FCLK : HCLK : PCLK = 1 : 4 : 8(Divide Ratio) str r1, [r0] mcr p15,0,r0,c1,c0,0 orr r0,r0,#0xc0000000 mcr p15,0,r0,c1,c0,0 ldr r0, =MPLLCON ldr r1, =MPLL_405MHZ str r1, [r0] mov pc, lr #define mem_contrl 0x48000000 init_sdram: ldr r0, =mem_contrl add r3, r0, #4*13 adrl r1, mem_data 0: ldr r2, [r1], #4 str r2, [r0], #4 cmp r0, r3 bne 0b mov pc, lr #define copy_length 0x350000 copy_to_ram: mov r0,#0x00 ldr r1,=_start ldr r2,=EFI_driver_end sub r2,r2,r1 mov ip,lr bl nand_to_ram mov lr,ip mov pc,lr init_stack: msr cpsr_c, #0xd2 //Switch irq mode and set sps ldr sp, =0x33000000 msr cpsr_c, #0xd3 //Switch back to SVC ldr sp, =0x34000000 mov pc ,lr clean_bss: ldr r0, =bss_start ldr r1, =bss_end cmp r0, r1 moveq pc, lr clean_loop: mov r2, #0 str r2, [r0], #4 cmp r0, r1 bne clean_loop mov pc, lr mem_data: .long 0x22000000 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00018001 .long 0x00018001 .long 0x008c04f5 .long 0x000000b1 .long 0x00000030 .long 0x00000030 #define GPBCON 0x56000010 #define GPBDAT 0x56000014 light_led: ldr r0, =GPBCON mov r1, #0x400 str r1, [r0] ldr r0, =GPBDAT mov r1, #0x0 str r1, [r0] mov pc, lr
3. 链接器脚本
OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x30004000; . = ALIGN(4); .text : { start.o (.text) *(.text) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); bss_start = .; .bss : { *(.bss) } bss_end = .; . = ALIGN(4); boot_cmd_start = .; .boot_cmd : { *(.boot_cmd) } boot_cmd_end = .; . = ALIGN(4); EFI_driver_start = .; .EFI_driver : { *(.EFI_driver) } EFI_driver_end = .; }
4. Makefile
CC := arm-linux-gcc LD := arm-linux-ld OBJCOPY := arm-linux-objcopy CFLAGS := -fno-builtin -I$(shell pwd)/Include export CFLAGS all: start.o main.o Core/Core.o CommonLib/CommonLib.o Driver/Driver.o Test/Test.o Net/Net.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ -L /usr/local/arm/4.3.2/lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t -lgcc arm-linux-objcopy -O binary gboot.elf gboot.bin %.o : %.S arm-linux-gcc -g -c $^ %.o : %.c arm-linux-gcc $(CFLAGS) -g -c $^ Core/Core.o : make -C Core all Driver/Driver.o : make -C Driver all CommonLib/CommonLib.o : make -C CommonLib all Test/Test.o : make -C Test all Net/Net.o : make -C Net all .PHONY: clean clean: make -C Driver clean make -C CommonLib clean make -C Test clean make -C Core clean make -C Net clean rm *.o *.elf *.bin
时间: 2024-10-14 12:06:33