【发布时间】:2015-05-03 17:19:46
【问题描述】:
我尝试编写一个非常简单的操作系统来更好地理解基本原理。我需要实现用户空间malloc。所以一开始我想在我的 linux 机器上实现和测试它。
一开始我通过以下方式实现了sbrk()函数
void* sbrk( int increment ) {
return ( void* )syscall(__NR_brk, increment );
}
但是这段代码不起作用。相反,当我使用 os 提供的 sbrk 时,效果很好。
我尝试使用 sbrk() 的另一种实现
static void *sbrk(signed increment)
{
size_t newbrk;
static size_t oldbrk = 0;
static size_t curbrk = 0;
if (oldbrk == 0)
curbrk = oldbrk = brk(0);
if (increment == 0)
return (void *) curbrk;
newbrk = curbrk + increment;
if (brk(newbrk) == curbrk)
return (void *) -1;
oldbrk = curbrk;
curbrk = newbrk;
return (void *) oldbrk;
}
从此函数调用的sbrk
static Header *morecore(unsigned nu)
{
char *cp;
Header *up;
if (nu < NALLOC)
nu = NALLOC;
cp = sbrk(nu * sizeof(Header));
if (cp == (char *) -1)
return NULL;
up = (Header *) cp;
up->s.size = nu; // ***Segmentation fault
free((void *)(up + 1));
return freep;
}
此代码也不起作用,就行(***)我得到分段错误。 哪里出了问题?
谢谢大家。我已经使用 sbrk 的新实现解决了我的问题。给定的代码工作正常。
void* __sbrk__(intptr_t increment)
{
void *new, *old = (void *)syscall(__NR_brk, 0);
new = (void *)syscall(__NR_brk, ((uintptr_t)old) + increment);
return (((uintptr_t)new) == (((uintptr_t)old) + increment)) ? old :
(void *)-1;
}
【问题讨论】:
-
有趣的问题,但您可能应该扩展“不起作用”。
-
我已经提到了问题的原因。请参见上文。
-
你为什么要“模拟”像
sbrk这样的系统调用?你应该编辑你的问题来激发它。 -
我尝试写一个非常简单的os来更好地理解基本原理。我需要实现用户空间malloc。所以一开始我想在我的 linux 机器上实现和测试它。
-
那么,你不需要定义
sbrk(你可以使用系统提供的)。你需要在你的malloc中使用mmap并且你的内核应该有mmap或者一些等效的方法来改变地址空间。你可以在 Qemu 下运行你的操作系统。顺便说一句,请编辑您的问题,不要只在 cmets 中给出重要的动机!
标签: linux malloc system-calls dynamic-memory-allocation sbrk