Adding code so far.
This commit is contained in:
commit
4700f983f8
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
bin/*
|
||||
*.bin
|
||||
*.o
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
20
Makefile
Normal file
20
Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
ASM=nasm
|
||||
AFLAGS=-f bin
|
||||
BIN=bin
|
||||
CFLAGS=-ffreestanding -fno-pie -m32
|
||||
CC=gcc
|
||||
LD=ld
|
||||
LDFLAGS=-melf_i386 -Ttext 0x1000 --oformat binary
|
||||
|
||||
basicos:
|
||||
mkdir -p $(BIN)
|
||||
$(ASM) boot_sect.asm $(AFLAGS) -o boot_sect.bin
|
||||
$(CC) $(CFLAGS) -c kernel.c -o kernel.o
|
||||
$(LD) $(LDFLAGS) -o kernel.bin kernel.o
|
||||
cat boot_sect.bin kernel.bin > $(BIN)/os-image
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm *.bin *.o
|
55
boot_sect.asm
Normal file
55
boot_sect.asm
Normal file
@ -0,0 +1,55 @@
|
||||
[org 0x7c00]
|
||||
KERNEL_OFFSET: equ 0x1000 ; kernel memory offset
|
||||
mov [BOOT_DRIVE], dl ; store boot drive for later.
|
||||
mov bp, 0x9000 ; setup the stack
|
||||
mov sp, bp
|
||||
|
||||
mov bx, MSG_REAL_MODE
|
||||
call print_string
|
||||
|
||||
call load_kernel ; load our kernel from memory
|
||||
call switch_to_pm ; switch to 32-bit protected mode
|
||||
|
||||
jmp $
|
||||
|
||||
%include "print.asm"
|
||||
%include "print32.asm"
|
||||
%include "disk.asm"
|
||||
%include "gdt.asm"
|
||||
%include "switch_prot.asm"
|
||||
|
||||
[bits 16]
|
||||
|
||||
load_kernel:
|
||||
mov bx, MSG_LOAD_KERNEL
|
||||
call print_string
|
||||
|
||||
mov bx, KERNEL_OFFSET ; address to load the kernel to
|
||||
mov dh, 15 ; number of sectors to load
|
||||
mov dl, [BOOT_DRIVE] ; drive to load from
|
||||
call disk_load
|
||||
|
||||
mov bx, MSG_KERNEL_LOADED
|
||||
call print_string
|
||||
|
||||
ret
|
||||
|
||||
[bits 32]
|
||||
BEGIN_PM:
|
||||
mov ebx, MSG_PROT_MODE
|
||||
call print_string_pm
|
||||
|
||||
call KERNEL_OFFSET
|
||||
|
||||
jmp $
|
||||
|
||||
;;;
|
||||
; Data
|
||||
BOOT_DRIVE: db 0
|
||||
MSG_REAL_MODE: db "Started in 16-bit Real Mode",0
|
||||
MSG_PROT_MODE: db "Successfully landed in 32-bit Protected Mode",0
|
||||
MSG_LOAD_KERNEL: db "Loading kernel into memory...",0
|
||||
MSG_KERNEL_LOADED: db "Successfully loaded kernel into memory",0
|
||||
|
||||
times 510-($-$$) db 0
|
||||
dw 0xaa55
|
43
disk.asm
Normal file
43
disk.asm
Normal file
@ -0,0 +1,43 @@
|
||||
;;;
|
||||
; disk_load
|
||||
; ---------
|
||||
; Load disk sectors into memory.
|
||||
;
|
||||
; Parameters:
|
||||
; - dh: number of sectors to read
|
||||
disk_load:
|
||||
pusha
|
||||
push dx ; store `dx' to check if the appropriate number of
|
||||
; sectors were read later on.
|
||||
mov ah, 0x02 ; BIOS read routine
|
||||
mov al, dh ; read `dh' sectors
|
||||
mov ch, 0x00 ; select cylinder 0
|
||||
mov dh, 0x00 ; select head 0
|
||||
mov cl, 0x02 ; start reading from second sector (after the boot
|
||||
; sector)
|
||||
|
||||
int 0x13 ; BIOS interrupt
|
||||
|
||||
jc disk_load_error ; if `cf' flag has gone off then a read error has
|
||||
; occurred
|
||||
|
||||
pop dx ; restore `dx'
|
||||
cmp dh, al ; were the appropriate amount of sectors read?
|
||||
jne disk_load_unexp ; if not then there was an error
|
||||
popa
|
||||
ret
|
||||
|
||||
disk_load_error:
|
||||
mov bx, DISK_READ_ERROR ; print the error
|
||||
jmp disk_load_print_exit
|
||||
disk_load_unexp:
|
||||
mov bx, DISK_READ_UNEXP
|
||||
disk_load_print_exit:
|
||||
call print_string
|
||||
jmp $ ; lock due to failure
|
||||
|
||||
DISK_READ_UNEXP:
|
||||
db "Unexpected amount of sectors read!",0
|
||||
|
||||
DISK_READ_ERROR:
|
||||
db "Disk read error!",0
|
37
gdt.asm
Normal file
37
gdt.asm
Normal file
@ -0,0 +1,37 @@
|
||||
; GDT
|
||||
gdt_start:
|
||||
|
||||
gdt_null:
|
||||
dd 0x0 ; the mandatory null-descriptor
|
||||
dd 0x0
|
||||
|
||||
gdt_code: ; code segment of descriptor
|
||||
dw 0xFFFF ; Limit (bits 0-15)
|
||||
dw 0x0 ; Base (bits 0-15)
|
||||
db 0x0 ; Base (bits 16-23
|
||||
; 1st flags: (present)1, (privilege)00, (descriptor type)1 -> 1001b
|
||||
; type flags: (code)1, (conforming)0, (readable)1, (accessed)0 -> 1010b
|
||||
; 2nd flags: (granularity)1, (32-bit default)1, (64-bit seg)0, (AVL)0 -> 1100b
|
||||
db 10011010b ; 1st flags and type flags
|
||||
db 11001111b ; 2nd flags and Limit (bits 16-19)
|
||||
db 0x0 ; Base (bits 24-31)
|
||||
|
||||
gdt_data:
|
||||
; type flags: (code)0, (expand down)0, (writable)1, (accessed)0 -> 0010b
|
||||
dw 0xFFFF ; Limit (bits 0-15)
|
||||
dw 0x0 ; Base (bits 0-15)
|
||||
db 0x0 ; Base (bits 16-23)
|
||||
db 10010010b ; 1st flags and type flags
|
||||
db 11001111b ; 2nd flags and Limit (bits 16-19)
|
||||
db 0x0 ; Base (bits 24-31)
|
||||
|
||||
gdt_end: ; for calculating size of the gdt
|
||||
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1 ; size of our GDT, always decrement true size by one
|
||||
dd gdt_start ; start address of our GDT
|
||||
|
||||
;;;
|
||||
; Constants used for GDT segment offsets
|
||||
GDT_CODE_SEG: equ gdt_code - gdt_start
|
||||
GDT_DATA_SEG: equ gdt_data - gdt_start
|
10
kernel.c
Normal file
10
kernel.c
Normal file
@ -0,0 +1,10 @@
|
||||
void main() {
|
||||
/*
|
||||
* point to first text cell of the video memory
|
||||
*/
|
||||
char *video_memory = (char*) 0xb8000;
|
||||
/*
|
||||
* store the character 'X' there
|
||||
*/
|
||||
*video_memory = 'X';
|
||||
}
|
27
print.asm
Normal file
27
print.asm
Normal file
@ -0,0 +1,27 @@
|
||||
;;;
|
||||
; print_string
|
||||
; ------------
|
||||
; Print a string from memory.
|
||||
;
|
||||
; Parameters:
|
||||
; - bx: pointer to string
|
||||
;
|
||||
; Internal Variables:
|
||||
; - ah: scrolling teletype BIOS routine code
|
||||
; - al: Byte containing character to print
|
||||
; - bx: shifting pointer to string
|
||||
print_string:
|
||||
pusha ; save the state of all registers to the stack
|
||||
|
||||
mov ah, 0x0e ; scrolling teletype BIOS routine code
|
||||
print_string_start:
|
||||
mov al, [bx] ; load first letter into `al'
|
||||
cmp al, 0
|
||||
je print_string_end ; if null-termination then return
|
||||
int 0x10 ; print the letter
|
||||
add bx, 0x1 ; offset to next character
|
||||
jmp print_string_start ; go back to beginning
|
||||
|
||||
print_string_end:
|
||||
popa ; return the state of all the registers
|
||||
ret
|
30
print32.asm
Normal file
30
print32.asm
Normal file
@ -0,0 +1,30 @@
|
||||
[bits 32]
|
||||
VIDEO_MEMORY: equ 0xB8000
|
||||
WHITE_ON_BLACK: equ 0x0F
|
||||
|
||||
;;;
|
||||
; print_string_pm
|
||||
; ------------
|
||||
; Print a string stored in memory.
|
||||
;
|
||||
; Parameters:
|
||||
; - ebx: pointer to string in memory
|
||||
print_string_pm:
|
||||
pusha
|
||||
mov edx, VIDEO_MEMORY ; set `edx' to the start of the video memory
|
||||
|
||||
print_string_pm_loop:
|
||||
mov al, [ebx] ; store the char at `ebx' in `al'
|
||||
mov ah, WHITE_ON_BLACK ; store the attributes in `ah'
|
||||
cmp al, 0 ; if null-termination then done
|
||||
je print_string_pm_done
|
||||
|
||||
mov [edx], ax ; store char and attributes
|
||||
add ebx, 1 ; increment ebx to next char
|
||||
add edx, 2 ; increment to next char cell in vidmem
|
||||
|
||||
jmp print_string_pm_loop
|
||||
|
||||
print_string_pm_done:
|
||||
popa
|
||||
ret
|
29
switch_prot.asm
Normal file
29
switch_prot.asm
Normal file
@ -0,0 +1,29 @@
|
||||
[bits 16]
|
||||
switch_to_pm:
|
||||
cli ; turn off all interrupts until we have properly
|
||||
; properly set them up
|
||||
|
||||
lgdt [gdt_descriptor] ; load the global descriptor table defining
|
||||
; protected mode segments
|
||||
|
||||
mov eax, cr0 ; set flag in register to switch to protected mode
|
||||
or eax, 0x1
|
||||
mov cr0, eax
|
||||
|
||||
jmp GDT_CODE_SEG:init_pm ; make a far jump to the 32-bit code forcing a flush
|
||||
; of the pipelining
|
||||
|
||||
[bits 32]
|
||||
; initialize registers and the stack once in protected mode
|
||||
init_pm:
|
||||
mov ax, GDT_DATA_SEG ; point our new segment registers to the data
|
||||
mov ds, ax ; selector defined in the GDT, since we cannot
|
||||
mov ss, ax ; use the old 16-bit code
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
mov ebp, 0x90000 ; Update the stack position so it's at the top
|
||||
mov esp, ebp ; of the free space
|
||||
|
||||
call BEGIN_PM
|
Loading…
Reference in New Issue
Block a user