标签: osdev

在保护模式下重启

在 x86 实模式下重启非常简单。您可以使用 BIOS 或:

jmp 0xFFFF:0000
Run Code Online (Sandbox Code Playgroud)

但是在保护模式下应该如何重新启动?

x86 osdev

5
推荐指数
1
解决办法
868
查看次数

Rustc/LLVM为aarch64生成错误代码,opt-level = 0

我有两个文件组装/编译/链接到minimalistic内核.

的start.s:

    .set CPACR_EL1_FPEN, 0b11 << 20

    .set BOOT_STACK_SIZE, 8 * 1024

    .global __boot_stack
    .global __start
    .global __halt

    .bss
    .align 16
__boot_stack:
    .fill BOOT_STACK_SIZE

    .text
__start:
    /* disable FP and SIMD traps */
    mov x0, #CPACR_EL1_FPEN
    msr cpacr_el1, x0

    /* set stack */
    adr x0, __boot_stack
    add sp, x0, #BOOT_STACK_SIZE

    /* call the Rust entry point */
    bl __boot

__halt:
    /* halt CPU */
    wfi
    b __halt
Run Code Online (Sandbox Code Playgroud)

boot.rs:

#[no_mangle]
pub extern fn __boot() {
    unsafe {
        let ptr = 0x9000000 …
Run Code Online (Sandbox Code Playgroud)

qemu osdev rust arm64

5
推荐指数
1
解决办法
256
查看次数

Intel GMA950 私有缓冲区中字节的含义,在 VGA 文本模式下

在文本屏幕(模式 3,80x25)上工作时,位于 B800h 的常用视频缓冲区和接近 4GB 地址空间末尾的线性帧缓冲区 (LFB) 都处于活动状态。我发现对于显示器上的每个字符单元格,LFB 使用8 bytes。第一个字节 (a) 表示 ASCII,第二个字节 (b) 表示属性。

在一个空的显示页面上,这 8 个字节看起来像:

20h,07h,00h,00h,00h,00h,00h,00h
(a) (b) (c) (d) (e) (f) (g) (h)    
Run Code Online (Sandbox Code Playgroud)

有谁知道额外的 6 个字节是做什么用的?我观察到只有这些神秘字节的第一个 (c) 和第五个 (g) 实际上刷新了对我来说似乎是随机的值。其他 4 个字节保持为零,但如果我将任何内容放入其中,即使设置了视频模式,它也能幸存下来。

assembly intel osdev vga video-memory

5
推荐指数
1
解决办法
226
查看次数

跳转到 64 位长模式时出现三重错误

以下从 32 位保护模式(启用 A20)转换到 64 位长模式的代码似乎给我带来了问题。我将 1GiB 页面从 0x00000000 恒等映射到 0x3fffffff;启用 PAE;启用 EFER MSR 中的长模式位;安装 GDT;启用分页;然后对我的 64 位入口点进行模拟 FAR JMP:

lea eax, [PML4]
mov cr3, eax

mov eax, cr4
or eax, 100000b
mov cr4, eax

mov ecx, 0xc0000080
rdmsr
or eax, 100000000b
wrmsr

mov eax, cr0
mov ebx, 0x1
shl ebx, 31
or eax, ebx
mov cr0, eax

call gdt64_install
push 8
push longmode
retf ;<===================== faults here
Run Code Online (Sandbox Code Playgroud)

当执行指令时,程序在BOCHSRETF中出现三次错误,但似乎没有返回任何错误。如果我info tab在这次跳转之前输入,我会得到:

0x00000000-0x3fffffff -> 0x000000000000-0x00003fffffff
Run Code Online (Sandbox Code Playgroud)

在我看来,分页正在工作。这是sreg …

paging x86 assembly x86-64 osdev

5
推荐指数
1
解决办法
693
查看次数

是否可以在不映射内核的情况下将进程映射到内存中?

OSDev维基说:

在每个用户进程中映射内核是传统的并且通常很好

那为什么呢?这个过程不能单独映射到内存吗?映射内核有什么好处,这不会浪费空间吗?

此外,是否可以从用户空间访问内核空间,为什么我会这样做?

x86 assembly memory-management osdev linux-kernel

5
推荐指数
1
解决办法
707
查看次数

QEMU/KVM 缺少 CPU 功能标志(kvm 没有通过?)

我正在尝试使用 kvm 在 qemu 中进行一些操作系统开发。我使用的是 x86-64,我的主机 CPU 是 Intel i7-6700K (Skylake)。问题是当我使用-cpu host.

我特别在寻找“est”(增强型 SpeedStep)。如果我lscpu在主机中运行,它会显示许多 cpu 标志,包括 est。如果查看我的操作系统中的 cpuid 结果,我会看到大约一半丢失了,包括 est)。

我想我明白 kvm 不会自动通过所有 cpu 标志,但是我怎么能告诉它通过特定标志(或者可能只是所有标志)?

x86-64 kvm qemu osdev cpuid

5
推荐指数
1
解决办法
346
查看次数

无法从引导加载程序(NASM + GCC 工具链)调用实模式 C 函数

我正在尝试编写自己的操作系统内核,但在引导加载程序和(即将成为)我的内核(用 C 编写的)之间正确连接时遇到了一些问题。

我有以下代码...

src/bootloader.asm

; Allows our code to be run in real mode.
BITS 16
extern kmain

section .text
global _start
_start:
        jmp Start

; Moves the cursor to row dl, col dh.
MoveCursor:
    mov ah, 2
    mov bh, 0
    int 10h
    ret

; Prints the character in al to the screen.
PrintChar:
    mov ah, 10
    mov bh, 0
    mov cx, 1
    int 10h
    ret

; Set cursor position to 0, 0.
ResetCursor:
    mov dh, 0
    mov dl, …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc osdev bootloader

5
推荐指数
1
解决办法
465
查看次数

GDB-remote + qemu 报告静态 C 变量的意外内存地址

基于os-dev 教程,使用 GDB 远程调试 Qemu 中运行的代码。
我的版本在这里。该问题仅在 qemu 中远程调试代码时发生,而不是在正常操作系统下构建普通可执行文件以直接在 GDB 中运行时发生。

代码如下所示:

#define BUFSIZE 255
static char buf[BUFSIZE];

void foo() {
  // Making sure it's all zero.
  for (int i = 0; i < BUFSIZE; i++) buf[i] = 0;

  // Setting first char:
  buf[0] = 'a';

  // >> insert breakpoint right after setting the char <<

  // Prints 'a'.
  printf("%s", buf);
}
Run Code Online (Sandbox Code Playgroud)

如果我在标记的位置放置一个断点并打印缓冲区,p buf我会从随机位置获得随机值,似乎来自我的代码部分。如果我得到地址,p &buf我会得到一些看起来不正确的东西,有两件事:

  1. 如果我执行 achar* p_buf = buf并用 …

c x86 gdb qemu osdev

5
推荐指数
1
解决办法
207
查看次数

使用时间和对齐 NASM 指令在复位向量指向的地址中放置一条指令

我一直在考虑以下汇编代码(NASM IA-32):

ORG 0xFF000 ; This is (1MB - 4KB) 0x100000 - 0x1000=0xFF000.
USE16 ;produce 16bit code
code_size EQU (end -init_16) ; calculates code length

times (4096-code_size) db 0x90 ; fills the rest of the memory with NOP's
init_16:
    cli ;disables interrupts (not really necessary, just an example)
    jmp init_16 ;infinite loop
align 16
end :
Run Code Online (Sandbox Code Playgroud)

这只是一个例子。这个想法是我们在实模式下有一个 IA-32 处理器。在内存的顶部 4 KB 上,我们有一个 NVRAM(非易失性 RAM)。复位向量指向 0xFFF0,因此代码尝试将cli指令放置在 0xFFFF0 地址中,而与放置在init16标签和align 16指令之间的指令数量无关(限制为 16 字节,因此可以适应 1M 字节)。但我无法理解它是如何做到的。

我对align …

x86 assembly nasm osdev

5
推荐指数
1
解决办法
90
查看次数

为什么要使用“ret”而不是“call”来调用方法?

在阅读和学习开源操作系统时,我偶然发现了一种在汇编中调用“方法”的极其复杂的方法。它使用“ret”指令来调用库方法来执行以下操作:

push rbp                ; rsp[1] = rbp
mov rbp, .continue      ; save return label to rbp
xchg rbp, QWORD [rsp]   ; restore rbp and set rsp[1] to return label

push rbp ; rsp[0] = rbp
mov rbp, 0x0000700000000000 + LIB_PTR_TABLE.funcOffset ; rbp = pointer to func pointer
mov rbp, QWORD [rbp]    ; rbp = func pointer
xchg rbp, QWORD [rsp]   ; restore rbp and set rsp[0] to func pointer

; "call" library by "returning" to the address we just planted …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 osdev spectre

5
推荐指数
1
解决办法
465
查看次数

标签 统计

osdev ×10

assembly ×6

x86 ×6

qemu ×3

x86-64 ×3

arm64 ×1

bootloader ×1

c ×1

cpuid ×1

gcc ×1

gdb ×1

intel ×1

kvm ×1

linux-kernel ×1

memory-management ×1

nasm ×1

paging ×1

rust ×1

spectre ×1

vga ×1

video-memory ×1