skyeye arm_hello分析

ARM 33浏览

在skyeye的安装目录下的testsuites目录下存在arm_hello工程,在该文件夹下存在如下的文件:

hello.c,hello.lds,Makefile,start.S,skyeye.conf,README

下面是README文件中关于上面三个文件的解释

Source Files:

After using command 'make clean' to delete binary files, you will find 

there are only five source files in "HelloForSkyeye". They are hello.c, hello.lds, 

makefile, skyeye.conf and start.S. I shall introduce them one by one.

makefile:

As the input file of 'make', makefile describes how to compile the whole 

"HelloForSkyeye" project. Some compilation parameters are strange, such as -mapcs,

-march. You can find their meaning in "as.info->Machine Dependencies->ARM-Dependent

->ARM Options"

该文件时作为make工具的输入,描述了如何编译该工程,注意的是有些编译参数比较陌生,象-mapcs,-march,... 这些参数的说明可以

在as.info::Machine Dependence::ARM-Dependent::ARM Options中找到。

该文件内容如下:

#

#makefile for helloforSkyeye

#

#author: SU Hang

#Date:   2004-08-28

#begin

# 定义编译器,编译参数和连接器,链接参数

    CC=arm-elf-gcc

    LD=arm-elf-ld

    CFLAGS= -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi 

    LDFLAGS= -N -p -X -Thello.lds

    LIB=

#第一个make目标all,生成hello文件

    all: hello 

    hello: start.o hello.o # hello可执行文件是由start.o和hello.o生成

$(LD) $(LDFLAGS)  start.o hello.o -o hello #将start.o和hello.o链接成hello可执行文件

arm-elf-objdump -xS hello > hello.s # 将生成的文件hello信息输入到hello.s文件中,可以注释掉

arm-elf-readelf -a hello > hello.r # 同上

arm-elf-nm hello > hello.n # 同上

 

    start.o:start.S #生成start.o

$(CC) $(CFLAGS) start.S  

    hello.o:hello.c # 生成hello.o

$(CC) $(CFLAGS) hello.c

    clean: # make clean

rm -rf *.o *.elf *.gdb *.r *.n *.s

#end

start.S:

Initial assemble codes are placed in this file to make irq mode with all irqs 

disabled,  set sp_irq and call "hello" fuction to print "helloworld" string. You may 

find the syntax of comments, constants and symbols is different from what described 

in textbook about ARM. Don't worry about it, because the GNU assembler has a 

machine-independent syntax. You can refer to the Syntax chapter of as.info to get more 

information.

start.S存放的是启动的汇编代码,主要工作是设置IRQ模式,屏蔽中断,调用函数输出字符串,然后重复这个工程。这些汇编指令大多是

arm指令,但是其中还是包含一些伪指令。

/*

 *  start.S 

 *  very simple code for ARM 7TDMI 

 * 该文件在Makefile中调用,和hello.c一起被ld链接成hello可执行文件

 *  author: SU Hang 

 *  date:   2004-08-28 

 */

 

#define MODE_SVC 0x13

#define I_BIT   0x80

.text

.align 4

.global begin

.type begin, function

begin:

/*disable I-bit*/

/* 设置cpsr寄存器,允许irq中断 */

mov     r0, #I_BIT|MODE_SVC

msr     cpsr_c, r0

mov r1,#0xd2

sub r2,r0,r1

/* 设置堆栈指针 */

ldr sp, =irq_stack           @ set sp_irq = irq_stack

bl hello /* 调用函数hello,该函数在hello.c中定义 */

b begin /* loop */

.data

.align  4

irq_stack: /* stack */

.space 4096

hello.c:

This is a common C source file which has only one function "hello". The "Hello" 

function output the "helloworld" string to UART. On AT91, the base address of UART0 is 

0xfffd0000 and the offset of US_THR is 0x1c so that when we write character to 0xfffd001c 

address, it means send character to UART. And skyeye will print the character to the 

screen. 

这是一个c语言源文件,其中只有一个hello函数,实现向串口输出“helloworld" 字串的功能。因为AT91的UART0的基址为0xfffd0000,

USART发送寄存器US_THR的偏移量是0x1c。所以向0xfffd001c地址写入字符,就是向串口发送字符。

/*

 * hello.c

 * just a function used to output "helloworld" to uart 

 * 

 * author: SU Hang

 * date:   2004-08-28

 */

#define BOGO_MIPS 1000000

void hello(void)

{

int i;

char * hellostr="helloworld";

// 定义串口发送字符串地址

long* paddr=(long*)0xfffd001c;

int timeout ;

i = *hellostr - 'h'; // 字符串长度

while(1){

// 时间延迟

timeout = 0;

while(++timeout != BOGO_MIPS);

// 向上面的地址写入字符串

for(i=0;i<10;i++)

{

* paddr=hellostr[i];

}

}

return;

}

hello.lds

This is ld script file in which program entry and every place of section are 

regulated. The script chapter of ld.info describes the syntax of lds file. We also can 

use command "objdump -x" to check the binary file.

这是ld链接器的脚本文件,其中规定了程序入口,各个段的放置位置。ld script的书写方法可以在ld.info::Scripts::中找到。该arm_hello可以被看做一个非常简单的操作系统内核,所以得要自己编写hello.lds文件。hello.lds文件中描述了如何把start.o,hello.o文件中得代码段、数据段等等如何组合到hello中。

/*

 * hello.lds

 * ld script for helloforSkyeye

 * 该文件在Makefile中被调用,作为ld输入文件。

 * author: SU Hang

 * Date:   2004-08-28

 */

/* 定义体系结构 */

OUTPUT_ARCH(arm)

/* 将后面括号中的符号值设置成入口地址 */

ENTRY(begin)

SECTIONS

{

/* text加载到地址0x1000000 */

. = 0x1000000;

.text : 

{

*(.text) 

*(.rodata)

}

/* 指定对齐方式 */

. = ALIGN(8192);

/* text段后加载数据段 */

.data : {*(.data)}

/* 数据段后加载bss段 */

.bss : {*(.bss)}

        /* Stabs debugging sections. 调试使用 */

        .stab 0 : { *(.stab) }

        .stabstr 0 : { *(.stabstr) }

        .stab.excl 0 : { *(.stab.excl) }

        .stab.exclstr 0 : { *(.stab.exclstr) }

        .stab.index 0 : { *(.stab.index) }

        .stab.indexstr 0 : { *(.stab.indexstr) }

        .comment 0 : { *(.comment) }

        .debug_abbrev 0 : { *(.debug_abbrev) }

        .debug_info 0 : { *(.debug_info) }

        .debug_line 0 : { *(.debug_line) }

        .debug_pubnames 0 : { *(.debug_pubnames) }

        .debug_aranges 0 : { *(.debug_aranges) }

}

skyeye.conf Configure file of skyeye. 

skyeye运行的配置文件,其中说明了模拟的cpu,arch,还有内存组配置。

#skyeye config file sample

# arm体系结构

arch:arm

# cpu类型

cpu: arm7tdmi

mach: at91

# 内存,读写

mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000

#io地址,读写

mem_bank: map=I, type=RW, addr=0xf0000000, size=0x10000000

#打开另外的一个终端来作为uart的输入和输出端

uart:mod=term

#log: logon=0, logfile=./sk1.log, start=0, end=200000