Added example disk, Made some minor changes to error output
This commit is contained in:
parent
0e3ae9c4e3
commit
7f0a94352d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
*.o
|
*.o
|
||||||
*.bin
|
*.bin
|
||||||
|
*.img
|
||||||
*.lock
|
*.lock
|
||||||
*.com
|
*.com
|
||||||
bx_enh_dbg.ini
|
bx_enh_dbg.ini
|
||||||
|
4
Makefile
4
Makefile
@ -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
|
||||||
|
67
boot.nasm
67
boot.nasm
@ -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
|
||||||
|
26
interrupt.c
26
interrupt.c
@ -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(;;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
39
kernel.c
39
kernel.c
@ -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), ®s);
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
||||||
@ -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), ®s);
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
||||||
@ -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')
|
||||||
|
2
tests.c
2
tests.c
@ -40,7 +40,7 @@ void TestDiskRead() {
|
|||||||
regs.w.ax = 3; // text mode
|
regs.w.ax = 3; // text mode
|
||||||
V8086Int(0x10, ®s);
|
V8086Int(0x10, ®s);
|
||||||
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);
|
||||||
|
1
v86.nasm
1
v86.nasm
@ -1,6 +1,5 @@
|
|||||||
[BITS 16]
|
[BITS 16]
|
||||||
[SECTION .v86]
|
[SECTION .v86]
|
||||||
|
|
||||||
global v86Interrupt
|
global v86Interrupt
|
||||||
v86Interrupt:
|
v86Interrupt:
|
||||||
int 0x00
|
int 0x00
|
||||||
|
@ -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
BIN
virtdisk.bin.ex
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user