标签: osdev

在保护模式下进行间接远跳转/调用

如何在保护模式下执行间接远跳转/调用?首先我认为这样做是允许的:

jmp 0x10:eax;
Run Code Online (Sandbox Code Playgroud)

(不用担心段选择器..我的 GDT 的第二个条目是有效的代码段)

但是当nasm组装的时候,却出现了语法错误。查看Intel(指令集参考)手册的Book 2a,只能使用 来完成jmp ptr16:32,其中ptr16:32是立即值,或者使用 来完成jmp m16:32,其中 是m16:32包含48位跳转地址(16:32 )。

现在我尝试以这种方式对其进行编码:

mov dword[ds:jumpaddress_offset],eax
; or just dword[jumpaddress_offset],eax
mov word[ds:jumpaddress_sel],0x10;
; or just mov word[ds:jumpaddress_sel],0x10;
jmp dword far [dword ds:jumpaddress];
...
jumpaddress:
jumpaddress_sel dw 0
jumpaddress_offset dd 0
Run Code Online (Sandbox Code Playgroud)

它组装成功,但当我尝试运行它时,处理器出现一般保护故障并重新启动。我不知道发生了什么事。

我假设编码是这样的:

(例如我想使用间接跳转跳转到0x10:0x8010)

dw 0x10
dd 0x8010
Run Code Online (Sandbox Code Playgroud)

这可能有什么问题吗?难道48位内存值应该以小端编码吗?并且应该这样编码吗?

;0010 0000 8010
dd 0x10,0x80,0,0,0x10,0
Run Code Online (Sandbox Code Playgroud)

我还没有尝试做最后一项。

x86 assembly osdev

4
推荐指数
1
解决办法
3097
查看次数

MinGW 的 ld 无法对非 PE 输出文件执行 PE 操作

我知道还有其他一些类似的问题,无论是否是 StackOverflow。我为此研究了很多,但仍然没有找到单一的解决方案。我正在做一个操作系统作为一个副项目。我一直在做汇编,但现在我想加入 C 代码。为了测试,我制作了这个汇编代码文件(称为 test.asm):

[BITS 32]

GLOBAL _a

SECTION .text

_a:
    jmp $
Run Code Online (Sandbox Code Playgroud)

然后我制作了这个 C 文件(称为 main.c):

extern void a(void);
int main(void)
{
    a();
}
Run Code Online (Sandbox Code Playgroud)

为了链接,我使用了这个文件(称为 make.bat):

"C:\minGW\bin\gcc.exe"  -ffreestanding -c -o c.o main.c
nasm -f coff -o asm.o test.asm
"C:\minGW\bin\ld.exe" -Ttext 0x100000 --oformat binary -o out.bin c.o asm.o

pause
Run Code Online (Sandbox Code Playgroud)

我一直在研究多年,但我仍在努力寻找答案。我希望这不会被标记为重复。我承认存在类似的问题,但都有不同的答案,没有一个对我有用。

问题:我做错了什么?

assembly gcc mingw nasm osdev

4
推荐指数
1
解决办法
2895
查看次数

我怎样才能在我的MBR中重新定位代码?

我正在尝试编写一个非常简单的MBR来开始学习如何编写MBR /内核.这是我到目前为止(从其他MBR的部分创建).我从使用nasm然后使用ld到链接的二进制文件与仅使用nasm两者有点不同,但这似乎不是问题.

我刚开始,jmp 0:continue但似乎跳转到0000:7c22(或001d单独使用nasm ...我相信我没有指定它开始于7c00)但我希望跳转到:7a22:7a1d重新定位代码的地址.我尝试使用just jmp continue,然后在下面看到未注释,将堆栈指针添加到continue指针,推送它并返回.当我读到第一个扇区时,我得到的只是一个闪烁的光标.任何帮助表示赞赏.

                            ; nasm+ld       nasm            comment
global _start
_start:
    xor    cx, cx           ; 6631c9        31c9            Set segment registers to zero
    mov    es, cx           ; 8ec1          8ec1
    mov    ds, cx           ; 8ed9          8ed9
    mov    ss, cx           ; 8ed1          8ed1
    mov    sp, 0x7A00       ; 66bc007a      bc007a          Stack
    mov    di, sp           ; 6689e7        89e7            Bottom of relocation point
    mov    esi, _start      ; be007c0000    66be00000000
    cld …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm osdev bootloader

4
推荐指数
1
解决办法
671
查看次数

BIOS磁盘 - 将扇区读入内存(int 0x13,ah = 0x02)阻塞

