skyeye arm_hello分析
在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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?