编写操作系统(Windows)或启动CD的语言是什么?
在使用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) 所以我有一个最小的操作系统没有做太多.有一个引导加载程序,它以32位保护模式加载基本的C内核.如何在C库中移植以便我可以使用类似的东西printf?我正在寻找使用GNU C库.在任何地方都有教程吗?
我试图在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) 我正在编写一个简单的自制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正确的方法吗?还是我应该使用其他哪条指令?
提前致谢。
我正在尝试学习操作系统的工作方式。这是我要解决的一个容易的任务:编写一个简单的引导程序,提示用户输入他的名字并打印欢迎消息,例如“ hello,>> name <<”-之后,它什么也不做。
如果minix 3与qemu此相关,我正在与一起运行。我只是将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) 我正在尝试使用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) 我正在制作一个业余爱好者内核,并且正在尝试实现一个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) 我偶然发现了一个看起来很奇怪的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尝试做什么。
因此,我阅读了有关处理器模式的信息,然后知道虚拟实模式允许实模式应用程序(例如DOS应用程序,例如BIOS程序)在受保护模式的操作系统中运行。
因此,我的问题是当前系统是否首先以实模式加载,然后再提供更多保护或直接将其保护为虚拟实模式,因为否则,我们必须创建一个从实模式开始的multiboot引导加载程序,然后跳转到虚拟模式。虚拟实模式难道不容易吗?