linux - 当我使用 Makefile 构建简单内核时出现 '__aeabi_STH' 错误

标签 linux build makefile

现在,我正在尝试制作一个简单的内核,它在启动后只打印“Hello world”。

我想使用arm-linux-gnueabihf-gcc-4.8,

所以我这样写Makefile

CC = arm-linux-gnueabihf-gcc-4.8
LD = arm-linux-gnueabihf-ld
OC = arm-linux-gnueabihf-objcopy

#CC = arm-none-eabi-gcc
#LD = arm-none-eabi-ld
#OC = arm-none-eabi-objcopy

CFLAGS  = -nostdinc -I. -I../include
CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs -O2 
CFLAGS += -fno-strict-aliasing -fno-common -pipe #-mapcs-32
CFLAGS += -mcpu=xscale -msoft-float -fno-builtin #-mshort-load-bytes

LDFLAGS = -static -nostdlib -nostartfiles -nodefaultlibs -p -X -T ./main-ld-script

OCFLAGS = -O binary -R .note -R .comment -S

all: karlinux.c
    $(CC) -c $(CFLAGS) -o entry.o entry.S
    $(CC) -c $(CFLAGS) -o gpio.o gpio.c
    $(CC) -c $(CFLAGS) -o time.o time.c
    $(CC) -c $(CFLAGS) -o vsprintf.o vsprintf.c
    $(CC) -c $(CFLAGS) -o printf.o printf.c
    $(CC) -c $(CFLAGS) -o string.o string.c
    $(CC) -c $(CFLAGS) -o serial.o serial.c
    $(CC) -c $(CFLAGS) -o lib1funcs.o lib1funcs.S
    $(CC) -c $(CFLAGS) -o karlinux.o karlinux.c
    $(LD) $(LDFLAGS) -o karlinux_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o karlinux.o
    $(OC) $(OCFLAGS) karlinux_elf karlinux_img

clean:
    rm *.o
    rm karlinux_elf
    rm karlinux_img

但是,当 LD 执行某些操作时,我遇到了错误。

错误消息是

xaliver@ubuntu:~/Documents/Karlinux/Karlinux/main$ make
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o entry.o entry.S
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o gpio.o gpio.c
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o time.o time.c
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o vsprintf.o vsprintf.c
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o printf.o printf.c
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o string.o string.c
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o serial.o serial.c
serial.c:26:0: warning: "__REG" redefined [enabled by default]
 #define __REG(x) (x) 
 ^
In file included from serial.c:18:0:
../include/pxa255.h:46:0: note: this is the location of the previous definition
 #define __REG(x)   (*((volatile Word *) io_p2v (x))) 
 ^
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o lib1funcs.o lib1funcs.S
arm-linux-gnueabihf-gcc-4.8 -c -nostdinc -I. -I../include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe  -mcpu=xscale -msoft-float -fno-builtin  -o karlinux.o karlinux.c
arm-linux-gnueabihf-ld -static -nostdlib -nostartfiles -nodefaultlibs -p -X -T ./main-ld-script -o karlinux_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o karlinux.o
time.o: In function `SetWatchdog':
time.c:(.text+0x14): undefined reference to `__aeabi_idiv'
vsprintf.o: In function `number':
vsprintf.c:(.text+0x18e): undefined reference to `__aeabi_uidiv'
vsprintf.c:(.text+0x1a4): undefined reference to `__aeabi_uidivmod'
vsprintf.c:(.text+0x22a): undefined reference to `__stack_chk_fail'
vsprintf.c:(.text+0x230): undefined reference to `__stack_chk_guard'
printf.o: In function `printf':
printf.c:(.text+0x5e): undefined reference to `__stack_chk_fail'
printf.c:(.text+0x68): undefined reference to `__stack_chk_guard'
make: *** [all] Error 1

有人知道如何链接这些功能吗?

请帮助我。

最佳答案

我想你和我有同一本书。

ARM架构没有“除法”指令,因此当编译器(gcc交叉编译器)遇到“1/2”等除法指令时,会转换为“__aeabi_uidiv()”、“__aeabi_uidivmod()”等函数。

当您的链接器“arm-linux-gnueabihf-ld”处理链接时,链接器尝试查找包含 __aeabi_uidiv' 函数(和其他函数)的库。该库是 libgcc.a,但您指定了选项“-nostdlib -nodefaultlib”,因此链接器无法找到 __aeabi_uidiv()' 函数的主体。链接失败。

在我看来,作者的意图是将这样的翻译函数__aeabi_uidiv()包含在lib1funcs.s中。书中包含的工具链是 gcc-3.3.2。该版本的 gcc arm 交叉编译器将除法翻译为“__udivsi3()”函数,而不是“__aeabi_uidiv()”。 '__udivsi3()'函数实现包含在'lib1funcs.s'中。

总而言之,解决方案有两个。

  1. 使用 gcc-3.3.2 的工具链,而不是你的。 (推荐)
  2. 将“lib1funcs.s”文件中的名称“__udivsi3()”和“__udivsi3...()”更改为“__aeabi_uidiv()”“__aeabi_uidiv...()”

我尝试了第二种方法并成功了,但是这个“ undefined reference ...”问题再次出现在本书的下一个示例中,这让我发疯。为了在第二种方法中取得成功,我认为需要对编译和链接过程有相对更深入的理解。我推荐第一种方法。

关于linux - 当我使用 Makefile 构建简单内核时出现 '__aeabi_STH' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26361552/

相关文章:

linux - awk 跳过空行

MySQL linux 服务器和 my.cnf 优化多行

visual-studio - VS 构建后事件

docker - Makefile with Docker Compose,如何防止每次构建?

makefile - 生成文件中 -DHAVE_CONFIG_H 的含义

linux - UUID真的是唯一的吗?为什么我们可以将多个 UUID 分配给单个磁盘片

Angular 13 Prerender 错误找不到主包

android - 找不到构建工具修订版 27.1.1。当我尝试下载时,说它没有下载链接 :

c - 在 Makefile 中,是否可以创建具有通用依赖项的通用规则?

java - 首选的 CGI 技术是什么?