一步步写嵌入式操作系统 启动流程

参考书目

《一步步写嵌入式操作系统》李无言著

文件结构

一步步写嵌入式操作系统 启动流程_第1张图片

链接脚本leeos.lds

OUTPUT_ARCH(arm)
ENTRY(_start)

SECTIONS
{
	. = 0x00000000;
	.text :
	{
		*(.startup)
		*(.text)
	}
	. = ALIGN(32);
	.data :
	{
		*(.data)
	}
	. = ALIGN(32);
	__bss_start__ = .;
	.bss :
	{
		*(.bss)
	}
	__bss_end__ = .;
}

启动代码start.s(由链接脚本指定了入口_start)

.section .startup
.code 32
.align 0

.global _start
.extern __vector_reset
.extern __vector_undefined
.extern __vector_swi
.extern __vector_prefetch_abort
.extern __vector_data_abort
.extern __vector_reserved
.extern __vector_irq
.extern __vector_fiq

_start:
	ldr pc,_vector_reset
	ldr pc,_vector_undefined
	ldr pc,_vector_swi
	ldr pc,_vector_prefetch_abort
	ldr pc,_vector_data_abort
	ldr pc,_vector_reserved
	ldr pc,_vector_irq
	ldr pc,_vector_fiq

	.align 4

_vector_reset:			.word  __vector_reset
_vector_undefined:		.word  __vector_undefined
_vector_swi:			.word  __vector_swi
_vector_prefetch_abort:	.word  __vector_prefetch_abort
_vector_data_abort:		.word  __vector_data_abort
_vector_reserved:		.word  __vector_reserved
_vector_irq:			.word  __vector_irq
_vector_fiq:			.word  __vector_fiq

初始化代码init.s

.equ DISABLE_IRQ,	0x80
.equ DISABLE_FIQ,	0x40
.equ SYS_MOD,		0x1f
.equ IRQ_MOD,		0x12
.equ FIQ_MOD,		0x11
.equ SVC_MOD,		0x13
.equ ABT_MOD,		0x17
.equ UND_MOD,		0x1b

.equ MEM_SIZE, 		0x800000
.equ TEXT_BASE,		0x30000000
.equ _SVC_STACK,	(TEXT_BASE+MEM_SIZE-4)
.equ _IRQ_STACK,	(_SVC_STACK-0x400)
.equ _FIQ_STACK,	(_IRQ_STACK-0x400)
.equ _ABT_STACK,	(_FIQ_STACK-0x400)
.equ _UND_STACK,	(_ABT_STACK-0x400)
.equ _SYS_STACK,	(_UND_STACK-0x400)

.text
.code 32
.global __vector_reset

.extern plat_boot
.extern __bss_start__
.extern __bss_end__

__vector_reset:
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|SVC_MOD)
	ldr sp,=_SVC_STACK
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|IRQ_MOD)
	ldr sp,=_IRQ_STACK
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|FIQ_MOD)
	ldr sp,=_FIQ_STACK
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|ABT_MOD)
	ldr sp,=_ABT_STACK
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|UND_MOD)
	ldr sp,=_UND_STACK
	msr cpsr_c,#(DISABLE_IRQ|DISABLE_FIQ|SYS_MOD)
	ldr sp,=_SYS_STACK

_clear_bss:
	ldr r1,_bss_start_
	ldr r3,_bss_end_
	mov r2,#0x0
_loop:
	cmp r1,r3
	beq _main
	str r2,[r1],#0x4
	b _loop

_main:
	b plat_boot


_bss_start_:	.word  __bss_start__
_bss_end_:		.word  __bss_end__

.end

异常处理代码abnormal.s

.global __vector_undefined
.global __vector_swi
.global __vector_prefetch_abort
.global __vector_data_abort
.global __vector_reserved
.global __vector_irq
.global __vector_fiq

.text
.code 32

__vector_undefined:
	nop
__vector_swi:
	nop
__vector_prefetch_abort:	
	nop
__vector_data_abort:
	nop
__vector_reserved:
	nop
__vector_irq:
	nop
__vector_fiq:
	nop

开机代码boot.c

typedef void (*init_func)(void);

#define UFCON0	((volatile unsigned int *)(0x50000020))

void helloworld(void)
{
	const char *p = "3.1_helloworld\n";
	while(*p) {
		*UFCON0 = *p++;
	};
}

static init_func init[] = {
	helloworld,
	0,
};

void plat_boot(void)
{
	int i;
	for(i = 0; init[i]; i++) {
		init[i]();
	}
	while(1);
}

编译脚本makefile

CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld
OBJCOPY=arm-none-eabi-objcopy

CFLAGS= -O2 -g
ASFLAGS= -O2 -g
LDFLAGS=-Tleeos.lds -Ttext 30000000 

OBJS=init.o start.o boot.o abnormal.o

.c.o:
	$(CC) $(CFLAGS) -c $<
.s.o:
	$(CC) $(ASFLAGS) -c $<

leeos.elf:$(OBJS)
	$(CC) -static -nostartfiles -nostdlib $(LDFLAGS) $? -o $@ -lgcc
	$(OBJCOPY) -O binary $@ leeos.bin

clean:
	rm *.o leeos.elf leeos.bin -f

skyeye配置文件skyeye.conf

cpu:  arm920t
mach: s3c2410x
  
#physical memory
mem_bank: map = M, type = RW, addr = 0x30000000, size = 0x00800000, file = ./leeos.bin, boot=yes
mem_bank: map = I, type = RW, addr = 0x48000000, size = 0x20000000

效果

一步步写嵌入式操作系统 启动流程_第2张图片

你可能感兴趣的:(一步步写嵌入式操作系统,c语言,开源,arm)