From 716ee8010361e9f2f75cf62f032495a2b0067d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20Kj=C3=A6r-Kammersgaard?= Date: Wed, 7 Nov 2018 13:39:25 +0100 Subject: [PATCH] hej --- CLI/CLI.nasm | 7 +- build | 24 ++-- build.sh | 3 +- go32bit.nasm | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel.nasm | 6 + lib/svim.nasm | 2 +- 6 files changed, 331 insertions(+), 17 deletions(-) create mode 100644 go32bit.nasm diff --git a/CLI/CLI.nasm b/CLI/CLI.nasm index 369f268..d50c21d 100644 --- a/CLI/CLI.nasm +++ b/CLI/CLI.nasm @@ -157,9 +157,9 @@ CLI_EXECUTE: ret .tmp dw 0 - .Num_Commands dw 9 - .Command_Name_List dw .CMD1, .CMD2, .CMD3, .CMD4, .CMD5, .CMD6, .CMD7, .CMD8, .CMD9 - .Command_Function_Pointers dw dumpmem_hardcoded_args, keyprint, svim, lsfs_list_files_command, lsfs_create_file, lsfs_format_disk, lsfs_get_fs_info, os_clear_screen, print_help_message + .Num_Commands dw 10 + .Command_Name_List dw .CMD1, .CMD2, .CMD3, .CMD4, .CMD5, .CMD6, .CMD7, .CMD8, .CMD9, .CMDa + .Command_Function_Pointers dw dumpmem_hardcoded_args, keyprint, svim, lsfs_list_files_command, lsfs_create_file, lsfs_format_disk, lsfs_get_fs_info, os_clear_screen, print_help_message, Go32Bit .CMD1 db 'dumpmem', 0 .CMD2 db 'keyprint', 0 .CMD3 db 'svim', 0 @@ -169,5 +169,6 @@ CLI_EXECUTE: .CMD7 db 'fsinfo', 0 .CMD8 db 'clear', 0 .CMD9 db 'help', 0 + .CMDa db 'go32', 0 diff --git a/build b/build index b94be90..709bf38 100755 --- a/build +++ b/build @@ -1,15 +1,17 @@ #!/usr/bin/bash -if [ "$1" == "build" ] || [ "$1" == "run" ]; then - nasm -fbin bootloader.nasm -o bootloader.bin - nasm -fbin kernel.nasm -o kernel.bin - cat bootloader.bin kernel.bin > SingOS.img +# if [ "$1" == "build" ] || [ "$1" == "run" ]; then +# nasm -fbin bootloader.nasm -o bootloader.bin +# nasm -fbin kernel.nasm -o kernel.bin +# cat bootloader.bin kernel.bin > SingOS.img - if [ $1 == "run" ]; then - qemu-system-x86_64 -drive index=0,format=raw,file=SingOS.img - else - bash -c "echo;echo;echo 'Press [ENTER] to exit'; read line" - fi -fi +# if [ $1 == "run" ]; then +# qemu-system-x86_64 -drive index=0,format=raw,file=SingOS.img +# else +# bash -c "echo;echo;echo 'Press [ENTER] to exit'; read line" +# fi +# fi -echo "Done" \ No newline at end of file +# echo "Done" + +sh build.sh \ No newline at end of file diff --git a/build.sh b/build.sh index 87a8822..f77a546 100755 --- a/build.sh +++ b/build.sh @@ -10,5 +10,4 @@ if [ "$1" != "make" ]; then qemu-system-x86_64 -drive index=0,format=raw,file=SingOS.img fi -echo "Done" - +echo "Done" \ No newline at end of file diff --git a/go32bit.nasm b/go32bit.nasm new file mode 100644 index 0000000..2f1f19a --- /dev/null +++ b/go32bit.nasm @@ -0,0 +1,306 @@ + +; %define GDT 0xfe00 +%define GDT_CodeSegIndex 1 +%define GDT_DataSegIndex 2 +%define GDT_Selector(DescriptorIndex, TableIndicator, RequestorPrivLevel) ((DescriptorIndex << 3) | ((TableIndicator & 1) << 2) | (RequestorPrivLevel & 0x3)) +%define GDT_CodeSegmentSelector GDT_Selector(GDT_CodeSegIndex, 0, 0) +%define GDT_DataSegmentSelector GDT_Selector(GDT_DataSegIndex, 0, 0) + +%define VIDEO 0xB8000 + +; GDT Stuff +%define Data 0000b +%define DataMutable 0010b +%define DataShrink 0100b +%define DataShrinkMutable 0110b +%define Code 1000b +%define CodeRead 1010b +%define CodeOwnRing 1100b +%define CodeOwnRingRead 1110b + +%macro GDT_NULL_ENTRY 1 ; address + %assign address %1 + lea di, [address] + xor ax, ax + mov cx, 4 + rep stosw +%endmacro + +%macro GDT_ENTRY 6 ; address base limit type privilege bits32 + %assign address %1 + + %assign base %2 + %assign limit %3 + + %assign type (%4 & 0xf) + %assign reserved (1<<4) + %assign privilege ((%5 & 0x3) << 5) + %assign present (1<<7) + %assign access (present | privilege | reserved | type) + + %assign bits32 ((%6 & 1) << 2) + %assign granularity (1<<3) + %assign flags (granularity | bits32) + + %assign limit_0_15 (limit & 0xffff) + %assign limit_16_19 ((limit >> 16) & 0xf) + %assign base_0_15 (base & 0xffff) + %assign base_16_23 ((base >> 16) & 0xff) + %assign base_24_31 ((base >> 24) & 0xff) + + mov WORD [es:(address + 0)], limit_0_15 + mov WORD [es:(address + 2)], base_0_15 + mov WORD [es:(address + 4)], base_16_23 | (access << 8) + mov WORD [es:(address + 6)], limit_16_19 | (flags << 4) | (base_24_31 << 8) +%endmacro + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Enable_A20: +; Enables A20 gate using:the BIOS, keyboard controller, or Fast A20 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pushad ;Preserve registers + pushfd ;Preserve EFLAGS because we might disable interrupts + mov ax,0x2402 ;INT 15h AX=2402h: Query A20 status + int 0x15 ;Check to see if A20 gate is enabled + jc A20_No_BIOS ;Error? Don't use BIOS to enable gate + test al,1 ;Test Bit 0 of AL + je A20_Enabled ;A20 gate already enabled + mov ax,0x2401 ;INT 15h AX=2401h: Enable A20 gate + int 0x15 ;Use BIOS to enable A20 gate + jc A20_No_BIOS ;Error? Don't use BIOS to enable gate + or ah,ah ;Test AH + jnz A20_No_BIOS ;Non-zero? A20 gate may not be enabled +A20_Enabled: + popfd ;Restore EFLAGS + popad ;Restore registers + ret ;Return +A20_No_BIOS: + mov ax,0x2403 ;INT 15h AX=2403h: Query A20 support + int 0x15 ;Call BIOS to find out how the A20 gate can be enabled + jc A20_KBD ;Error? Assume that keyboard controller is the only option + test bx,1 ;Bit 0:Keyboard controller supported + je A20_KBD ;BIOS indicates that keyboard controller is supported + test bx,2 ;Bit 1:Fast A20 supported + je FAST_A20 ;BIOS indicated that Fast A20 is supported + call Check_A20 ;Test A20 gate manually + jc A20_Enabled ;A20 gate already enabled +A20_Fail: + call A20_OUT_Wait ;"Unable to enable A20 gate!" + cli ;Disable interrupts + hlt ;Halt machine +FAST_A20: + in al,0x92 ;Read System Control Port A + test al,2 ;Test Fast A20 bit + jnz A20_Fail ;Bit already set, failed to enable A20 gate + or al,2 ;Set Bit 1:Enable Fast A20 + and al,0xFE ;Always clear Bit 0 so that machine does not reboot + out 0x92,al ;Write to port 92h + call Check_A20 ;Check A20 gate + jc A20_Enabled ;Success? + cli ;No? something must have gone wrong + hlt ;Clear interrupts and halt machine +A20_KBD: + cli ;Disable interrupts + mov cx,50 ;Number of attempts to enable gate +Use_KBD: + call A20_OUT_Wait ;Wait for keyboard + mov al,0xAD ;Disable Keyboard + out 0x64,al ;Wait for Keyboard + mov al,0xD0 ;Read Controller Output Port + out 0x64,al + call A20_IN_Wait ;Wait for Keyboard + in al,0x60 ;Read Data Port + push ax ;Save + call A20_OUT_Wait ;Wait for Keyboard + mov al,0xD1 ;Write Controller Output Port + out 0x64,al + call A20_OUT_Wait ;Wait for Keyboard + pop ax ;Get port data back + or al,10b ;Bit 1: Enable A20 gate + out 0x60,al ;Write to data port + call A20_OUT_Wait ;Wait for Keyboard + mov al,0xAE ;Enable Keyboard + out 0x64,al + call A20_OUT_Wait ;Wait for Keyboard + call Check_A20 ;Verify that gate is enabled + jc A20_Enabled ;Yes? Return + loop Use_KBD ;No? Keep trying + jmp A20_Fail ;Could not enable gate after 50 tries +A20_OUT_Wait: + in al,0x64 ;Read status register + test al,10b ;Is port ready? + jnz A20_OUT_Wait ;Nope, wait + ret ;Yep, continue +A20_IN_Wait: + in al,0x64 ;Read status register + test al,1b ;Is port ready? + jz A20_IN_Wait ;Nope, wait + ret ;Yep, continue + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Check_A20: +; Test if A20 gate is enabled by comaparing the value in FFFF:7E0E +; with the VBR boot signature at 0000:7DFE +; Out: Carry flag set if A20 gate is enabled +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pushad ;Preserve registers + push es + mov ax, 0xFFFF + mov es, ax ;Extra segment:FFFF + cmp WORD [es:0x7DFE + 16], 0xAAFF ;See if boot signature is wrapped at FFFF:7E0E (Meaning FFFF:7E0E = 0:7DFE) + stc ; Assume we didn't wrap, yes A20 + jne .End + clc ; We did wrap, no A20 +.End: + pop es + popad + ret + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Go32Bit: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call Enable_A20 + + ; Set screen mode + mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors + mov bx, 0x0000 + int 0x10 ; Video BIOS interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Global Descriptor Table ; +;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 0x1000 + mov es, ax + mov cx, 1024 + lea si, [GO32_COPY_BEGIN] + xor di, di + rep movsb + + %assign GDT_SIZE 0 + + GDT_NULL_ENTRY 0 + %assign GDT_SIZE (GDT_SIZE+8) + + GDT_ENTRY (GDT_CodeSegIndex*8), 0x00000000, 0xffffffff, CodeRead, 0, 1 + %assign GDT_SIZE (GDT_SIZE+8) + + GDT_ENTRY (GDT_DataSegIndex*8), 0x00000000, 0xffffffff, DataMutable, 0, 1 + %assign GDT_SIZE (GDT_SIZE+8) + + + cli + lgdt [GDT_Record] + + mov eax, cr0 + or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0) + mov cr0, eax + + jmp ClearPrefetchQueue + nop + nop +ClearPrefetchQueue: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Manually assembled long jump ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + db 0x66 ; 32bit override + db 0xea ; Long jump + dd 0x1000*16 + 512 ; Absolute address + dw GDT_CodeSegmentSelector ; Descriptor Selector + +GDT_Record: + dw GDT_SIZE - 1 ; Size of GDT in bytes minus 1 + dd 0x1000*16 ; Linear address of GDT + + + +align 512 +GO32_COPY_BEGIN: +segment Go32Bit vstart=(0x1000*16) +BITS 32 +GDT: + .null_selector: dq 0 + .code_selector: dq 0 + .data_selector: dq 0 +align 512 +ProtectedModeBaby: + + ; Update Other Segments + mov ax, GDT_DataSegmentSelector + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Setup stack + mov esp, 0xffffffff + + mov ecx, 0 + mov edx, 0 + lea edi, [VIDEO] + mov ax, 0x4000 +LoopRows: + LoopCols: + mov bl, cl + xor bl, dl + shl bl, 4 + mov ah, bl + ror bl, 1 + xor ah, bl + and ah, 0x70 + mov al, dl + add al, cl + and al, 4 + ror al, 1 + or ah, al + mov al, 0 + mov WORD [edi], ax + inc edi + inc edi + inc ecx + cmp ecx, 80 + je BreakLoopCols + jmp LoopCols + BreakLoopCols: + mov ecx, 0 + inc edx + cmp edx, 25 + je BreakLoopRows + jmp LoopRows +BreakLoopRows: + +WriteProtectedModeString: + cld + lea esi, [ProtectedWelcomeStr] + lea edi, [VIDEO+(80*2)*12+19*2] +.print_loop: + mov al, BYTE [esi] + test al, al + jz .break_print_loop + mov BYTE [edi], al + mov BYTE [edi+1], 0x0f + inc esi + inc edi + inc edi + jmp .print_loop +.break_print_loop: + +HALT: + cli + hlt + jmp HALT + +;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings +;;;;;;;;;;;;;;;;;;;;;;;; + ProtectedWelcomeStr: db " Placeholder for SingOS - 32 bit edition! ", 0 +align 512 diff --git a/kernel.nasm b/kernel.nasm index 7020258..78a038f 100644 --- a/kernel.nasm +++ b/kernel.nasm @@ -305,6 +305,12 @@ data: ;times 131072-($-$$) db 0 ; 256 sectos ;GLOBAL_VSFS_START db 'VSFS v0.1' ; sector 257 reserved for file system information + +%include "go32bit.nasm" + +; times ((1<<13)-($-$$)) db 0 ; sector 258 to sector 2048 should be avaliable to the filesystem. + + times ((1<<20)-($-$$) - 26) db 0 ; sector 258 to sector 2048 should be avaliable to the filesystem. magic_string_end_of_SingOS_kernel db '** END OF KERNEL SingOS **' diff --git a/lib/svim.nasm b/lib/svim.nasm index e86ce45..55d09cc 100644 --- a/lib/svim.nasm +++ b/lib/svim.nasm @@ -242,5 +242,5 @@ svim: .welcome_svim_enter_fileindex db 'Enter fileindex: ', 0 .seperate_line db '________________________________________________________________________________', 0 .fileindex_for_open_file dw 0 -.buffer_for_svim times 1024 db 0 ; db 'this is the buffer', 0, times 32 db 0 +.buffer_for_svim times 1 db 0 ; db 'this is the buffer', 0, times 32 db 0 .buffer_counter_svim dw 0