Так что я создаю простую ОС, и я запускаю ошибку, указанную выше при вызове кода ядра из загрузочного сектора. Я потратил несколько дней на борьбу и все еще в тупике.load_seg_reg (ES, 0xfffc): недопустимый сегмент при попытке запустить код ядра из загрузочного сектора
Код невозможен при вызове KERNEL_OFFSET. Я знаю, что он терпит неудачу, потому что я пытаюсь перейти к недействительному сегменту, но я не могу понять, как и где. Я также заметил, что на самом деле это не чтение диска. Мой код load_kernel запрашивает 10 секторов для чтения, но только, казалось, был прочитан. Программа может войти в защищенный режим и в состоянии загружать то, что мне нужно для загрузки с диска, несмотря на то, что поведение загрузки является странным.
Im также показывает мой make-файл, потому что я подозреваю, что, возможно, я не связал вещи должным образом. Я запускаю OSX btw так idk, если команды shell im im правильные.
Я был в этом несколько дней, любая помощь будет оценена по достоинству. Благодаря
boot_sector
;
; A simple boot sector program.
; BIOS stores the boot drive in DL
;
[org 0x7c00]
[bits 16]
mov [BOOT_DRIVE], dl ; Move boot drive info to memory.
; Setup stack to a position we know is free.
mov bp, 0x9000
mov sp, bp
; Output a nice message.
mov dx, REAL_MODE_MSG
call PrintString16
; Load the kernel.
mov dx, [BOOT_DRIVE]
call LoadKernel
mov dx, LOADED_KERNEL_MSG
call PrintString16
; Switch to protected mode.
; Note, we never break from Protected mode.
call SwitchToProtectedMode
jmp $
; Including some useful routines.
%include "string_utils_16.s"
%include "gdt.s"
%include "string_utils.s"
%include "load_kernel.s"
%include "switch_to_pm.s"
[bits 32]
BeginProtectedMode:
mov edx, PROT_MODE_MSG
call PrintString
; This call should, theoritecally, run the instructions we just loaded.
; AKA, the C code.
; KERNEL_OFFSET is defined in load_kernel.s
call KERNEL_OFFSET
jmp $
BOOT_DRIVE db 0
LOADED_KERNEL_MSG db "Loaded kernel with no errors!", 0
REAL_MODE_MSG db "Welcome! Started in 16-bit Real Mode!", 0
PROT_MODE_MSG db "Now running in 32-bit Protected Mode", 0
times 510 -($ - $$) db 0
dw 0xaa55
switch_to_pm
[bits 16]
SwitchToProtectedMode:
cli
lgdt [gdt_descriptor]
; To actually switch to 32 bit mode, set LSB of cr0 to 1
; Can't touch the cr0 register directly so gotta do it the hard way.
mov eax, cr0
or eax, 0x1
mov cr0, eax
; Technically, after that last move instruction, we're in 32 bit mode BUT
; the CPU may have been doing work in between all this, since, the CPU can do
; certain things in parallel if its got different circuitry to do those things,
; which it probably does. Few of the things the CPU could do in parallel is
; fetch, decode and execute. We dont want the CPU to be fetching the next
; instruction while our stuff is happening (those next things that will be
; fetched probably wont work in 32 bit mode) and we want it to finish whatever
; it is currently executing. so, we're going to do a far jump to
; somewhere so that the CPU cannot make any extrapolations on what to fetch next
; and anything being executed can finish executing.
jmp CODE_SEGMENT:init_pm
[bits 32]
; Initialize segment registers. In 32 bit mode, they all point to an entry in
; the GDT.
init_pm:
mov ax, DATA_SEGMENT
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Define the stack somewhere we're sure has free memory.
mov ebp, 0x90000
mov esp, ebp
call BeginProtectedMode
load_kernel
[bits 16]
KERNEL_OFFSET equ 0x1000
; Will load the kernel into memory.
; dl will contain the boot drive.
LoadKernel:
push dx ; Save the boot drive info
mov dx, LOAD_KERNEL_MSG
call PrintString16
pop dx ; Get it back. DL contains boot drive.
mov bx, KERNEL_OFFSET ; Where we want kernel to be loaded to.
mov dh, 10 ; How many sectors to load
; dl is also a parameter but we already have it.
call LoadFromDisk
ret
%include "disk_load.s"
LOAD_KERNEL_MSG db "Loading kernel...", 0
ядро
// Simple kernel.
#include "screen.h"
void main() {
print("It worked!");
// char* video = (char*) 0xb800;
// video[0] = 'S';
}
Makefile
INCLUDE = include/
# List is expanded when used not when declared.
OBJECTS = $(wildcard temp/*.o)
# -------------------- Build the os_image
os_image.bin : temp/boot_sect.bin temp/kernel.bin
cat temp/boot_sect.bin temp/kernel.bin > os_image.bin
# -------------------- Build the boot sector image
temp/boot_sect.bin : boot/boot_sect.s
nasm boot/boot_sect.s -i boot/ -f bin -o temp/boot_sect.bin
# -------------------- Build kernel image
temp/kernel.bin : kernel.o kernel_entry.o
clang -ffreestanding -m32 kernel_entry.o $(OBJECTS) kernel.o -o temp/kernel.bin
# -------------------- Build object files
kernel.o : kernel/kernel.c temp/screen.o
clang -ffreestanding -m32 -c -I $(INCLUDE) kernel/kernel.c -o kernel.o
kernel_entry.o : kernel/kernel_entry.s
nasm -f macho -o kernel_entry.o kernel/kernel_entry.s
# -------------------- Build driver objects
temp/screen.o : include/screen.h drivers/screen.c temp/low_level.o
clang -ffreestanding -m32 -c -I $(INCLUDE) drivers/screen.c -o temp/screen.o
temp/low_level.o : include/low_level.h kernel/low_level.c
clang -ffreestanding -m32 -c -I $(INCLUDE) kernel/low_level.c -o temp/low_level.o
clean :
rm *.o
rm ./temp/*.o
rm ./temp/*.bin
rm *.bin
отношения Bochs консоль дамп
00014040953i[BIOS ] Booting from 0000:7c00
00014479618i[FDD ] partial read() on floppy image returns 172/512
00014561257i[MEM0 ] allocate_block: block=0x10 used 0x3 of 0x20
00014561312e[CPU0 ] load_seg_reg(ES, 0xfffc): invalid segment
00014561312e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00014561312e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00014561312i[CPU0 ] CPU is in protected mode (active)
00014561312i[CPU0 ] CS.mode = 32 bit
00014561312i[CPU0 ] SS.mode = 32 bit
00014561312i[CPU0 ] EFER = 0x00000000
00014561312i[CPU0 ] | EAX=0008fffc EBX=00001000 ECX=00090003 EDX=ffff0136
00014561312i[CPU0 ] | ESP=0008fff8 EBP=00090003 ESI=000e0000 EDI=00007d2d
00014561312i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf AF pf CF
00014561312i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014561312i[CPU0 ] | CS:0008(0001| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | DS:0010(0002| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | SS:0010(0002| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | ES:0010(0002| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | FS:0010(0002| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | GS:0010(0002| 0| 0) 00000000 ffffffff 1 1
00014561312i[CPU0 ] | EIP=0000107c (0000107c)
00014561312i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00014561312i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[14561312] [0x000000000000107c] 0008:000000000000107c (unk. ctxt): pop es ; 07
00014561312e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting