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
|
||||
*.bin
|
||||
*.img
|
||||
*.lock
|
||||
*.com
|
||||
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
|
||||
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
|
||||
nasm -f elf32 -o $@ $<
|
||||
@ -11,7 +11,7 @@ all: $(objects)
|
||||
nasm boot.nasm -o boot.bin
|
||||
gcc -Tlink.ld -Wl,-M -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\
|
||||
$(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
|
||||
virtdisk:
|
||||
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 ss, ax
|
||||
mov sp, 0xFF00
|
||||
mov ah, 0x41 ; int 13 extensions check
|
||||
mov bx, 0x55AA
|
||||
int 0x13
|
||||
jc no_exten
|
||||
mov cx, kernelreads
|
||||
read_loop:
|
||||
xor ax, ax
|
||||
@ -19,6 +23,14 @@ add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
|
||||
add word [addr_packet_start_block], secreadcnt
|
||||
loop read_loop
|
||||
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
|
||||
xor ax,ax
|
||||
mov ds, ax
|
||||
@ -28,19 +40,50 @@ or al, 1
|
||||
mov cr0, eax
|
||||
jmp 08h:Pmode
|
||||
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
|
||||
pop es
|
||||
xor di, di
|
||||
mov si, string
|
||||
mov cx, 10
|
||||
mov ah, 0x7
|
||||
err_print:
|
||||
lodsb
|
||||
stosw
|
||||
loop err_print
|
||||
add di, 2
|
||||
mov ax, bx
|
||||
call hexprint
|
||||
hlt_loop:
|
||||
hlt
|
||||
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]
|
||||
Pmode:
|
||||
mov eax, 0x10
|
||||
@ -49,18 +92,29 @@ mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, 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
|
||||
jnz after
|
||||
jnz .fa20_end
|
||||
or al, 2
|
||||
and al, 0xFE
|
||||
out 0x92, al
|
||||
after:
|
||||
.fa20_end:
|
||||
jmp .a20
|
||||
.kernel:
|
||||
mov esi, 0x8000
|
||||
mov edi, 0x100000
|
||||
mov ecx, 0x10000
|
||||
rep movsb
|
||||
jmp 08h:0x100000
|
||||
|
||||
gdt_desc:
|
||||
dw gdt_end - gdt
|
||||
dd gdt
|
||||
@ -79,6 +133,9 @@ gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
gdt_end:
|
||||
|
||||
string: db 'DISK ERROR'
|
||||
string_end:
|
||||
no_exten_str: db 'NO INT13 EXTEN'
|
||||
no_exten_str_end:
|
||||
|
||||
addr_packet:
|
||||
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, &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 {
|
||||
uint16_t size;
|
||||
@ -90,6 +97,8 @@ extern void real_test();
|
||||
extern void jmp_usermode_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void return_prev_task();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void error_environment(); // defined in kernel.c
|
||||
#define VALID_FLAGS 0xDFF
|
||||
__attribute__ ((interrupt))
|
||||
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);
|
||||
goto done;
|
||||
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(;;);
|
||||
}
|
||||
}
|
||||
|
39
kernel.c
39
kernel.c
@ -104,15 +104,16 @@ void ensure_v86env() {
|
||||
char *d = &_v86code;
|
||||
while (d < &_ev86code)
|
||||
*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__))
|
||||
extern void return_prev_task();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
void error_environment() {
|
||||
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;
|
||||
FARPTR v86_entry = i386LinearToFp(v86TextMode);
|
||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
||||
@ -126,7 +127,12 @@ void error_environment() {
|
||||
for(;;) {
|
||||
uint8_t key = get_scancode() & 0xff;
|
||||
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);
|
||||
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];
|
||||
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;
|
||||
asm("mov %%esp, %%eax" : "=a"(o) : :);
|
||||
vga_text += printDword(o, vga_text);
|
||||
@ -303,15 +315,14 @@ void start() {
|
||||
// *(char *)&vga_text[i+(80*3)] = c[i];
|
||||
//if (!apic) return;
|
||||
|
||||
char sse_str[] = "SSE support: ";
|
||||
vga_text += printStr("SSE: ", vga_text);
|
||||
char sse = check_sse();
|
||||
if (!sse) {
|
||||
*vga_text = 'N';
|
||||
return;
|
||||
}
|
||||
vga_text += printStr("Y ", vga_text);
|
||||
enable_sse();
|
||||
//char sse_str[] = "SSE support: ";
|
||||
//vga_text += printStr("SSE: ", vga_text);
|
||||
//char sse = check_sse();
|
||||
//if (!sse) {
|
||||
// *vga_text = 'N';
|
||||
//}
|
||||
//vga_text += printStr("Y ", vga_text);
|
||||
//enable_sse();
|
||||
|
||||
setup_binary();
|
||||
|
||||
@ -327,7 +338,7 @@ void start() {
|
||||
//print_cr4();
|
||||
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);
|
||||
uint8_t key = get_key();
|
||||
if (key == 't' || key == 'T')
|
||||
|
2
tests.c
2
tests.c
@ -40,7 +40,7 @@ void TestDiskRead() {
|
||||
regs.w.ax = 3; // text mode
|
||||
V8086Int(0x10, ®s);
|
||||
vga_text += printStr("Done. Starting Disk Read... ", vga_text);
|
||||
char *diskReadBuf = (char *)0x23000;
|
||||
char *diskReadBuf = (char *)0x8000;
|
||||
v86disk_addr_packet.transfer_buffer =
|
||||
(uintptr_t)diskReadBuf & 0x000F |
|
||||
(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
|
||||
|
1
v86.nasm
1
v86.nasm
@ -1,6 +1,5 @@
|
||||
[BITS 16]
|
||||
[SECTION .v86]
|
||||
|
||||
global v86Interrupt
|
||||
v86Interrupt:
|
||||
int 0x00
|
||||
|
@ -41,7 +41,7 @@ union __attribute((__packed__)) V86Regs_t {
|
||||
} 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);
|
||||
|
||||
@ -76,3 +76,4 @@ typedef uint32_t FARPTR;
|
||||
|
||||
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