2013年11月22日 星期五

一步步写嵌入式操作系统:ARM编程的方法与实践 - 第1個 helloworld.c 範例

這是一步步写嵌入式操作系统:ARM 编程的方法与实践的第一個範例。

helloworld.c
 1 /*
 2 helloworld.c:
 3 Copyright (C) 2009  david leels <davidontech@gmail.com>
 4 
 5 This program is free software: you can redistribute it and/or modify
 6 it under the terms of the GNU General Public License as published by
 7 the Free Software Foundation, either version 3 of the License, or
 8 (at your option) any later version.
 9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see http://www.gnu.org/licenses/.
17 */
18 
19 #define UFCON0 ((volatile unsigned int *)(0x50000020))
20 
21 void helloworld(void){
22  const char *p="helloworld\n";
23  while(*p){
24   *UFCON0=*p++;
25  };
26  while(1);
27 }

很不順, 照著書上跑 skyeye 執行 helloworld.c 竟然給我這個:

arch: arm
cpu info: armv4, arm920t, 41009200, ff00fff0, 2
mach info: name s3c2410x, mach_init addr 0x806dee0
SKYEYE: use arm920t mmu ops

**************************** WARNING **********************************
If you want to run ELF image, you should use -e option to indicate
your elf-format image filename. Or you only want to run binary image,
you need to set the filename of the image and its entry in skyeye.conf.
***********************************************************************

Your elf file is little endian.
uart_mod:0, desc_in:, desc_out:, converter:
Loaded RAM   ./helloworld.bin
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 7, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 13, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 16, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 19, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 25, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 28, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 31, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 37, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 40, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 43, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 49, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 52, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 55, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 61, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 64, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 67, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 73, mem_read_word addr = fffffff8 no bank
^DSKYEYE:Error in mem_read_word, no bank found, NumInstrs 76, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 79, mem_read_word addr = fffffff8 no bank
SKYEYE:Error in mem_read_word, no bank found, NumInstrs 85, mem_read_word addr = fffffff8 no bank

我嚇傻了,  怎麼這樣勒?

找到這篇有了答案
http://hi.baidu.com/vtrsazxaxjcdfge/item/4826cdaecf0f4c328919d354

加上 L7 搞定。

skyeye.conf
1 cpu:  arm920t
2 mach: s3c2410x
3   
4 #physical memory
5 mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000, file=./helloworld.bin, boot=yes
6 #ref : http://hi.baidu.com/vtrsazxaxjcdfge/item/4826cdaecf0f4c328919d354 for stack address
7 mem_bank: map=M, type=RW, addr=0xfff00000, size=0x000fffff 
8 #all peripherals I/O mapping area
9 mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000

不過我可不是在重複說明人家已經知道的事情, 我要來討論為什麼 stack 沒設定會產生這種結果? 下面是反組譯的程式碼, 看不懂 arm 組合語言是吧? 我也是, 所以只看這行 (L8) 就好 ...

/usr/leeos_tools_for_linux/bin/arm-elf-objdump -d helloworld.c.elf
 1 
 2 helloworld.c.elf:     file format elf32-littlearm
 3 
 4 
 5 Disassembly of section .text:
 6 
 7 00000000 <helloworld>:
 8    0: e52db004  push {fp}  ; (str fp, [sp, #-4]!)
 9    4: e28db000  add fp, sp, #0
10    8: e24dd004  sub sp, sp, #4
11    c: e59f3038  ldr r3, [pc, #56] ; 4c <helloworld+0x4c>
12   10: e50b3004  str r3, [fp, #-4]
13   14: ea000007  b 38 <helloworld+0x38>
14   18: e3a03205  mov r3, #1342177280 ; 0x50000000
15   1c: e2833020  add r3, r3, #32
16   20: e51b2004  ldr r2, [fp, #-4]
17   24: e5d22000  ldrb r2, [r2]
18   28: e5832000  str r2, [r3]
19   2c: e51b3004  ldr r3, [fp, #-4]
20   30: e2833001  add r3, r3, #1
21   34: e50b3004  str r3, [fp, #-4]
22   38: e51b3004  ldr r3, [fp, #-4]
23   3c: e5d33000  ldrb r3, [r3]
24   40: e3530000  cmp r3, #0
25   44: 1afffff3  bne 18 <helloworld+0x18>
26   48: eafffffe  b 48 <helloworld+0x48>
27   4c: 00000050  .word 0x00000050

還沒找到類似 bochs 的模擬器, 只好用猜的, 看看

 8    0: e52db004  push {fp}  ; (str fp, [sp, #-4]!)

push 指令會動到 stack, 那從 helloworld.c 有看到那行在設定 stack 嗎?沒有, 所以 stack 可能在某塊不能存取的地方, 恭喜踩到地雷, 連結提到的 stack 位址因為沒有好用的模擬器可用來觀察, 就只能先相信了。而實際上把這段 stack 位址補上也的確能正常執行。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。