2016-09-13 17 views
0

Linux内核中是否有任何需要有效用户空间堆栈的内容?也就是说,如果我要编写一个程序,只能访问数据段中的固定内存位置,或者只使用寄存器进行一些计算,我是否可以安全地将堆栈指针设置为0或另一个无效地址,甚至可以一个有效的地址,而不必担心那里的内存被覆盖?Linux是否需要用户空间堆栈?

  • 我认为硬件中断可以很好地处理,因为它们可以在任何时候发生,并且内核在处理这些中断时不会对用户空间的状态做出假设。
  • 虽然在映射页面发生故障呢?
  • 如何进行系统调用?当然不是通过libc,而是直接通过?

附加问题:有人知道有关其他操作系统的问题的答案,例如: MacOS X,BSD,Windows?

+0

为什么你认为堆栈这样的负担? *“如果我要编写一个程序......”* - 为什么不尝试编写这样一个不重要的程序来查看这是否可能? *“我安全地将堆栈指针设置为0 ...”* - 除非你破解内核,否则*你希望这样做?仅供参考许多处理器体系结构和C语言(以及其他高级语言)都需要堆栈,因此它不仅仅是Linux操作系统。 IOW C和Linux通常仅用于具有硬件堆栈支持的处理器。 – sawdust

+0

@sawdust在评论中很难回答你所有的问题。我不能仅仅测试它,因为这并不能保证我所做的事实际上是允许的;它可能恰好适用于我的测试,并打破下一个内核版本或体系结构。堆栈指针可以通过'movq $ 0,%rsp'进行简单的修改,不需要内核入侵。 x86只需要一个用于ISR的堆栈,这与用户空间无关(当然,您不能推/ pop/call/ret)。另外,我知道C,但那不是我的问题。我询问_kernel_是否需要一个有效的_user space_堆栈。 –

+0

为了给出更多的上下文:我不一定要完全避免堆栈(尽管这将是一个有趣的实验)。我正在考虑使用适合当前线程/光纤的最大调用图的正确大小的非常小的堆栈。这意味着堆栈有时可能完全满,并且不一定在页面边界上结束。我想确定内核可以处理这种情况。也许用不同的方式来解释这个问题:Linux内核是否需要用户空间来遵循特定的ABI? –

回答

1

我怀疑任何人都可以很有信心地告诉你,但我会采取刺。

我的猜测是,在技术上没有堆栈运行是可行的,但获得正确的细节将是非常困难的。

中断和异常(例如,页面错误)应将寄存器保存到内核堆栈而不是用户空间堆栈,因此这没有问题。如果直接在汇编中编码,系统调用甚至应该可以工作(除非你在32位模式下运行并且使用5个以上的参数,在这种情况下,第六个在用户堆栈上,但你仍然可以很容易地修复它)。 gdb希望你的堆栈安排如此。

其他事情要考虑:

通常,您被分配在启动时堆栈区域。不确定;你可以通过适当的链接器指令来改变它。堆栈区域通常配置为向下生长。当地址不在任何当前分配的区域中时出现页面错误时,假定要生成堆栈区域。错误地址不得少于sp(即esp/rsp)(少于64K软件)的值。我想这不是一个问题,如果你不使用堆栈。

当您调用clone系统调用来创建一个新任务(线程)时,您为新任务提供了一个堆栈指针。我不确定内核究竟做了什么,看起来只是填入新任务中的sp寄存器(如果它不为零)。这导致我...

clone系统调用和其他一些没有很好地指定。 libc中嵌入了许多魔术来正确处理forkpthread_create等等。如果你想创建额外的线程,你必须知道这个魔法并自己实现它。

信号处理希望能够将参数推送到用户空间堆栈。我不认为你可以在没有堆栈的情况下使用信号 - 或者至少它会非常复杂。

+0

因此,看起来我只是需要对内核有信心,而不是做出意想不到的事情。至少Linux有一个永不破坏用户空间的策略。感谢你提醒我关于clone()和朋友的特殊待遇,这是我不得不留意的事情。对于信号处理程序,可以用'sigaltstack(2)'设置一个备用栈。 –