Added example disk, Made some minor changes to error output

This commit is contained in:
Lucia Ceionia 2023-02-07 18:52:17 -06:00
parent 0e3ae9c4e3
commit 7f0a94352d
9 changed files with 119 additions and 24 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
*.o *.o
*.bin *.bin
*.img
*.lock *.lock
*.com *.com
bx_enh_dbg.ini bx_enh_dbg.ini

View File

@ -1,5 +1,5 @@
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o tests.o kbd.o helper.o progs.o objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o tests.o kbd.o helper.o progs.o
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c CFLAGS = -target "i486-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
%.o: %.nasm %.o: %.nasm
nasm -f elf32 -o $@ $< nasm -f elf32 -o $@ $<
@ -11,7 +11,7 @@ all: $(objects)
nasm boot.nasm -o boot.bin nasm boot.nasm -o boot.bin
gcc -Tlink.ld -Wl,-M -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\ gcc -Tlink.ld -Wl,-M -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\
$(objects) $(objects)
dd bs=256 count=1 conv=notrunc if=boot.bin of=virtdisk.bin dd bs=400 count=1 conv=notrunc if=boot.bin of=virtdisk.bin
dd bs=512 seek=1 conv=notrunc if=kernel.bin of=virtdisk.bin dd bs=512 seek=1 conv=notrunc if=kernel.bin of=virtdisk.bin
virtdisk: virtdisk:
dd bs=1M count=32 if=/dev/zero of=virtdisk.bin dd bs=1M count=32 if=/dev/zero of=virtdisk.bin

View File

@ -8,6 +8,10 @@ mov es, ax
mov ax, 0x8000 mov ax, 0x8000
mov ss, ax mov ss, ax
mov sp, 0xFF00 mov sp, 0xFF00
mov ah, 0x41 ; int 13 extensions check
mov bx, 0x55AA
int 0x13
jc no_exten
mov cx, kernelreads mov cx, kernelreads
read_loop: read_loop:
xor ax, ax xor ax, ax
@ -19,6 +23,14 @@ add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
add word [addr_packet_start_block], secreadcnt add word [addr_packet_start_block], secreadcnt
loop read_loop loop read_loop
entry: entry:
mov ax,0x2403 ; A20 BIOS Support
int 0x15
jb .no_a20
cmp ah,0
jnz .no_a20
mov ax,0x2401 ; A20 BIOS Activate
int 0x15
.no_a20:
cli ; no interrupts cli ; no interrupts
xor ax,ax xor ax,ax
mov ds, ax mov ds, ax
@ -28,19 +40,50 @@ or al, 1
mov cr0, eax mov cr0, eax
jmp 08h:Pmode jmp 08h:Pmode
err: err:
mov bx, ax
mov si, string
mov cx, string_end - string
jmp print
no_exten:
mov bx, ax
mov si, no_exten_str
mov cx, no_exten_str_end - no_exten_str
print:
push 0xb800 push 0xb800
pop es pop es
xor di, di xor di, di
mov si, string
mov cx, 10
mov ah, 0x7 mov ah, 0x7
err_print: err_print:
lodsb lodsb
stosw stosw
loop err_print loop err_print
add di, 2
mov ax, bx
call hexprint
hlt_loop: hlt_loop:
hlt hlt
jmp hlt_loop jmp hlt_loop
hexprint:
xor cx, cx
mov bl, al
shr al, 4
jmp .donibble
.nibble2:
mov al, bl
inc cx
.donibble:
and al, 0x0F
cmp al, 0x0A
jl .noadjust
add al, 'A' - '0' - 10
.noadjust:
add al, '0'
mov ah, 0x7
stosw
test cx, cx
jz .nibble2
ret
[BITS 32] [BITS 32]
Pmode: Pmode:
mov eax, 0x10 mov eax, 0x10
@ -49,18 +92,29 @@ mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
mov ss, ax mov ss, ax
in al, 0x92 ; check A20
.a20:
mov edi, 0x101337
mov esi, 0x001337
mov [esi], esi
mov [edi], edi
cmpsd
jne .kernel
in al, 0x92 ; fast A20
test al, 2 test al, 2
jnz after jnz .fa20_end
or al, 2 or al, 2
and al, 0xFE and al, 0xFE
out 0x92, al out 0x92, al
after: .fa20_end:
jmp .a20
.kernel:
mov esi, 0x8000 mov esi, 0x8000
mov edi, 0x100000 mov edi, 0x100000
mov ecx, 0x10000 mov ecx, 0x10000
rep movsb rep movsb
jmp 08h:0x100000 jmp 08h:0x100000
gdt_desc: gdt_desc:
dw gdt_end - gdt dw gdt_end - gdt
dd gdt dd gdt
@ -79,6 +133,9 @@ gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
gdt_end: gdt_end:
string: db 'DISK ERROR' string: db 'DISK ERROR'
string_end:
no_exten_str: db 'NO INT13 EXTEN'
no_exten_str_end:
addr_packet: addr_packet:
db 0x10, 0x00 ; size, reserved db 0x10, 0x00 ; size, reserved

