@**************************** @name: start.S @by : Lieber @time: 2018.3.25 @function: @ 异常向量表 @ 设置SVC模式 @ 关闭看门狗 @ 关闭中断 @ 关闭MMU @ 外设基地址初始化 @ 点亮LED @ 时钟初始化 @ 内存初始化 @ 代码搬移 @****************************
.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: nop fiq: nop reset: bl set_svc bl set_peri_port bl disable_watchdog bl disable_interrupt bl disable_mmu bl init_clock bl mem_init bl copy_to_ram bl init_stack bl clean_bss ldr pc, =gboot_main @ bl light_led set_peri_port: ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 mov pc, lr set_svc: mrs r0, cpsr bic r0, r0,#0x1f orr r0, r0,#0xd3 msr cpsr, r0 mov pc, lr #define pWTCON 0x7e004000 disable_watchdog: ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] mov pc, lr disable_interrupt: mvn r1,#0x0 ldr r0,=0x71200014 str r1,[r0] ldr r0,=0x71300014 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 CLK_DIV0 0x7e00f020 #define OTHERS 0x7e00f900 #define MPLL_CON 0x7e00f010 #define APLL_CON 0x7e00f00c #define CLK_SRC 0x7e00f01c #define DIV_VAL ((0x0<<0)|(0x1<<9)|(0x1<<8)|(0x3<<12)) #define PLL_VAL ((1<<31)|(266<<16)|(3<<8)|(1<<0)) init_clock: ldr r0, =CLK_DIV0 ldr r1, =DIV_VAL str r1, [r0] ldr r0, =OTHERS ldr r1, [r0] bic r1,r1,#0xc0 str r1, [r0] ldr r0, =APLL_CON ldr r1, =PLL_VAL str r1, [r0] ldr r0, =MPLL_CON ldr r1, =PLL_VAL str r1, [r0] ldr r0, =CLK_SRC mov r1, #0x3 str r1, [r0] mov pc, lr copy_to_ram: @ ldr r0, =0x0c000000 adr r0, _start @从代码执行第一条指令的地址,不是0x00 ldr r1, =0x50008000 add r3, r0, #1024*4 copy_loop: ldr r2, [r0], #4 str r2, [r1], #4 cmp r0, r3 bne copy_loop mov pc, lr init_stack: ldr sp, =0x54000000 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 #define GPKCON 0x7f008800 #define GPKDAT 0x7f008808 .global light_led light_led: ldr r0, =GPKCON ldr r1, =0x11110000 str r1, [r0] ldr r0, =GPKDAT ldr r1, =0xa0 str r1, [r0] mov pc, lr
@**************************** @name: mem.S @by : Lieber @time: 2018.3.25 @function: @ 内存初始化 @****************************
.global mem_init mem_init: @设置数据引脚 ldr r0, =0x7e00f120 mov r1, #0x8 str r1, [r0] ldr r0, =0x7e001004 @内存控制命令寄存器 mov r1, #0x4 @根据手册得知需要先进入配置模式 str r1, [r0] ldr r0, =0x7e001010 @刷新寄存器地址 ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) ) @设置刷新时间 str r1, [r0] ldr r0, =0x7e001014 @CAS latency寄存器 mov r1, #(3 << 1) str r1, [r0] ldr r0, =0x7e001018 @t_DQSS寄存器 mov r1, #0x1 str r1, [r0] ldr r0, =0x7e00101c @T_MRD寄存器 mov r1, #0x2 str r1, [r0] ldr r0, =0x7e001020 @t_RAS寄存器 ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001024 @t_RC寄存器 ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001028 @t_RCD寄存器 ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e00102c @t_RFC寄存器 ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001030 @t_RP寄存器 ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001034 @t_rrd寄存器 ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001038 @t_wr寄存器 ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) ) @ ldr r2, [r0] str r1, [r0] ldr r0, =0x7e00103c @t_wtr寄存器 mov r1, #0x07 str r1, [r0] ldr r0, =0x7e001040 @t_xp寄存器 mov r1, #0x02 str r1, [r0] ldr r0, =0x7e001044 @t_xsr寄存器 ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001048 @t_esr寄存器 ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e00100c @内存控制配置寄存器 ldr r1, =0x00010012 @配置控制器 str r1, [r0] ldr r0, =0x7e00104c @32位DRAM配置控制寄存器 ldr r1, =0x0b45 str r1, [r0] ldr r0, =0x7e001200 @片选寄存器 ldr r1, =0x150f8 str r1, [r0] ldr r0, =0x7e001304 @用户配置寄存器 mov r1, #0x0 str r1, [r0] ldr r0, =0x7e001008 @issue NOP ldr r1, =0x000c0000 str r1, [r0] ldr r1, =0x00000000 @issue prechargeall str r1, [r0] ldr r1, =0x00040000 @issue refresh str r1, [r0] ldr r1, =0x000a0000 @issue mrs str r1, [r0] ldr r1, =0x00080032 @issue mrs str r1, [r0] ldr r0, =0x7e001004 mov r1, #0x0 str r1, [r0] @顺序执行 check_dmc1_ready: ldr r0, =0x7e001000 ldr r1, [r0] mov r2, #0x3 and r1, r1, r2 cmp r1, #0x1 bne check_dmc1_ready nop mov pc,lr
@**************************** @name: main.c @by : Lieber @time: 2018.3.25 @function: @ c语言环境初始化/用c点亮led @****************************
start.S下汇编调用C函数
ldr pc, =gboot_main
#define GPKCON (volatile unsigned long*)0x7f008800 #define GPKDAT (volatile unsigned long*)0x7f008808 int gboot_main() { *(GPKCON) = 0x11110000; *(GPKDAT) = 0xa0; return 0; }
main.c 下c 语言调用汇编
#define GPKCON (volatile unsigned long*)0x7f008800 #define GPKDAT (volatile unsigned long*)0x7f008808 int gboot_main() { light_led(); return 0; }
#define GPKCON 0x7f008800 #define GPKDAT 0x7f008808 @需要把 light_led 声明为全局的 .global light_led light_led: ldr r0, =GPKCON ldr r1, =0x11110000 str r1, [r0] ldr r0, =GPKDAT ldr r1, =0xa0 str r1, [r0] mov pc, lr
c 语言与汇编混合编程格式:
__asm(
汇编语句部分
:输出部分
:输入部分
:破坏描述部分---内容被修改的部分
);
C内嵌汇编以关键字”__asm”或”asm”开始,下辖四
个部分,各部分之间使用":"分开, 第一部分是必须写的,
后面三部分是可以省略,但是分号:不能省略!
#define GPKCON (volatile unsigned long*)0x7f008800 #define GPKDAT (volatile unsigned long*)0x7f008808 int gboot_main() { __asm( "ldr r1, =0x11110000\n" "str r1, [%0]\n" "ldr r1, =0xa0\n" "str r1, [%1]\n" : :"r"(GPKCON),"r"(GPKDAT) :"r1" ); return 0; }
@**************************** @name: Makefile @by : Lieber @time: 2018.3.25 @****************************
all: start.o mem.o main.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ arm-linux-objcopy -O binary gboot.elf gboot.bin %.o : %.S arm-linux-gcc -g -c $^ %.o : %.c arm-linux-gcc -g -c $^ .PHONY: clean clean: rm *.o *.elf *.bin fhb: arm-linux-objdump -D -S gboot.elf > dump
@**************************** @name: gboot.lds @by : Lieber @time: 2018.3.25 @****************************
OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x50008000; . = ALIGN(4); .text : { start.o (.text) *(.text) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); bss_start = .; .bss : { *(.bss) } bss_end = .; }