一个简单的基于MINI2440开发板的启动代码

时间:2022-05-09 01:03:29

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