原文链接:https://wiki.osdev.org/Libgcc_without_red_zone
主页:https://blog.csdn.net/qq_37422196/article/details/122591214
下面的链接如果指向原网站的话,大概是还没有翻译
在赶了在赶了……
主条目:libgcc
本文讨论了如何构建libgcc而无需在内核中支持红色区域
。如果你的目标平台不是X86-64,你就不需要它,因为i*86没有这样的要求
什么是"红色区域"
红色区域
是x86-64 ABI中描述的功能
红色区域是堆栈指针(rsp)以下的128字节区域(rsp-128 ~ rsp)。该区域可供编译器自由使用,无需通知应用程序/操作系统或任何正在运行的中断处理程序
对于用户应用程序这没有问题,因为中断和其他内核相关代码不会干扰用户堆栈。然而,在你的内核中,事情可能会变得很糟糕,特别是如果你有嵌套中断并且没有红色区域
支持。想象一下在你的中断处理程序运行时,gcc将一些数据放入红色区域,这时发生嵌套中断并破坏红色区域
。反之亦然
为了解决这个问题,可以通过将-mno-red-zone
传递给GCC来禁用红色区域
x86_64-elf-gcc $CFLAGS -mno-red-zone ...
为什么要修改libgcc
如果你链接到(也应该链接到)libgcc,则会出现一个问题:libgcc是在启用红色区域
下构建的
因此,虽然你的内核工作得很好,但libgcc中的方法可能会意外地把事情搞砸。解决方案很简单——添加-mno-red-zone
重构libgcc。幸运的是,GCC通过在其源代码树中提供多库支持,以直接支持这一点
准备
主条目:GCC交叉编译器
按照构建GCC交叉编译器时的说明提取和准备GCC源代码,但暂时不要运行configure
创建以下文件并将其保存为GCC源文件树下的gcc/config/i386/t-x86_64-elf
# 添加没有红色区域的libgcc multilib变体MULTILIB_OPTIONS += mno-red-zone
MULTILIB_DIRNAMES += no-red-zone
默认情况下,除非明确告知,否则GCC不会使用此新配置。在你喜欢的编辑器中打开gcc/config.gcc
并搜索case块,如下所示:
x86_64-*-elf*)tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h";;
这是为x86_64-elf创建GCC交叉编译器时使用的目标配置。修改它以包含新的multilib配置:
x86_64-*-elf*)tmake_file="${tmake_file} i386/t-x86_64-elf" # include the new multilib configurationtm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h";;
构建libgcc
运行configure然后像往常一样调用all-target-libgcc
和install-target-libgcc
,GCC将构建两个版本的libgcc——一个启用红色区域
,一个不启用。你可以通过检查已安装的libgcc.a归档文件来检查构建是否成功:
find $TOOLCHAIN_PREFIX/lib -name 'libgcc.a'
如果一切顺利,你应该会看到在no-red-zone
multilib目录中安装了一个额外的libgcc:
./gcc/x86_64-pc-elf/4.9.1/libgcc.a
./gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a
链接到正确的 multilib 版本
假设你使用GCC来链接你的内核。所需要的只是在进行最后的链接器调用时确保-mno-red-zone
在你的LDFLAGS
中
x86_64-elf-gcc $LDFLAGS -mno-red-zone -o kernel $SOURCES
如果你不确定使用的哪个libgcc版本,可以通过将-mno-red-zone
和-print-libgcc-file-name
传递给GCC来检查:
x86_64-elf-gcc -mno-red-zone -print-libgcc-file-name
lib/gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a
相关内容
文章
- GCC
- GCC交叉编译器
- libgcc
- Bare Bones