View File

@ -22,6 +22,13 @@ void int_printDword(uint32_t v, uint16_t *buff) {
int_printWord(v >> 16, buff); int_printWord(v >> 16, buff);
int_printWord(v, &buff[4]); int_printWord(v, &buff[4]);
} }
__attribute((__no_caller_saved_registers__))
uintptr_t int_printStr(char *v, uint16_t *buff) {
char *s;
for (s = v;*s;s++,buff++)
*(char*)buff = *s;
return s - v;
}
struct __attribute__((__packed__)) IDTR_t { struct __attribute__((__packed__)) IDTR_t {
uint16_t size; uint16_t size;
@ -90,6 +97,8 @@ extern void real_test();
extern void jmp_usermode_test(); extern void jmp_usermode_test();
__attribute((__no_caller_saved_registers__)) __attribute((__no_caller_saved_registers__))
extern void return_prev_task(); extern void return_prev_task();
__attribute((__no_caller_saved_registers__))
extern void error_environment(); // defined in kernel.c
#define VALID_FLAGS 0xDFF #define VALID_FLAGS 0xDFF
__attribute__ ((interrupt)) __attribute__ ((interrupt))
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
@ -220,6 +229,23 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
frame->eip = (uint16_t) (frame->eip + 1); frame->eip = (uint16_t) (frame->eip + 1);
goto done; goto done;
default: default:
{
uint16_t *e = error_screen;
for (int i = 0; i < 80; i++)
e[i] = 0x0f00;
e += int_printStr("Unknown instruction caused V86 GPF: ", e);
*(uint32_t*)e = 0x1f001f00;
int_printDword(*(uint32_t*)ip, e);
e += 9;
*(uint8_t*)e = '@';
e += 1;
int_printWord(frame->cs, e);
e += 4;
*(uint8_t*)e = ':';
e += 1;
int_printWord(frame->eip, e);
error_environment();
}
for(;;); for(;;);
} }
} }

View File

