Main函数的第一个函数Init_BSS()
位于./src/geekos/mem.c中
/*
* Initialize the .bss section of the kernel executable image.
*/
void Init_BSS(void)
{
extern char BSS_START, BSS_END;
/* Fill .bss with zeroes */
memset(&BSS_START, '\0', &BSS_END - &BSS_START);
}
可以看到Init_BSS函数清空了从BSS_START到BSS_END的内存。
先来看memset的实现
位于./src/common/string.c中
void* memset(void* s, int c, size_t n)
{
unsigned char* p = (unsigned char*) s;
while (n > 0) {
*p++ = (unsigned char) c;
--n;
}
return s;
}
和C语言的memset功能一样,实现也很简单。
再来看一下外部声明BSS_START,BSS_END
位于/include/geekos/defs.h
/*
* The windows versions of gcc use slightly different
* names for the bss begin and end symbols than the Linux version.
*/
#if defined(GNU_WIN32)
# define BSS_START _bss_start__
# define BSS_END _bss_end__
#else
# define BSS_START __bss_start
# define BSS_END end
#endif
在project0下使用命令
$find ./ | xargs grep GNU_WIN32
可以看到,GNU_WIN32标志在./build/Makefile中定义,
用于区别windows下的cygwin编译环境和linux下的gcc,两者生成的elf文件的符号有细微的差别。
明显在Linux中定义的是后者。
再次搜索
$find ./ | xargs grep __bss_start
可以看到__bss_start符号出现在内核符号表kernel.syms中
我把这一段贴出来
0001a5dc A __bss_start
00018b58 r __func__.1314
000185fb r __func__.1319
00018fcd r __func__.1319
00019289 r __func__.1319
00018ad2 r __func__.1331
000188f1 r __func__.1333
0001860c r __func__.1335
00018fde r __func__.1335
0001