Added example disk, Made some minor changes to error output
This commit is contained in:
		
							
								
								
									
										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.
										
									
								
							
		Reference in New Issue
	
	Block a user