这个问题已经解决了!!!我已经更新了引导加载程序和内核代码,以匹配已修复的代码,以便任何遇到相同问题的操作系统制造商(可能很快会在内核中添加评论)。以下是 Nate Eldredge 编写的修复代码的解释。无关,但操作系统最初称为 POVESK。结果发现已经有这样的名字,所以现在在引导加载程序代码中进行了更改。
最近在做一个操作系统,在制作GDT的时候遇到了很大的问题
内核代码(这就是我拼写内核的方式):
[org 0x8000]
[bits 16]
jmp short start
%define ENDL 0x0D, 0x0A
gdt_start:
dq 0x0000000000000000
dq 0x00CF9A000000FFFF
dq 0x00CF92000000FFFF
dq 0x00CF92000000FFFF
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
print:
push si
push ax
push bx
.loop:
lodsb
or al, al
jz .done
mov ah, 0x0E
mov bh, 0
int 0x10
jmp .loop
.done:
pop bx
pop ax
pop si
ret
start:
mov si, start_sixteen
call print
in al, 0x64
.wait_ibe:
test al, 0x02
jnz .wait_ibe
mov al, 0xD1
out 0x64, al
.wait_ibe2:
in al, 0x64
test al, 0x02
jnz .wait_ibe2
mov al, 0xDF
out 0x60, al
first_sixteen:
mov ah, 0x00
mov al, 0x03
int 0x10
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword 0x08:.afterstart
[bits 32]
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f
.afterstart:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov ebx, start_thirty_two
call print32
cli
hlt
jmp short start_prog
print32:
pusha
mov edx, VIDEO_MEMORY
.loop:
mov al, [ebx]
mov ah, WHITE_ON_BLACK
cmp al, 0
je .done
mov [edx], ax
add ebx, 1
add edx, 2
jmp .loop
.done:
popa
ret
start_prog:
mov al, 2
mov eax, 1004
mov [Xval], eax
mov eax, 50
mov [Yval], eax
mov eax, 10
mov [Wval], eax
mov eax, 20
mov [Hval], eax
lea esi, [PySpr]
call draw_spr
.halt:
cli
hlt
draw_spr:
xor edx, edx
mov ecx, [Hval]
draw_sprite:
mov eax, [Yval]
mov ebx, 1024
mul ebx
add eax, [Xval]
mov edi, eax
push ecx
mov ecx, [Wval]
draw_pixels:
mov al, [esi]
cmp al, 5
je skip_pixel_2
stosd
jmp skip_pixel
skip_pixel_2:
inc edi
skip_pixel:
inc esi
loop draw_pixels
pop ecx
mov eax, [Yval]
inc eax
mov [Yval], eax
loop draw_sprite
ret
start_sixteen: db 'STAGE ONE START', ENDL, 0
start_thirty_two: db 'STAGE TWO START', 0
Xval dd 0
Yval dd 0
Wval dd 0
Hval dd 0
PySpr db 5,5,5,2,2,2,2,5,5,5
db 5,5,2,2,2,2,2,2,5,5
db 5,2,2,2,2,2,2,2,2,5
db 2,2,2,2,2,2,2,2,2,2
db 5,8,8,8,8,8,8,8,8,5
db 5,8,15,0,8,8,0,15,8,5
db 5,8,8,8,8,8,8,8,8,5
db 5,8,8,0,0,0,0,8,8,5
db 5,5,8,8,8,8,8,8,5,5
db 2,2,2,2,2,2,2,2,2,2
db 2,2,2,2,2,2,2,2,2,2
db 2,5,2,2,2,2,2,2,5,2
db 2,5,2,2,2,2,2,2,5,2
db 2,5,2,2,2,2,2,2,5,2
db 8,5,2,2,2,2,2,2,5,8
db 5,5,6,6,6,6,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,7,7,7,5,5,7,7,7,5
引导加载程序代码(基本上是第 3 部分的 nanobyte os 引导加载程序,但略有改动):
[org 0x7C00]
[bits 16]
%define ENDL 0x0D, 0x0A
jmp short start
nop
bdb_oem: db 'CLIPIN..'
bdb_bytes_per_sector: dw 512
bdb_sectors_per_cluster: db 1
bdb_reserved_sectors: dw 1
bdb_fat_count: db 2
bdb_dir_entries_count: dw 0E0h
bdb_total_sectors: dw 2880
bdb_media_descriptor_type: db 0F0h
bdb_sectors_per_fat: dw 9
bdb_sectors_per_track: dw 18
bdb_heads: dw 2
bdb_hidden_sectors: dd 0
bdb_large_sector_count: dd 0
ebr_drive_number: db 0
db 0
ebr_signature: db 29h
ebr_volume_id: db 12h, 34h, 56h, 78h
ebr_volume_label: db 'CLIPIN.. OS'
ebr_system_id: db 'FAT12 '
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
push es
push word .after
retf
.after:
mov [ebr_drive_number], dl
mov si, msg_loading
call puts
push es
mov ah, 08h
int 13h
jc floppy_error
pop es
and cl, 0x3F
xor ch, ch
mov [bdb_sectors_per_track], cx
inc dh
mov [bdb_heads], dh
mov ax, [bdb_sectors_per_fat]
mov bl, [bdb_fat_count]
xor bh, bh
mul bx
add ax, [bdb_reserved_sectors]
push ax
mov ax, [bdb_dir_entries_count]
shl ax, 5
xor dx, dx
div word [bdb_bytes_per_sector]
test dx, dx
jz .root_dir_after
inc ax
.root_dir_after:
mov cl, al
pop ax
mov dl, [ebr_drive_number]
mov bx, buffer
call disk_read
xor bx, bx
mov di, buffer
.search_kernal:
mov si, file_kernal_bin
mov cx, 11
push di
repe cmpsb
pop di
je .found_kernal
add di, 32
inc bx
cmp bx, [bdb_dir_entries_count]
jl .search_kernal
jmp kernal_not_found_error
.found_kernal:
mov ax, [di + 26]
mov [kernal_cluster], ax
mov ax, [bdb_reserved_sectors]
mov bx, buffer
mov cl, [bdb_sectors_per_fat]
mov dl, [ebr_drive_number]
call disk_read
mov bx, kernal_LOAD_SEGMENT
mov es, bx
mov bx, kernal_LOAD_OFFSET
.load_kernal_loop:
mov ax, [kernal_cluster]
add ax, 31
mov cl, 1
mov dl, [ebr_drive_number]
call disk_read
add bx, [bdb_bytes_per_sector]
mov ax, [kernal_cluster]
mov cx, 3
mul cx
mov cx, 2
div cx
mov si, buffer
add si, ax
mov ax, [ds:si]
or dx, dx
jz .even
.odd:
shr ax, 4
jmp .next_cluster_after
.even:
and ax, 0x0FFF
.next_cluster_after:
cmp ax, 0x0FF8
jae .read_finish
mov [kernal_cluster], ax
jmp .load_kernal_loop
.read_finish:
mov dl, [ebr_drive_number]
mov ax, kernal_LOAD_SEGMENT
mov ds, ax
mov es, ax
jmp kernal_LOAD_SEGMENT:kernal_LOAD_OFFSET
jmp wait_key_and_reboot
cli
hlt
floppy_error:
mov si, msg_read_failed
call puts
jmp wait_key_and_reboot
kernal_not_found_error:
mov si, msg_kernal_not_found
call puts
jmp wait_key_and_reboot
wait_key_and_reboot:
xor ah, ah
int 16h
jmp 0FFFFh:0
.halt:
cli
hlt
puts:
push si
push ax
push bx
.loop:
lodsb
or al, al
jz .done
mov ah, 0x0E
xor bh, bh
int 0x10
jmp .loop
.done:
pop bx
pop ax
pop si
ret
lba_to_chs:
push ax
push dx
xor dx, dx
div word [bdb_sectors_per_track]
inc dx
mov cx, dx
xor dx, dx
div word [bdb_heads]
mov dh, dl
mov ch, al
shl ah, 6
or cl, ah
pop ax
mov dl, al
pop ax
ret
disk_read:
push ax
push bx
push cx
push dx
push di
push cx
call lba_to_chs
pop ax
mov ah, 02h
mov di, 3
.retry:
pusha
stc
int 13h
jnc .done
popa
call disk_reset
dec di
test di, di
jnz .retry
.fail:
jmp floppy_error
.done:
popa
pop di
pop dx
pop cx
pop bx
pop ax
ret
disk_reset:
pusha
xor ah, ah
stc
int 13h
jc floppy_error
popa
ret
msg_loading: db 'BOOT START', ENDL, 0
msg_read_failed: db 'FAIL READ DISK', ENDL, 0
msg_kernal_not_found: db 'KERNAL NOT FOUND', ENDL, 0
file_kernal_bin: db 'KERNAL BIN'
kernal_cluster: dw 0
kernal_LOAD_SEGMENT equ 0x0000
kernal_LOAD_OFFSET equ 0x8000
times 510-($-$$) db 0
dw 0AA55h
buffer:
问题出在内核代码中。我进行了一些调试,并确定这可能是由于三重错误(chatGPT 得出的结论)造成的,并且它通常发生在 jmp dword 0x08:.afterstart 中,但奇怪的是,在多次尝试修复此问题后(找到许多教程和项目并将它们修复到我的代码中),三重错误出现在许多不同的代码行中。我在这个主题上相当缺乏经验,所以我可能真的很笨,错过了一些显而易见的东西。
如果有人有解决方案请告诉我。提前谢谢!
三重失误jmp dword 0x08:.afterstart
,并已开始出现在许多其他线路中。
构建命令:
--WinCMD NASM
nasm scr/boot.asm -f bin -o build/boot.bin
nasm scr/kernal.asm -f bin -o build/kernal.bin
--WSL
dd if=/dev/zero of=v_004.img bs=512 count=2880
mkfs.fat -F 12 -n NBOS v_004.img
dd if=boot.bin of=v_004.img conv=notrunc
mcopy -i v_004.img kernal.bin ::kernal.bin
--QEMUCMD
qemu-system-x86_64 v_004.img