问题标签 [osdev]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
x86 - (写内核)如何修改中断描述符表?
我正在编写一个小内核,只是为了稍微了解一下低级的东西。现在,它在 Virtual Box 中启动,我可以在屏幕上显示文本、分配一些内存以及其他非常基本的事情。它是用 C++ 和一点 asm 编写的。
我想探索的一件事是多任务处理背后的机制。据我了解,它是这样的:
- 内核初始化中断描述符表,以便周期性地(例如毫秒)发出中断并调用内核中定义的例程。
- 当例程被调用时,它可以决定将代码/数据段和堆栈指针设置为另一个程序的上下文,即“上下文切换”。
所以,它在概念上似乎很简单,但我知道细节会变得更加复杂。我在网上找到了一些东西,但术语变化很大,而且这些例子似乎来自我没有的上下文(比如来自 Linux 内核)。
但是,设置描述符表的方式似乎是这样的:
- 将一些数据发送到 PIC(
outb
以及其他)以对其进行初始化。 - 在内存中准备一个中断表,其中包含指向所需例程的函数指针,注意这些函数能够成为信号处理程序。
- 用 加载表
lidt
。
但是,我找不到太多关于专门做这些事情的信息,或者这是否正确。有没有人有困惑的内核编写者的资源?
assembly - 与 CMPSB 指令混淆
我一直在看这段代码,我对rep cmpsb行感到困惑。
我知道它重复 cmpsb cx 次,但这如何比较两个字符串?比如说比较“Hey\0”和“hey\0”,这个循环比较4个字符串。第一个字符不同,并且 EFlags 寄存器将被相应地设置。但是,cmpsb指令会重复,并且下一个字符将是相同的。我可能误解了cmpsb 的工作原理,但看起来这个循环没有正确比较两个字符串。这个循环真的有效吗?
gcc - 成功构建了 GCC 交叉编译器工具链。如何正确设置环境变量?
我不知道这是否是关于如何为交叉编译工具链设置环境变量的正确位置。工具链的目的是开发操作系统。我正在使用 Ubuntu 12.04 LTS。问题是如何为工具链设置环境变量。交叉编译工具链的路径是
我希望能够使用 GCC 交叉编译器工具链,但仍然能够使用 Ubuntu 附带的 GCC 工具链。如果我不清楚,请随时问我一些问题,或者如果您需要有关我想要实现的目标的更多信息。
c - 简单 C 引导程序/内核的问题
最近,我开始对编写自己的非常基本的操作系统感兴趣。我写了(好吧,复制了)一些基本的程序集,它建立了一个堆栈并做了一些基本的事情,这似乎工作得很好,但是试图将 C 引入混合中却把一切都搞砸了。
我有两个主要的项目文件:loader.s 是一些 NASM,它创建堆栈并调用我的 C 函数,以及 kernel.c 包含基本的 C 函数。
我目前的问题本质上是当我运行 kernel.bin 文件时 QEMU 冻结了。我猜我的代码有很多问题——也许这个问题并不适合 StackOverflow 格式,因为它非常特殊。我的项目文件如下:
装载机.s:
内核.c:
我像这样编译所有东西:
nasm -f elf -o loader.o loader.s
i386-elf-gcc -I/usr/include -o kernel.o -c kernel.c -Wall -nostdlib -fno-builtin -nostartfiles -nodefaultlibs
i386-elf-ld -T linker.ld -o kernel.bin loader.o kernel.o
然后像这样测试:
qemu-system-x86_64 -kernel kernel.bin
希望有人可以帮我看看这个——代码片段不是很长。
谢谢。
gcc - 使用队列切换任务
我正在开发自己的爱好操作系统,现在我遇到了调度程序/任务切换的问题。
我计划使用 FIFO 队列作为结构来保存进程。我使用链表实现了它。
我还决定使用 iret 方法从一个任务切换到另一个(因此,当操作系统在 iret 之前提供中断请求时,我更改了 ESP 寄存器以转移到新任务)。
但我有一个问题。当操作系统启动时,它会启动两个任务:
- 闲置的
- 壳
有了这两个我没有问题。但是,如果我尝试启动另外两个任务(里面有一个简单的 printf),则任务队列已损坏。
如果在那之后我尝试打印队列它只打印两个刚刚创建的任务并且空闲和shell消失了,但是操作系统继续工作(我认为在特定时刻新任务的esp字段被替换了带有外壳的 esp 内容)。
任务数据结构为:
和 tss 是:
调度器函数如下:
tss 使用以下值初始化:
创建新任务的函数如下:
我确定我只是忘记了一些东西,或者我错过了一些考虑。但我无法弄清楚我错过了什么。
实际上我只在内核模式下工作,并且在相同的地址空间内(启用分页,但实际上我对所有任务使用相同的 pagedir)。
ISR 宏在这里定义: https ://github.com/inuyasha82/DreamOs/blob/master/include/processore/handlers.h
为了处理 ISR,我声明了四种函数:
- 例外
- EXCEPTION_EC(带有错误代码的异常)
- 中断请求
- 系统调用
显然调度程序是由一个 IRQ 例程调用的,所以宏看起来像:
中断处理函数是:
这些是 enqueue_task 和 dequeue_task 函数:
提前致谢,如果您需要更多详细信息,请告诉我!
assembly - 以独立于操作系统的汇编语言打开文件
我一直在试图弄清楚如何在汇编中从硬盘驱动器中打开文件。我想在不使用 DOS 中断或任何需要操作系统的情况下执行此操作,因为我正在尝试构建一个简单的操作系统。当然,我对 BIOS 中断很好。
assembly - 组装 - 读取虚拟磁盘的下一个扇区
作为世界上至少有一次在他/她的生活中的程序员,我正在尝试创建我的“革命性”,新的和唯一的操作系统。:D
好吧,我正在使用一个虚拟模拟器(Oracle VM Virtual Box),为此我创建了一个新的未知操作系统,带有一个 vmdk 磁盘。我喜欢 vmdk 因为它们只是普通文件,所以我可以将引导加载程序粘贴到虚拟硬盘的前 512 个字节上。
现在,我正在尝试读取该虚拟磁盘的下一个扇区,我将在该扇区上粘贴一个显示消息的简单内核。
我有两个问题:
我是否正确读取了第二段(前 -512 字节 - 被引导加载程序占用)? 代码:
在这里,我在检查 CF 后收到错误消息。但是,如果我使用 INT 13, 1 来获取最后一条状态消息,则 AL 为 0 - 因此不会保存任何错误。
我是否将我的简单内核粘贴到 vmdk 内的正确位置?我所做的是将它粘贴在文件的第 512 个字节之后,正如我所说,前 512 个字节是引导加载程序。该文件如下所示:
/li>
所以,这就是我试图将内核添加到第二个扇区的方式。你认为这有什么问题?谢谢!
更新
好的,我现在没有收到任何错误,但我没有看到正在执行的加载代码。它应该在窗口上显示一个点:
c - C中变量的位置
我试图了解 C 如何将内存分配给全局变量。
我正在研究一个简单的内核。到目前为止,除了打印到屏幕和启用中断之外,它不能做更多的事情。我现在正在开发一个基本的物理内存管理器。
我的内存管理器是一个位图,如果内存已分配或可用,则设置为 1 或 0。我需要将我的内核正在使用的内存作为“已分配”添加到位图中,因此没有任何内容会覆盖它。
我可以很容易地找到内核的开始,因为它被静态加载到 0x100000。弄清楚长度也不应该太难。我不确定的部分是全局变量在内存中的位置?
假设我的内核是 12K,然后我可以将这些 3x 4K 内存块分配给它以进行保护。我需要分配更多来覆盖它使用的变量吗?或者变量是 12K 的一部分?
谢谢你的帮助,我希望我有足够的意义。
c - 简单的 C 内核字符指针不起作用
我正在尝试使用 C 制作一个简单的内核。一切都加载并正常工作,我可以访问视频内存和显示字符,但是当我尝试实现一个简单的 puts 函数时,由于某种原因它不起作用。我已经尝试过自己的代码和其他代码。此外,当我尝试使用在函数外部声明的变量时,它似乎不起作用。这是我自己的代码:
(spos
起始位置)的东西是因为我无法制作全局位置变量。putc
工作正常,但puts
没有。我也试过这个:
为什么这不起作用?我尝试将我的 puts 实现与我的原生 GCC 一起使用(没有颜色和 spos 数据并使用printf("%c")
),它运行良好。
c - 编译和链接 C 代码,输出文件中没有任何附加数据
由于缺乏使用 GCC 和 ld 的知识,我正在寻求专业人士的帮助。我正在为教育目的编写操作系统,并且在编译和链接 C 代码时遇到问题。老实说,这没有任何问题,但我对 GCC 和 LD 生成的输出文件中的不必要数据感到困惑,比如
等等。我真的需要知道哪些参数同时用于 gcc 和 ld 以减少这种无用的(对于我的操作系统)数据
我之前使用的参数: -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -fstrength-reduce -finline-functions 我也使用链接描述文件来组织段。
我尝试使用 objcopy 来减少输出中的 .comment 和 .note 等块,对我来说这是最好的解决方案