在树莓派裸机编程中创建 C-library 个存根

creating C-library stubs in raspberry pie bare metal programming

我目前正在使用 raspberry pie 并遵循 Chap 2 of valvers.com 上写得很好的第 2 章教程。我设法理解了所有内容,但我几乎没有停留在标题为 "C-Library stubs" 的最后一节中。因为我面临下面提到的一些疑问:

    #include <sys/stat.h>

/* A helper function written in assembler to aid us in allocating memory */
extern caddr_t _get_stack_pointer(void);

/* Increase program data space. As malloc and related functions depend on this,
   it is useful to have a working implementation. The following suffices for a
   standalone system; it exploits the symbol _end automatically defined by the
   GNU linker. */
caddr_t _sbrk( int incr )
{
    extern char _end;
    static char* heap_end;
    char* prev_heap_end;

    if( heap_end == 0 )
        heap_end = &_end;

     prev_heap_end = heap_end;

     if( ( heap_end + incr) > _get_stack_pointer() )
     {
        while(1)
        {
            /* TRAP HERE! */
        }
     }

     heap_end += incr;
     return (caddr_t)prev_heap_end;
}

到目前为止我只明白这是_sbrk函数的实现。

1). 根据 link?

中给出的教程,我无法理解这段代码的具体作用

2). 我无法理解的另一件事在 armc-008c 和 009c 中很常见,即我们为什么以及如何从 main 函数更改为 kernel_main 功能?唯一可用的文本提到

NOTE: We've now changed from main to kernel_main, and there's a reason for this - the bootloader is actually expecting a slightly different entry definition compared to the standard C main function. So as we're setting up our own C-Runtime anyway, we can define the correct entry format

我是 C 语言的初学者,这些问题听起来可能很菜鸟,但我做了很多研究,并在同一教程上花了 3 到 4 天,然后才在这里问这个问题。我仍在努力理解这些程序背后的逻辑。你们能阐明这个问题吗?这不仅仅是帮助。

提前致谢

您问题中的 _sbrk 函数试图 增加 extern 符号 _end 允许应用程序malloc 更多内存。 (它不直接递增 _end 而是 return 递增的值, heap_end 声明为 static 通过多个 _sbrk 保留值电话)

(我个人怀疑这个 _sbrk 实现是否经过测试,_end 声明为 char 而不是 pointer (* 丢失) 是可疑的并且 heap_end 假设被初始化为 0)

关于mainkernel_main,几乎每个C代码都需要一个入口点,对于普通的libc应用程序是 main (是一个 libc 约定),但正如引用所说,在这种情况下使用了 bootloader 并且它期望(寻找)一个 kernel_main 符号跳入(引导加载程序通常不使用 libc)。 (至少 gcc)编译器的真正入口点是 _start 但 libc 隐藏它并使用它来准备 环境 以启动应用程序,可能是 this帮助您了解它的工作原理。