shang79 发表于 2004-8-29 15:17:32

HelloWorld on Skyeye,新手请进!

<chyyuu>最简单的可以在skyeye上运行的程序!

介绍:    初始学习嵌入式系统编程和使用Skyeye的人往往不知道该如何入手,
我想除了看资料以外,最好还有简单的例子可以用来作为基础练习。一般学习新
的编程和工具,都是从helloworld入手,所以我参考ucos-ii,使得用最少的代码
实现在skyeye上打印helloworld字串的功能。注意这里的Hello4Skyeye程
序与以前介绍的skyeye上的helloworld程序不同:它不需要有操作系统底层支
持,比如uclinux;它不是应用程序;它直接往串口写字符。Hello4Skyeye代
码量很少,没有实际应用意义,只是新手用于练习使用,高手就不必看了,欢迎
检查。

编译运行:    Hello4Skyeye程序是在Skyeye0.8.6,RedHat9.0上编译
通过的。编译之前请确定安装了Skyeye和arm-elf交叉编译器。有关这两者的安
装说明可以在论坛置顶的《Skyeye使用简介》中找到。步骤如下:
1把Hello4Skyeye.tgz下载到Linux用户目录中用
   tar -zxvf Hello4Skyeye.tgz 解压缩Hello4Skyeye.tgz, 产生
   Hello4Skyeye目录
2 cd Hello4Skyeye
3用make编译
4用skyeye hello运行hello,和其它程序一样接着用tar sim; load;run;
就可以看到以下结果:
***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.6 with GDB 5.3 Interface ****
**** ****
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --
target=arm-elf"...(no debugging symbols found)...
(SkyEye) tar s
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813dae4
log_info: log is off.
log_info:log file is /tmp/sk1.log, fd is 0x829e0e0
log_info: log start clock 0
log_info: log end clock 200000
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .text, size 0x98 vma 0x1000000
Loading section .data, size 0x1000 vma 0x1002000
Start address 0x1000000
Transfer rate: 33984 bits in <1 sec.
(SkyEye) run
Starting program: /home/shang/HelloForSkyeye/hello
helloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworld   

组成部分:    在Hello4Skyeye目录中用make clean命令可以删除目标代
码,只留下源代码,可以看到总共只有hello.c hello.lds makefile
skyeye.conf start.S五个文件。下面逐一介绍。

makefile:   该文件做为make工具的输入,描述了该如何编译
HelloForSkyeye项目。有关makefile的编写在make.info中已经详细说明,值
得注意的是有些编译参数比较陌生,象-mapcs,-march,... 这些参数的说明可以
在as.info::Machine Dependence::ARM-Dependent::ARM Options中找到。

start.S:    该文件存放了启动的汇编代码,主要工作就是设置IRQ模式,屏蔽中
断,调用hello函数输出字串,重新循环。这里的汇编指令都是ARM指令,但是伪
指令,还有label,立即数等等都和教科书上写的ARM程序大相径庭。这些都是
GNU AS汇编编译器的统一语法。在as.info中有详细的介绍。

hello.c:    这是一个c语言源文件,其中只有一个hello函数,实现向串口输出
“helloworld" 字串的功能。因为AT91的UART0的基址为0xfffd0000,USART
发送寄存器US_THR的偏移量是0x1c。所以向0xfffd001c地址写入字符,就是
向串口发送字符。Skyeye就会把字符打印到屏幕上。可以看到系统编程必须对硬
件了解。

hello.lds:这是ld链接器的脚本文件,其中规定了程序入口,各个段的放置位
置。ld script的书写方法可以在ld.info::Scripts::中找到。编译好的目标代码,
还可以用'objdump -x' 查看里面的各段的位置。

skyeye.conf: skyeye运行的配置文件,其中说明了模拟的cpu,arch,还有内存
组配置。论坛置顶的《Skyeye使用简介》中详细说明了该配置文件的写法。

chyyuu 发表于 2004-8-30 22:08:43

很好的初学例子!

quantumm 发表于 2004-12-2 00:41:04

Where download the "HelloForSkyeye.tar"?THX
or mail me [email protected]

shang79 发表于 2004-12-2 01:20:21

