标签: osdev

2
推荐指数
3
解决办法
2万
查看次数

远跳到保护模式后的GPF

在使用GRUB作为引导加载程序进行了数周的工作后,我决定自己动手做,以便我了解它们的工作原理。我在互联网上找到了Brokenthorn的教程(当前在http://www.brokenthorn.com/Resources/OSDev9.html上)。当我尝试切换到保护模式时,cpu硬件会在跳远后重置。我正在运行bochs v。2.6。

这是我的第二阶段引导程序(几乎是本教程的副本,因为我认为它可以解决我的问题-不会)

    bits    16

; Remember the memory map-- 0x500 through 0x7bff is unused above the BIOS data area.
; We are loaded at 0x500 (0x50:0)

org 0x50:0x0

jmp main                ; go to start

;*******************************************************
;   Preprocessor directives
;*******************************************************

%include "Gdt.inc"          ; Gdt routines

;*******************************************************
;   Data Section
;*******************************************************


;*******************************************************
;   STAGE 2 ENTRY POINT
;
;       -Store BIOS information
;       -Load Kernel
;       -Install GDT; go into protected mode (pmode)
;       -Jump to Stage 3
;******************************************************* …
Run Code Online (Sandbox Code Playgroud)

x86 assembly protected-mode osdev bochs

2
推荐指数
1
解决办法
1135
查看次数

端口GNU C库到最小的爱好操作系统

所以我有一个最小的操作系统没有做太多.有一个引导加载程序,它以32位保护模式加载基本的C内核.如何在C库中移植以便我可以使用类似的东西printf?我正在寻找使用GNU C库.在任何地方都有教程吗?

c assembly operating-system osdev hobby-os

2
推荐指数
2
解决办法
2138
查看次数

INT 0x13/AH = 0x02适用于软盘映像,但不能在闪存驱动器上刻录

我试图在x86程序集中创建一个简单的命令系统.命令系统是在0x1000:0000中加载的第二个阶段.要查看我的引导加载程序,请单击此stackoverflow问题.

这是第二阶段命令系统:



[BITS 16]
[ORG 0x0000]      

mov ax, cs
mov ds, ax   
xor cx, cx  
mov bx, welcome_msg
call str_prt
call new_line
mov bx, creator_msg
call str_prt
call new_line
mov bx, boot_msg
call str_prt
call new_line
mov bx, [buffer]

call new_line

mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
mov al, '>'
int 0x10

loop:
in al, 64h  
test al, 1    
je loop
xor ah, ah
int 0x16
call key_scan
jmp loop …
Run Code Online (Sandbox Code Playgroud)

assembly nasm osdev bochs x86-16

2
推荐指数
1
解决办法
312
查看次数

在长模式下更改GDT并更新CS

我正在编写一个简单的自制64位OS,并通过UEFI进行引导。这意味着当我的代码开始执行时,它已经处于long模式,并且启用了分页。

现在,退出UEFI引导服务后,我想用我自己的UEFI构建所有控制结构。

成功更改CR3(分页结构)的内容后,我使用成功加载了新的GDT lgdt

问题在于,现在,要正确使用此新GDT,我需要将新值移至CS中。在网上,我找到了许多有关如何从32位切换到64位的方法的教程,但是从长模式到长模式几乎一无所获。

我想我应该跳个很远的距离,但是我没有用以下代码(AT&T语法)来做到这一点:

mov %rax, %cr3   # load paging structures (it works)
lgdt 6(%rcx)     # load gdt (it works)
mov $100, %rsp   # update stack pointer (it works)

# now what I tried unsuccessfully:
pushw $8         # new code segment selector
pushq fun        # function to execute next
retfq            # far return (pops address and code segment)
Run Code Online (Sandbox Code Playgroud)

没有适当的IDT,此代码使处的错误倍增retfq

编辑:我检查了我的分页结构,并且我很确定它们不是问题的原因。实际上,在没有最后三个指令的情况下,代码可以正常运行。问题是我需要一种更新CS的方法,在我的代码中仍然引用UEFI构建的旧段。是retfq正确的方法吗?还是我应该使用其他哪条指令?

提前致谢。

64-bit assembly x86-64 osdev gdt

2
推荐指数
1
解决办法
831
查看次数

编写一个简单的引导程序,读取用户名

我正在尝试学习操作系统的工作方式。这是我要解决的一个容易的任务:编写一个简单的引导程序,提示用户输入他的名字并打印欢迎消息,例如“ hello,>> name <<”-之后,它什么也不做。

如果minix 3qemu此相关,我正在与一起运行。我只是将asm文件dd及其前512个字节编译为/dev/c0d0(的虚拟硬盘minix)。

我可以打印消息并打印用户输入的内容。但是,此后我没有设法打印用户名。

这是我的汇编代码:

[bits 16]
[org 0x7c00]

mov si, HelloString
call print_string
mov di, name
call read_name
mov si, name
call print_string

read_name:
    read_char:
        mov ah, 0h  ; read character from keyboard
        mov [di], ah    ; save it in the buffer
        inc di      ; next char
        int 0x16    ; store it in AL
        cmp ah, 0x0d    ; check for enter
        je stop_reading 
        mov …
Run Code Online (Sandbox Code Playgroud)

x86 assembly osdev minix bootloader

2
推荐指数
1
解决办法
139
查看次数

如何在BIOS级汇编中打印换行符?

我正在尝试使用NASM Assembler自己编写一个bootloader.我正在尝试打印两行文本,等待按键,如果按下的键是'r'则重新启动,如果按下的键是'b'则继续启动.但是,这不是我的问题的主题(我将在稍后实现这些函数,因此nop目前代码中的指令).相反,我想问一下为什么我的换行符0xA以如此奇怪的方式打印?我已经在我的TODO中完成了所有三个项目,但我认为这很重要,因为加载器一定不会看起来很糟糕.

输出

这是我的代码:

BITS 16     ; tell nasm we're working in 16 bit real mode

start:          ; entry symbol for the os          

        mov ax, 0x07C0          ; 4 kilobyte stack space set up
        add ax, 288             ; (4096+512) / 16 bytes per paragraph
        mov ss, ax              
        mov sp, 4096

        mov ax, 0x07C0          ; set data segment to where we've loaded
        mov ds, ax

        mov si, text_string     ; put our string position into SI
        call write_string       ; call …
Run Code Online (Sandbox Code Playgroud)

x86 assembly interrupt bios osdev

2
推荐指数
1
解决办法
1439
查看次数

printf()函数的实现

我正在制作一个业余爱好者内核,并且正在尝试实现一个printf()功能。

这是我的实现:

void kprint(uint8_t *format, ...) {
  va_list ap;
  va_start(ap, format);

  uint8_t *ptr;

  for (ptr = format; *ptr != '\0'; ptr++) {
    if (*ptr == '%') {
      ptr++;
      switch (*ptr) {
        case 's':
          puts(va_arg(ap, uint8_t *), 0x0F, xPos, yPos);
          break;
      }
    } else {
      puts(ptr, 0x0F, xPos, yPos);
      ptr++;
    }
  }

  va_end(ap);
}
Run Code Online (Sandbox Code Playgroud)

当我要打印“ Hello World!”时 使用此功能,它返回我:

"Hello %sllo %so %sWorld"
Run Code Online (Sandbox Code Playgroud)

这是函数调用:

kprint("Hello %s", "World");
Run Code Online (Sandbox Code Playgroud)

c operating-system osdev

2
推荐指数
1
解决办法
345
查看次数

Gnu Make&gt; $ *和$ *的含义

我偶然发现了一个看起来很奇怪的Makefile,我听不懂

这是那个Makefile

AS=as -32 -Iinclude
LD=ld -m elf_i386
CC=gcc -m32 -fno-pie -fno-stack-protector
CPP=gcc -E -nostdinc -Iinclude
CFLAGS=-W -nostdlib -Wno-long-long -I include -fomit-frame-pointer

.s.o:
    ${AS} -a $< -o $*.o >$*.map

all: boot setup

boot: boot.o
    ${LD} --oformat binary -N -e start -Ttext 0x0000 -o boot $<

setup: setup.o
    ${LD} --oformat binary -N -e start -Ttext 0x0000 -o setup $<

clean:
    rm -f boot setup *.o *.map
Run Code Online (Sandbox Code Playgroud)

我不明白的部分是

.s.o:
    ${AS} -a $< -o $*.o >$*.map
Run Code Online (Sandbox Code Playgroud)

.s.o在这种情况下的意义是什么,以及该$*.o >$*.map尝试做什么。

c x86 makefile gnu-make osdev

2
推荐指数
1
解决办法
70
查看次数

现代计算机是以实模式还是虚拟实模式启动?

因此,我阅读了有关处理器模式的信息,然后知道虚拟实模式允许实模式应用程序(例如DOS应用程序,例如BIOS程序)在受保护模式的操作系统中运行。

因此,我的问题是当前系统是否首先以实模式加载,然后再提供更多保护或直接将其保护为虚拟实模式,因为否则,我们必须创建一个从实模式开始的multiboot引导加载程序,然后跳转到虚拟模式。虚拟实模式难道不容易吗?

x86 kernel osdev multiboot bootloader

2
推荐指数
1
解决办法
63
查看次数