我目前正在使用树莓派,并在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)。我无法理解这段代码在链接中给出的教程中究竟是做什么的?
2)。我无法理解的另一件事在armc-008c和009c中很常见,即我们为什么以及如何从main函数更改为kernel_main函数?唯一可用的文字提到
注意:我们现在已经从main更改为kernel_main,并且有一个原因 - 引导加载程序实际上期望与标准C主函数相比稍微不同的条目定义。因此,无论如何我们都要设置自己的C-Runtime,我们可以定义正确的输入格式
我是C语言的初学者,这些可能听起来很无聊,但我做了大量的研究,并在同一个教程上花了3到4天才在这里提出这个问题。我仍在努力理解这些程序背后的逻辑。你们能否对这个问题有所了解。它不仅仅是帮助。
提前致谢
答案 0 :(得分:2)
您问题中的_sbrk
函数正在尝试增加 extern 符号_end
,从而使应用程序能够malloc更多内存。 (它不会直接递增_end
但返回递增的值,heap_end
声明为 static 通过多个_sbrk
调用保留值
(我个人怀疑这个 _sbrk
实现是否已经过测试,_end
声明为 char 而不是指针(*缺失)是可疑的,heap_end
假设初始化为0)
关于main
和kernel_main
,几乎每个C代码都需要一个入口点,对于常见的 libc 应用程序是main
(是一个libc约定),但正如引言所说的那样,在这种情况下使用 bootloader 并且它期望(寻找)kernel_main
符号跳转到(引导加载程序通常不会&#39;使用libc)。 (至少gcc)编译器的真正入口点是_start
但是libc隐藏它并使用它来准备环境来启动应用程序,可能this可以帮助你理解它是如何工作的。