在这个问题的帮助下,我想学习和填补我的知识空白 因此,用户正在运行一个线程(内核级),现在它调用yield(我认为是一个系统调用)。调度程序现在必须将当前线程的上下文保存在TCB中(存储在内核中的某个地方),然后select另一个线程运行并加载其上下文并跳转到其CS:EIP。 为了缩小范围,我正在研究运行在x86架构之上的Linux。 现在,我想进入细节: 所以,首先我们有一个系统调用: 1)yield的包装函数将系统调用参数推送到堆栈上。 按下返回地址,并将系统调用号码压入某个寄存器(例如EAX),引发中断。 2)中断将CPU模式从用户切换到内核,并跳转到中断向量表,并从那里到内核中的实际系统调用。 3)我想调度器现在被调用,现在它必须保存TCB中的当前状态。 这是我的困境。 因为调度器将使用内核堆栈而不是用户堆栈来执行其操作(这意味着SS和SP必须被改变),它如何在不修改任何寄存器的情况下存储用户的状态。 我已经在论坛上看到有保存状态的特殊硬件指令,但是调度程序如何访问它们以及谁在运行这些指令? 4)调度器现在将状态存储到TCB中并加载另一个TCB 5)当调度程序运行原始线程时,控件返回到清除堆栈和线程继续的包装函数 旁边的问题:调度程序是否作为内核线程运行(即只能运行内核代码的线程)? 每个内核线程或每个进程是否有单独的内核堆栈?
我正在学习linux内核的内部知识,在阅读“理解Linux内核”的同时,还碰到了很多与内存有关的问题。 其中之一是,如果我的系统上安装了只有512MB的物理内存,Linux内核如何处理内存映射。 就像我读的那样,内核映射0(或16)MB-896MB物理内存到0xC0000000的线性地址并且可以直接对它进行寻址。 所以,在上面描述的情况下,我只有512 MB: 内核如何从仅512 MB映射896 MB? 在所描述的scheme中,内核进行设置,以便每个进程的页表将从0xC0000000到0xFFFFFFFF(1GB)的虚拟地址直接映射到从0x00000000到0x3FFFFFFF(1GB)的物理地址。 但是,当我只有512 MB物理RAM时,如何映射虚拟地址从0xC0000000-0xFFFFFFFF到物理0x00000000-0x3FFFFFFF? 点是我有一个物理范围只有0x00000000-0x20000000。 在这种情况下用户模式进程呢? 每篇文章只解释了情况,当你安装了4GB内存,内核将1GB映射到内核空间,用户进程使用剩余的RAM。 我会感谢任何帮助提高我的理解。 谢谢..!
我希望有人能够解释linux内核源码中使用的__usermacros的细微差别。 首先,macros观: # define __user __attribute__((noderef, address_space(1))) 现在,经过一些Googlesearch,我发现这个macros允许指定一个指针属于用户地址空间,而不应该解除引用。 我可能会错过一些明显的事实,但是有人可以解释一下这个macros的含义吗? 举个例子,这个macros在哪里可以被使用,这是一个很好的例子。 再次,原谅我,如果我失去了一些明显的东西。 为了说明这一点,我在考察一些USB代码(linux / usbdevice_fs.h)的同时,把它与macros相关联。 我只是在寻找这个macros(或其他类似的)在内核中使用的一般理解。 感谢您的期待!
内核和用户线程之间是否有关系? 一些操作系统教科书说“ 将一个(许多)用户线程映射到一个(许多)内核线程”。 地图在这里意味着什么?
据我所知, initrd作为一个块设备,因此需要一个文件系统驱动程序(如ext2 )。 内核必须至less有一个用于检测initrd文件系统的内置模块。 在本文中, 介绍初始RAM磁盘的新模型initramfs ,它写道: 但是由于caching的原因,ramdisk实际上浪费了更多的内存。 Linux被devise为caching从块设备读取或写入到块设备的所有文件和目录条目,因此Linux将数据从RAM存储器复制到“页面caching”(用于文件数据)和“dentry cache”(用于目录条目) 。 虚拟硬盘伪装成块设备的缺点是它被视为块设备。 什么是page cache和dentry cache ? 在该段落中,是否意味着数据被复制,因为ramdisk被视为块设备,因此所有数据都被caching? 相反, ramfs : 几年前,Linus Torvalds有一个很好的想法:如果Linux的caching可以像文件系统一样安装? 只要将文件保存在caching中,永远不要删除它们,直到它们被删除或系统重新启动? Linus在名为“ramfs”的caching中写了一个小小的包装,其他内核开发人员创build了一个名为“tmpfs”的改进版本(它可以将数据写入交换空间,并限制给定挂载点的大小,所有可用内存)。 Initramfs是tmpfs的一个实例。 这些基于ram的文件系统会自动增长或缩小以适应其包含的数据的大小。 将文件添加到ramfs(或扩展现有文件)将自动分配更多的内存,删除或截断文件将释放该内存。 块设备和caching之间没有重复,因为没有块设备。 caching中的副本是数据的唯一副本。 最重要的是,这不是新的代码,而是现有Linuxcaching代码的新应用程序,这意味着它几乎没有添加任何大小,非常简单,并且基于经过严格testing的基础架构。 总之, ramfs只是文件打开并加载到内存中,不是吗? initrd和ramfs都是在编译时压缩的,不同之处在于, initrd是一个解压缩的块设备,在启动时被内核挂载,而ramfs通过cpio解压到内存中。 我对么? 或者ramfs是一个非常小的文件系统? 最后,直到今天, initrd映像仍然存在于最新的内核中。 但是, initrd实际上就是今天使用的ramfs ,名字只是为了历史的目的?
我想学习linux内核编程。 那会是什么起点呢? 什么可能是一些更简单的问题的目标? 提前致谢
用你自己的话来解释什么是抢占,这对于一个(linux)内核意味着什么? 拥有可抢占内核的优点和缺点是什么?
这是有道理的,像一个操作系统的东西会写在C.但是,它有多less,什么样的C? 我的意思是,在C中,如果你需要一些堆内存,你可以调用malloc。 但是,操作系统甚至有一堆? 据我所知,malloc 要求操作系统的内存 ,然后将其添加到链表或二叉树,或其他东西。 怎么样一个调用堆栈? 操作系统负责设置其他应用程序使用的所有东西 ,但是它是如何实现的? 当你想用C打开或创build一个文件时,相应的function会向操作系统询问该文件。 那么…那个电话的另一端是什么样的C? 或者在内存分配的另一端? 另外,一个操作系统实际上可以用C编写多less? 所有的? 依赖于架构的代码是什么? 那么更高层次的抽象层次呢 – 是否会用C ++等高级语言编写? 我的意思是,我只是出于好奇而问这个问题。 我现在正在下载最新的linux内核,但是这是永远的。 我不确定是否能够遵循代码 – 或者如果我将陷入一个我从未见过的复杂networking。
我不明白操作系统和内核之间的区别。 有人可以解释吗?
如果我加载一个内核模块,并用lsmod列出加载的模块,我可以得到模块的“使用计数”(其他模块的数量与模块的引用)。 有没有办法找出什么是使用模块,但? 问题是我正在开发的模块坚持使用count为1,因此我不能使用rmmod来卸载它,但是它的“by”列是空的。 这意味着每次我想重新编译和重新加载模块,我都必须重新启动机器(或者,至less,我不能找出任何其他方式来卸载它)。