If you log in as a formal user not a guest, you can see the link of Helloforskyeye.tar under my first post.
Anyway, I have send Helloforskyeye.tar to your mailbox.

quantumm 发表于 2004-12-3 00:21:53

I get it ! THX!

wenwencarol 发表于 2004-12-3 18:44:39

thank you very much!

gulite 发表于 2005-1-27 11:48:11

我想在skyeye里代码级调试这个程序,我修改了makefile,在CFLAGS里加上了-g,如下:

...
CFLAGS=-g ...
...

之后用skyeye载入hello,发生如下错误:
Dwarf Error: bad offset (0x1003000) in compilation unit header (offset 0x0 + 6)

不知道这是怎么回事?请教代码级调试的入门方法

谢谢

shang79 发表于 2005-2-16 15:54:50

hello4skyeye的源码级调试方法

问题描述如下:

在Makefile中的CFLAG中添加-g选项编译hello4skyeye后,如果使用break,list命令就会出现以下提示

No symbol table is loaded. Use the "file" command.

如果使用file hello的命令则会出现错误提示:

Reading symbols from hello.elf...Dwarf Error: bad offset (0x1003000) in compilation unit header (offset 0x0 + 6).

解决方法如下:

修改hello.lds文件,在SECTIONS中,最后添加以下 Stabs debugging sections.部分代码:
/*
* hello.lds
* ld script for helloforSkyeye
*
* author: SU Hang
* Date:   2004-08-28
*/

OUTPUT_ARCH(arm)
ENTRY(begin)
SECTIONS
{
      . = 0x1000000;
      .text : {*(.text)}

      . = ALIGN(8192);

      .data : {*(.data)}

      .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) }

}
然后再用-g参数编译链接产生的hello程序就可以进行源码级调试了,调试示例见本贴最后。现在说明一下hello.lds文件的作用和该错误的原因。

hello.lds文件是一个链接控制脚本文件(Linker Control Scripts)。该文件的作用是在链接过程中,描述输入文件(*.o)的各部分(section)是如何组合映射到输出文件(hello)的各段(segment)中的。

通常情况下,链接器ld运行时会使用一个默认的lds文件,不需要用户自己编写lds文件。该默认lds文件的内容可以在使用ld时使用--verbose参数显示。但是在特定情况下,比如编写操作系统内核,就会需要编写自己的lds文件。

hello4skyeye可以被看做一个非常简单的操作系统内核,所以得要自己编写hello.lds文件。hello.lds文件中描述了如何把start.o,hello.o文件中得代码段、数据段等等如何组合到hello。

本来有了.text .data .bss三个段,hello程序就可以在skyeye上运行了,但是如果是调试版的hello程序,就需要把start.o和hello.o中更多的与调试相关的section放入hello中,这就是我们为什么要在hello.lds中添加更多代码的原因了。

更多的关于lds方面资料,可以在Linux中使用info ld看Scripts章节。《Linker & Loader》中也有关于link Control Scripts方面的说明。


# make编译hello可执行文件
arm-elf-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes start.S
arm-elf-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes hello.c
arm-elf-ld -p -X -Thello.lds start.o hello.o -o hello
arm-elf-objdump -S hello > hello.s
arm-elf-readelf -a hello > hello.r
arm-elf-nm hello > hello.n
# skyeye hello运行hello可执行文件
***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.6 with GDB 5.3 Interface ****
**** ****
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --target=arm-elf"...
(SkyEye) tar s
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813efa4
log_info: log is off.
log_info:log file is /tmp/sk1.log, fd is 0x829a318
log_info: log start clock 0
log_info: log end clock 200000
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .text, size 0x54 vma 0x1000000
Loading section .rodata, size 0xb vma 0x1000054
Loading section .data, size 0x1000 vma 0x1002000
Start address 0x1000000
Transfer rate: 33528 bits in <1 sec.
(SkyEye) list         显示hello可执行文件中的源代码
1 /*
2 * hello.c
3 * just a function used to output "helloworld" to uart
4 *
5 * author: SU Hang
6 * date: 2004-08-28
7 */
8 void hello(void)
9 {
10 int i;
(SkyEye) list
11 char * hellostr="helloworld";
12 long* paddr=(long*)0xfffd001c;
13
14 for(i=0;i<10;i++)
15 {
16 * paddr=hellostr;
17 }
18 return;
19 }
20
(SkyEye) break hello在hello函数入口设置断点
Breakpoint 1 at 0x1000030: file hello.c, line 14.
(SkyEye) run          程序运行到hello断点处停止
Starting program: /home/suhang/HelloForSkyeye/hello