我正在编写MBR并使用QEMU进行测试.

当将读取扇区用于内存(int 0x13, ah=0x02)时,该int指令似乎阻止了我的程序的执行,并且它继续挂起.我已经用各种打印语句对此进行了测试,以确认这是特定的指令阻塞.

什么可以使中断阻止?我认为这只能通过cli指令完成,即使这样也不会阻止int指令.


对于上下文,这是导致阻塞中断的代码read_sectors_16:

        [bits 16]        
        [ORG 0x7C00]
        jmp 0x000:start_16      ; ensure cs == 0x0000

        reset_failure_str db 'error: boot disk reset', 13, 10, 0
        read_failure_str db 'error: boot disk read', 13, 10, 0
        boot_segaddr dw 0x7E00

        read_attempt_str db 'read attempt', 13, 10, 0
        end_read_attempt_str db 'end read attempt', 13, 10, 0

start_16:
        ;; Initialize segment registers
        mov ax, cs
        mov ds, ax
        mov es, …
Run Code Online (Sandbox Code Playgroud)

x86 mbr qemu osdev bootloader

4
推荐指数
1
解决办法
882
查看次数

x86 保护模式下的键盘中断导致处理器错误

我正在开发一个简单的内核,并且一直在尝试实现一个键盘中断处理程序来摆脱端口轮询。我一直在-kernel模式下使用 QEMU (为了减少编译时间,因为使用生成 isogrub-mkrescue需要相当长的时间)并且它工作得很好,但是当我想切换到-cdrom模式时它突然开始崩溃。我不知道为什么。

最终我意识到,当它从 ISO 引导时,它还会在引导内核本身之前运行 GRUB 引导加载程序。我发现 GRUB 可能会将处理器切换到保护模式,这会导致问题

问题:通常我会简单地初始化中断处理程序,每当我按下一个键时,它就会被处理。但是,当我使用 iso 运行内核并按下一个键时,虚拟机就崩溃了。这发生在 qemu 和 VMWare 中,所以我认为我的中断一定有问题。

请记住,只要我不使用 GRUB,代码就可以正常工作。 interrupts_init()(见下文)是main()内核函数中调用的第一件事。

本质上的问题是:有没有办法让它在保护模式下工作?.

我的内核的完整副本可以在我的GitHub 存储库中找到。一些相关文件:

lowlevel.asm

section .text

global keyboard_handler_int
global load_idt

extern keyboard_handler

keyboard_handler_int:
    pushad
    cld
    call keyboard_handler
    popad
    iretd

load_idt:
    mov edx, [esp + 4]
    lidt [edx]
    sti
    ret
Run Code Online (Sandbox Code Playgroud)

interrupts.c

#include <assembly.h> // defines inb() and outb()

#define IDT_SIZE 256
#define …
Run Code Online (Sandbox Code Playgroud)

c x86 interrupt osdev multiboot

4
推荐指数
1
解决办法
982
查看次数

如何告诉 qemu 将 ram 复制到文件中

我正在制作一个操作系统,并使用 Qemu 对其进行调试。我想要一种方法来读取一些指令末尾的内存的一些大块。怎么做?可以对 Qemu 说将 ram 复制到文件中吗?如果不是我能做什么?

qemu osdev

4
推荐指数
1
解决办法
9742
查看次数

如何加载IDT?

我正在写自己的小操作系统。我已经完成启动,进入保护模式,一些文本打印以及与qemu的串行通信。我已经尝试添加中断两天了。我到处都在寻找,包括其他系统资源。不,我下面没有代码,qemu(我不知道为什么)关闭了。我包括geust errorsqemu。

这是我的主文件 kernel.cpp

__asm__ (".pushsection .text.start\r\n" \
          "jmp main\r\n" \
          ".popsection\r\n");

#include &lt;stdbool.h>
#include "utils/debug.h"
#include "drivers/display.h"
#include "drivers/serial.h"
#include "drivers/keyboard.h"
#include "drivers/pic.h"
#include "interrupt/interrupt.h"


void initDrivers(){
    serial::init();
    pic::init();
    interrupt::init();
    interrupt::enable();
    terminal_initialize();
}