@ -104,15 +104,16 @@ void ensure_v86env() {
char *d = &_v86code; char *d = &_v86code;
while (d < &_ev86code) while (d < &_ev86code)
*d++ = *s++; *d++ = *s++;
for (int i = 0; i < 80*50; i++)
if (!(error_screen[i] & 0xFF00))
error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF);
} }
__attribute((__no_caller_saved_registers__)) __attribute((__no_caller_saved_registers__))
extern void return_prev_task(); extern void return_prev_task();
__attribute((__no_caller_saved_registers__))
void error_environment() { void error_environment() {
ensure_v86env(); ensure_v86env();
for (int i = 0; i < 80*50; i++)
if (!(error_screen[i] & 0xFF00))
error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF);
union V86Regs_t regs; union V86Regs_t regs;
FARPTR v86_entry = i386LinearToFp(v86TextMode); FARPTR v86_entry = i386LinearToFp(v86TextMode);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
@ -126,7 +127,12 @@ void error_environment() {
for(;;) { for(;;) {
uint8_t key = get_scancode() & 0xff; uint8_t key = get_scancode() & 0xff;
if (key == KEY_E) break; if (key == KEY_E) break;
if (key == KEY_R) return_prev_task(); if (key == KEY_R) {
// reset error screen
for (int i = 0; i < (80*50)/2; i++)
((uint32_t*)error_screen)[i] = 0x0f000f00;
return_prev_task();
}
} }
v86_entry = i386LinearToFp(v86TransFlag); v86_entry = i386LinearToFp(v86TransFlag);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), &regs);
@ -288,6 +294,12 @@ void start() {
*(char *)&vga_text[i] = h[i]; *(char *)&vga_text[i] = h[i];
vga_text = &vga_text[80]; vga_text = &vga_text[80];
// DL *should* be preserved
uint8_t dl;
asm volatile("nop":"=d"(dl));
vga_text += printByte(dl, vga_text);
vga_text++;
uint32_t o; uint32_t o;
asm("mov %%esp, %%eax" : "=a"(o) : :); asm("mov %%esp, %%eax" : "=a"(o) : :);
vga_text += printDword(o, vga_text); vga_text += printDword(o, vga_text);
@ -303,15 +315,14 @@ void start() {
// *(char *)&vga_text[i+(80*3)] = c[i]; // *(char *)&vga_text[i+(80*3)] = c[i];
//if (!apic) return; //if (!apic) return;
char sse_str[] = "SSE support: "; //char sse_str[] = "SSE support: ";
vga_text += printStr("SSE: ", vga_text); //vga_text += printStr("SSE: ", vga_text);
char sse = check_sse(); //char sse = check_sse();
if (!sse) { //if (!sse) {
*vga_text = 'N'; // *vga_text = 'N';
return; //}
} //vga_text += printStr("Y ", vga_text);
vga_text += printStr("Y ", vga_text); //enable_sse();
enable_sse();
setup_binary(); setup_binary();
@ -327,7 +338,7 @@ void start() {
//print_cr4(); //print_cr4();
backup_ivtbios(); backup_ivtbios();
vga_text = &((word *)0xb8000)[80]; vga_text = &((word *)0xb8000)[160];
vga_text += printStr("Press T for tests, or any key to continue... ", vga_text); vga_text += printStr("Press T for tests, or any key to continue... ", vga_text);
uint8_t key = get_key(); uint8_t key = get_key();
if (key == 't' || key == 'T') if (key == 't' || key == 'T')

View File

@ -40,7 +40,7 @@ void TestDiskRead() {
regs.w.ax = 3; // text mode regs.w.ax = 3; // text mode
V8086Int(0x10, &regs); V8086Int(0x10, &regs);
vga_text += printStr("Done. Starting Disk Read... ", vga_text); vga_text += printStr("Done. Starting Disk Read... ", vga_text);
char *diskReadBuf = (char *)0x23000; char *diskReadBuf = (char *)0x8000;
v86disk_addr_packet.transfer_buffer = v86disk_addr_packet.transfer_buffer =
(uintptr_t)diskReadBuf & 0x000F | (uintptr_t)diskReadBuf & 0x000F |
(((uintptr_t)diskReadBuf & 0xFFFF0) << 12); (((uintptr_t)diskReadBuf & 0xFFFF0) << 12);

View File

@ -1,6 +1,5 @@
[BITS 16] [BITS 16]
[SECTION .v86] [SECTION .v86]
global v86Interrupt global v86Interrupt
v86Interrupt: v86Interrupt:
int 0x00 int 0x00

View File

@ -41,7 +41,7 @@ union __attribute((__packed__)) V86Regs_t {
} h; } h;
}; };
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs); extern uint32_t enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
void V8086Int(uint8_t interrupt, union V86Regs_t *regs); void V8086Int(uint8_t interrupt, union V86Regs_t *regs);
@ -76,3 +76,4 @@ typedef uint32_t FARPTR;
FARPTR i386LinearToFp(void *ptr); FARPTR i386LinearToFp(void *ptr);
void ensure_v86env();

BIN
virtdisk.bin.ex Normal file

Binary file not shown.