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 | *.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.
										
									
								
							
		Reference in New Issue
	
	Block a user
	 Lucia Ceionia
					Lucia Ceionia