Breakpoint 1, hello () at hello.c:14
14 for(i=0;i<10;i++)
(SkyEye) info all-register 显示当前skyeye虚拟机中所有寄存器的值
r0 0xd2 210
r1 0xfffd001c -196580
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x1001ffc 16785404
r12 0x1002000 16785408
sp 0x1001ff0 16785392
lr 0x0 0
pc 0x1000030 16777264
f0 0 (raw 0x000000000000000000000000)
f1 0 (raw 0x000000000000000000000000)
f2 0 (raw 0x000000000000000000000000)
f3 0 (raw 0x000000000000000000000000)
f4 0 (raw 0x000000000000000000000000)
f5 0 (raw 0x000000000000000000000000)
f6 0 (raw 0x000000000000000000000000)
f7 0 (raw 0x000000000000000000000000)
fps 0x0 0
cpsr 0xd2 210

zxlufei 发表于 2005-2-20 22:44:06

感谢楼主,按你的方法偶在ROOT登陆时运行成功了,不过非ROOT时登陆可以吗?
(SkyEye) target sim
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813e02c
log_info: log is off.
SkyEye: Error when open log file:: 权限不够
$
这个是什么原因?请指点~万分感谢!

shang79 发表于 2005-2-22 01:35:24

出现"SkyEye: Error when open log file"的错误是因为skyeye.conf文件中把log文件设为/tmp/sk1.log,因为普通用户没有权限打开该文件写入skyeye日志,所以会报错.

解决的方法的方法是把Hello4Skye目录中的skyeye.conf文件中的下面语句:

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

改为

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

应该就可以了,要保证logfile是普通用户可以打开的文件.

zxlufei 发表于 2005-2-26 10:29:27

多谢楼主,按楼主指点,在非root下也成功了~

littertiger 发表于 2005-2-27 21:22:10

I have two arm tool chains, one is arm-linux-xxx (3.3.2), the other is arm-elf-xxx. which should I use? what's the difference?
when use arm-elf-xxx:
error:invalid option 'short-load-bytes'
when use arm-linux-xxx:
arm-linux-ld:hello:not enough room for program headers, try linking with -N
when I use -N to link: no error, but no "hello" is outputed when run in skyeye.

why?

tropic 发表于 2005-2-28 14:41:11

我遇到楼上相同的问题啊?不知怎么解决呢?
arm-unknown-linux-gnu-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytesstart.S
arm-unknown-linux-gnu-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-byteshello.c
arm-unknown-linux-gnu-ld -p -X -Thello.ldsstart.o hello.o -o hello
arm-unknown-linux-gnu-ld: hello: Not enough room for program headers, try linking with -N
arm-unknown-linux-gnu-ld: final link failed: Bad value
make: *** Error 1

shang79 发表于 2005-3-2 13:31:31

非常感谢楼上两位的提问,帮我发现了hello4skyeye中间BUG。事实上原来的hello4skyeye,都是使用arm-elf-tools-20030314编译的,因为编译出来的hello可以运行,所以也没有发现其中的问题。

现在使用arm-elf-tools-20040427编译,就出现错误:Not enough room for program headers, try linking with -N

经过检查发现是hello.lds链接控制脚本中,漏写了一个段.rodata,该段包含只读数据应该放在.text段中。所以修改hello.lds如下所示:
   .text :
      {
                *(.text)
                *(.rodata)
      }

另外Start.S中有一处错误,就是b hello,应该改为bl hello。后者表示跳转至hello执行完后返回。

参考资料:
《Executable and Linking Format(ELF) Specification》

黄敏峰 发表于 2005-3-12 17:24:45

也给我发一个吧, 谢谢!

[email protected]
页: [1] 2 3 4 5 6 7 8
查看完整版本: HelloWorld on Skyeye,新手请进!