int main() {
    initDrivers();
    terminal_setcolor(VGA_COLOR_WHITE);
    terminal_writestring("Hello!");

    debug::println("after println");

    bool alive = true;
    while(alive) {

    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

PIC驱动程序pic.cpppic.h

#include "pic.h"
#include &lt;stddef.h>
#include &lt;stdint.h>
#include "IO.h"
#include "../utils/debug.h"
/*
* IMR - Interrupt Mask Register
* IRR - Interrupt Request …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly osdev interrupt-handling

4
推荐指数
1
解决办法
375
查看次数

是什么原因导致“x.asm:(.text+0xd): 对‘y’的未定义引用”?

我已经很长一段时间没有使用 C 和汇编语言进行编程了(大约 2 年)。现在我决定重新开始,但我想做一些更复杂的事情。我考虑过创建一个简单的内核。现在我在网上找到了这个源代码:

启动.asm:

global loader
extern kernel_main
MAGIC equ 0xbad
FLAGS equ 0x3
CHECKSUM equ -(MAGIC+FLAGS)

section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM

loader:
call kernel_main
cli

quit:
hlt
jmp quit
Run Code Online (Sandbox Code Playgroud)

内核.c:

void print(char *text) {
    char *memory = (char*)0xb8000;
    while(*text) {
        *memory++ = *text++;
        *memory++ = 0x3;
    }
}

void kernel_main() {
    print("My cat sometimes smells like cafe. I love it.");
}
Run Code Online (Sandbox Code Playgroud)

链接器.ld:

ENTRY(loader)
SECTIONS {
      . = 0x100000;
      .text : { *(.text) …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc nasm osdev

4
推荐指数
1
解决办法
1336
查看次数

Intel x86 - 中断服务例程责任

我没有真正意义上的问题,但我会尽力澄清内容问题。假设我们有一个微内核(PC Intel x86;32 位保护模式),具有针对每个 CPU 异常工作的中断描述符表 (IDT)中断服务例程 (ISR)。ISR 被成功调用,比如在出现Division by Zero异常的情况下。

global ir0
extern isr_handler

isr0:

    cli
    push 0x00   ; Dummy error code
    push %1     ; Interrupt number

    jmp isr_exc_handler

isr_exc_handler:

; Save the current processor state

    pusha

    mov ax, ds
    push eax

    mov ax, 0x10 ; Load kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    ; Push current stack pointer

    mov eax, esp
    push eax …
Run Code Online (Sandbox Code Playgroud)

x86 assembly intel interrupt osdev

4
推荐指数
1
解决办法
1183
查看次数

MSI-X 如何触发中断处理程序?是否需要轮询所选的内存地址?

我有一个使用 UEFI 启动的小内核。我正在使用 QEMU 进行虚拟化。我想编写一个 xHCI 驱动程序来支持我的内核中的 USB 键盘。我很难找到简洁明了的信息。我在我的内核中“发现”了 xHCI。我有一个指向其 PCI 配置空间的指针。它支持 MSI-X。我想使用 MSI-X,但我无法理解它如何与 xHCI 和 USB 配合使用。

我的问题是,通常 osdev.org 提供的信息非常丰富,并且具有我需要实现某些功能的基础。就MSI-X而言,情况似乎并非如此。我很难将 osdev.org 上的所有信息与 MSI-X 功能联系起来。

基本上,我找到 MSI-X 表,然后在那里设置一些地址,告诉 xHCI PCI 设备写入该地址以触发中断。但是中断处理程序会在某个时刻被调用吗?我是否需要轮询该地址以确定是否发生中断?我本以为 MSI-X 表中的矢量控制字段可以让我设置中断矢量,但所有位都被保留。

编辑

我发现以下 stackoverflow 问答部分回答了我的问题:Question about Message Signaled Interrupts (MSI) on x86 LAPIC system

所以基本上,数据寄存器的低字节包含要触发的向量,消息地址寄存器包含要触发的 LAPIC id。我还有一些问题。

  1. 为什么“消息地址寄存器包含固定顶部0xFEE”。

  2. 消息地址寄存器中的 RH、DM 和 XX 位是什么?

  3. 这如何与 LAPIC 配合使用?基本上,它是如何触发 LAPIC 中的中断的。这是 PCI 设备的一个特殊功能,允许它们在 LAPIC 中触发中断。或者只是 PCI 设备向 LAPIC 的内存映射寄存器写入一些触发中断的特定数据。因为通常 LAPIC 是从内核内部访问的,每个 LAPIC 的地址都相同。是来自 CPU 外部的某种处理器间中断吗?

x86 interrupt osdev apic pci

4
推荐指数
1
解决办法
2331
查看次数

标签 统计

osdev ×10

x86 ×8

assembly ×6

interrupt ×3

nasm ×3

bootloader ×2

c ×2

gcc ×2

qemu ×2

apic ×1

intel ×1

interrupt-handling ×1

mbr ×1

mingw ×1

multiboot ×1

pci ×1