Compare commits
	
		
			4 Commits
		
	
	
		
			68371475d9
			...
			BasicGraph
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f0651ef972 | |||
| 405b9468d5 | |||
| 006c902200 | |||
| 2eca761edc | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -5,6 +5,4 @@ isodir/
 | 
			
		||||
root/
 | 
			
		||||
*.iso
 | 
			
		||||
*.img
 | 
			
		||||
*.sym
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										104
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								Makefile
									
									
									
									
									
								
							@ -3,11 +3,11 @@ EMULATOR = qemu-system-i386
 | 
			
		||||
AS = ${HOME}/opt/cross/bin/i686-elf-as
 | 
			
		||||
CC = ${HOME}/opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++ 
 | 
			
		||||
CFLAGS =  -ffreestanding -Og -ggdb  -Wall -Wextra
 | 
			
		||||
CFLAGS =  -ffreestanding -O2 -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o  $(BUILD_DIR)/paging.o	$(BUILD_DIR)/pit.o 	$(BUILD_DIR)/time.o	$(BUILD_DIR)/keyboard.o	 $(BUILD_DIR)/io.o 	$(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o  $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o
 | 
			
		||||
OFILES =  $(BUILD_DIR)/boot.o $(BUILD_DIR)/window.o $(BUILD_DIR)/cursor.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o  $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o  $(BUILD_DIR)/vesa.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
 | 
			
		||||
 | 
			
		||||
SRC_DIR = source
 | 
			
		||||
SRC_DIR = src
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
 | 
			
		||||
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
 | 
			
		||||
@ -23,6 +23,8 @@ all: clean build
 | 
			
		||||
 | 
			
		||||
build: build_kernel iso
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
clean_iso: 
 | 
			
		||||
	if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi
 | 
			
		||||
	if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi
 | 
			
		||||
@ -30,19 +32,17 @@ clean_iso:
 | 
			
		||||
iso: clean_iso clean build
 | 
			
		||||
	mkdir -p root/boot/grub
 | 
			
		||||
	cp build/myos.bin root/boot/myos.bin
 | 
			
		||||
	cp source/grub.cfg root/boot/grub/grub.cfg
 | 
			
		||||
	cp src/grub.cfg root/boot/grub/grub.cfg
 | 
			
		||||
	grub-mkrescue -o build/barinkOS.iso root
 | 
			
		||||
	
 | 
			
		||||
run: all
 | 
			
		||||
	$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo
 | 
			
		||||
 | 
			
		||||
debug: all
 | 
			
		||||
	objcopy --only-keep-debug build/myos.bin kernel.sym
 | 
			
		||||
	$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int
 | 
			
		||||
test:
 | 
			
		||||
	$(EMULATOR)  -kernel $(BUILD_DIR)/myos.bin -serial mon:stdio -vga std  -display gtk -m 2G -cpu core2duo # -monitor stdio
 | 
			
		||||
test_iso:
 | 
			
		||||
	$(EMULATOR) -cdrom build/barinkOS.iso -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo
 | 
			
		||||
 | 
			
		||||
build_kernel: $(OBJ_LINK_LIST)
 | 
			
		||||
	$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
 | 
			
		||||
	 -ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc
 | 
			
		||||
	 -ffreestanding -O2 -nostdlib $(OBJ_LINK_LIST) -lgcc
 | 
			
		||||
 | 
			
		||||
build_x86_64: 
 | 
			
		||||
	$(AS) $(SRC_DIR)/cgc/x86_64/crti.s -o $(BUILD_DIR)/crti_64.o
 | 
			
		||||
@ -51,62 +51,48 @@ build_x86_64:
 | 
			
		||||
clean: 
 | 
			
		||||
	rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
 | 
			
		||||
 | 
			
		||||
# C++ definition -> Object files
 | 
			
		||||
$(BUILD_DIR)/kernel.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti -fpermissive
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/kterm.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/terminal/kterm.cpp  -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp  -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/io.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/io.cpp  -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/interrupts/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/gdtc.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/string.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/lib/string.cpp  -o $(BUILD_DIR)/string.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pit.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp  -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/keyboard.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/ps-2/keyboard.cpp  -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/time.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/time.cpp  -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/sv-terminal.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/supervisorterminal/superVisorTerminal.cpp  -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/memory.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp  -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/paging.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/KHeap.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/KernelHeap.cpp -o $(BUILD_DIR)/KHeap.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/prekernel.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/prekernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/cpu.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Assembly -> Object files
 | 
			
		||||
$(BUILD_DIR)/boot.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/crti.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/crtn.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/crtn.s -o $(BUILD_DIR)/crtn.o
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/io.o:
 | 
			
		||||
		$(CPP) -c $(SRC_DIR)/kernel/io.cpp  -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/PageDirectory.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti 
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/gdtc.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/string.o:
 | 
			
		||||
	$(CC) -c $(SRC_DIR)/libc/include/string.c  -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/PhysicalMemoryManager.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp  -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/vesa.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/vesa/vesa.cpp  -o $(BUILD_DIR)/vesa.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/window.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/gui/window.cpp  -o $(BUILD_DIR)/window.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/cursor.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/gui/cursor.cpp  -o $(BUILD_DIR)/cursor.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							@ -6,6 +6,9 @@
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
### Screenshot(s)
 | 
			
		||||
 \
 | 
			
		||||
It may not look like much but I am proud of it! We are in graphics mode.
 | 
			
		||||
 | 
			
		||||
   \
 | 
			
		||||
The first scrolling boot screen. 😲
 | 
			
		||||
 | 
			
		||||
@ -16,16 +19,10 @@ W.I.P - Working on interrupt handling
 | 
			
		||||
 | 
			
		||||
 \
 | 
			
		||||
Multiboot information can be read by the kernel.
 | 
			
		||||
 | 
			
		||||
 \
 | 
			
		||||
Enabled paging and am getting page faults!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
 | 
			
		||||
### The goal
 | 
			
		||||
Writing a hobby operating system to better understand the basic building blocks of any operating system.Initially I'd like for my 
 | 
			
		||||
operating system to be able to run bash.
 | 
			
		||||
Writing a hobby operating system to better understand the basic building blocks of any operating system.
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
### Operating System Technical specs/details
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								features.md
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								features.md
									
									
									
									
									
								
							@ -1,30 +1,29 @@
 | 
			
		||||
# TODO list 
 | 
			
		||||
## Basics
 | 
			
		||||
## Start planning
 | 
			
		||||
<input type="checkbox" checked/> Setup Cross-Compiler \
 | 
			
		||||
<input type="checkbox" checked/> Multiboot to kernel \
 | 
			
		||||
<input type="checkbox" checked/> Printing string to the screen \
 | 
			
		||||
<input type="checkbox" checked/> Printing values/numbers to the screen \
 | 
			
		||||
<input type="checkbox" checked/> Basic Terminal \
 | 
			
		||||
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
 | 
			
		||||
<input type="checkbox" checked/> Extend Multiboot implementation \
 | 
			
		||||
<input type="checkbox" checked/> Output to serial port \
 | 
			
		||||
<input type="checkbox" checked/> Move to protected mode \
 | 
			
		||||
<input type="checkbox" checked/> Enabel CMOS clock \
 | 
			
		||||
<input type="checkbox" checked/> Time measurement (PIC &| PIT) \
 | 
			
		||||
<input type="checkbox" /> Time measurement (PIC &| PIT) \
 | 
			
		||||
<input type="checkbox" /> Detect CPU speed \
 | 
			
		||||
<input type="checkbox" checked/> Interrupt / exception system (API) \
 | 
			
		||||
<input type="checkbox" checked/> PCI support \
 | 
			
		||||
<input type="checkbox" checked/> ATA PIO Mode support \
 | 
			
		||||
<input type="checkbox" checked/> FAT Filesystem \
 | 
			
		||||
<input type="checkbox" /> Virtual filesystem \
 | 
			
		||||
<input type="checkbox" checked/> Keyboard support ( P/S2 Keyboard) \
 | 
			
		||||
<input type="checkbox" checked/> Physical memory management \
 | 
			
		||||
<input type="checkbox" checked/>  Paging \
 | 
			
		||||
<input type="checkbox" checked/> Virtual memory management \
 | 
			
		||||
<input type="checkbox" checked/> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
 | 
			
		||||
 | 
			
		||||
<input type="checkbox" checked/> Plan your memory map (virtual, and physical) : decide where you want the data to be. \
 | 
			
		||||
<input type="checkbox" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
 | 
			
		||||
<input type="checkbox" /> Enable SIMD Extensions (SSE)
 | 
			
		||||
 | 
			
		||||
<input type="checkbox" /> Hardware Management system
 | 
			
		||||
 | 
			
		||||
## Other features I am thinking of:
 | 
			
		||||
<input type="checkbox" /> PCI support \
 | 
			
		||||
<input type="checkbox" /> ATA PIO Mode support \
 | 
			
		||||
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
 | 
			
		||||
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
 | 
			
		||||
<input type="checkbox" /> ATAPI support \
 | 
			
		||||
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
 | 
			
		||||
<input type="checkbox" checked/> Memory Management (MMU)   
 | 
			
		||||
<input type="checkbox" /> Preemptive multi tasking \
 | 
			
		||||
<input type="checkbox" /> Processes  \
 | 
			
		||||
<input type="checkbox" /> Threads  
 | 
			
		||||
@ -33,11 +32,9 @@
 | 
			
		||||
<input type="checkbox" /> POSIX compliance (partially) \
 | 
			
		||||
<input type="checkbox" /> RPC - for interprocess communication \
 | 
			
		||||
<input type="checkbox" /> Sync primitives  - Semaphores, Mutexes, spinlocks et al. \
 | 
			
		||||
 | 
			
		||||
<input type="checkbox" /> ACPI support  \
 | 
			
		||||
<input type="checkbox" /> ATAPI support \
 | 
			
		||||
 | 
			
		||||
## Optional 
 | 
			
		||||
<input type="checkbox" /> Basic Terminal \
 | 
			
		||||
<input type="checkbox" /> Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \
 | 
			
		||||
<input type="checkbox" /> Basic Window server/client \
 | 
			
		||||
## Support for more filesystems if I like the challenge in writing these ...
 | 
			
		||||
<input type="checkbox" /> FAT Filesystem \
 | 
			
		||||
<input type="checkbox" /> EXT2 Filesystem 
 | 
			
		||||
<input type="checkbox" /> USTAR Filesystem \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS_logo(standard).svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS_logo(standard).svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS_logo.svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS_logo.svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								screenshots/BarinkOS_VBE_GRAPHICS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/BarinkOS_VBE_GRAPHICS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								screenshots/PageFault.png
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/PageFault.png
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								screenshots/must frustrating bug ever.png
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/must frustrating bug ever.png
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@ -1,3 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
cmake -DLLVM_ENABLE_PROJECTS="clang-tools-extra"  -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ../llvm
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Run clang-tidy 
 | 
			
		||||
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
menuentry "BarinkOS" {
 | 
			
		||||
    multiboot /boot/myos.bin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menuentry "BarinkOS Tests" {
 | 
			
		||||
    multiboot /boot/myos.bin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryAllocatorTest()
 | 
			
		||||
{
 | 
			
		||||
    #ifdef UNIT_TESTS
 | 
			
		||||
        // Small test!
 | 
			
		||||
        void* block = allocate_block();
 | 
			
		||||
        void* block2 = allocate_block();
 | 
			
		||||
        printf("Allocated addresss 1: 0x%x 2: 0x%x\n", (uint32_t)block ,(uint32_t)block2);
 | 
			
		||||
        free_block(block);
 | 
			
		||||
        free_block(block2);
 | 
			
		||||
        void* block3 = allocate_block();
 | 
			
		||||
        printf("Allocated addresss 3: 0x%x\n", (uint32_t)block3);
 | 
			
		||||
        free_block(block3);
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
 | 
			
		||||
void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
        kterm_writestring("Writing to COM1 serial port:");
 | 
			
		||||
        init_serial();
 | 
			
		||||
        write_serial('A');
 | 
			
		||||
        write_serial('B');
 | 
			
		||||
        write_serial('C');
 | 
			
		||||
        write_serial('D');
 | 
			
		||||
        write_serial('E');
 | 
			
		||||
 | 
			
		||||
        char Character_received = read_serial();
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
        kterm_writestring("received from COM 1: \n");
 | 
			
		||||
        kterm_put(Character_received);
 | 
			
		||||
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
@ -1,38 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
inline void bitmap_set( uint32_t* map , int index )
 | 
			
		||||
{
 | 
			
		||||
    map[index/32] |= (1 << (index % 32));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void bitmap_unset(uint32_t* map , int index)
 | 
			
		||||
{
 | 
			
		||||
    map[index/32] &= ~(1 << (index % 32));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t bitmap_first_unset( uint32_t* map , int map_size)
 | 
			
		||||
{
 | 
			
		||||
    for ( int i = 0 ; i < map_size ; i ++ )
 | 
			
		||||
    {
 | 
			
		||||
        // a bit or more is set within this byte!
 | 
			
		||||
        if( (map[i] & 0xFFFFFFFF) > 0 ){
 | 
			
		||||
 | 
			
		||||
            // which bit is set? 
 | 
			
		||||
            for(int j = 0 ; j < 32 ; j++){
 | 
			
		||||
                if ( (map[i] & (0x00000001 << j)) > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    return (i*32)+j;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@ -1,113 +0,0 @@
 | 
			
		||||
.include "./source/kernel/boot/multiboot.s"
 | 
			
		||||
/*
 | 
			
		||||
*	Allocate initial stack
 | 
			
		||||
*/
 | 
			
		||||
.section .bootstrap_stack, "aw", @nobits
 | 
			
		||||
stack_bottom:
 | 
			
		||||
.skip 16384 # 16 KiB
 | 
			
		||||
stack_top:
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Preallocate a couple pages to get us bootstrapped 
 | 
			
		||||
* Being carefull to not use any address the bootloader might 
 | 
			
		||||
* be using for its multiboot structures
 | 
			
		||||
*/
 | 
			
		||||
.section .bss, "aw", @nobits
 | 
			
		||||
	.align 4096
 | 
			
		||||
.globl boot_page_directory
 | 
			
		||||
boot_page_directory:
 | 
			
		||||
	.skip 4096
 | 
			
		||||
.globl boot_page_table
 | 
			
		||||
boot_page_table:
 | 
			
		||||
	.skip 4096
 | 
			
		||||
.globl multiboot_page_table
 | 
			
		||||
multiboot_page_table:
 | 
			
		||||
	.skip 4096
 | 
			
		||||
# More page tables may be required
 | 
			
		||||
 | 
			
		||||
# Entry point
 | 
			
		||||
.section .multiboot.text, "a"
 | 
			
		||||
.globl _start
 | 
			
		||||
.type _start, @function 
 | 
			
		||||
_start:
 | 
			
		||||
 | 
			
		||||
	# Get physical address of the boot_page_table
 | 
			
		||||
	movl $(boot_page_table - 0xC0000000), %edi
 | 
			
		||||
	# Map address 0
 | 
			
		||||
	movl $0, %esi
 | 
			
		||||
1:	
 | 
			
		||||
	cmpl $(_kernel_end - 0xC0000000), %esi
 | 
			
		||||
	jge 3f
 | 
			
		||||
 | 
			
		||||
	# Map physical address as "present and writable"
 | 
			
		||||
	movl %esi, %edx
 | 
			
		||||
	orl $0x003, %edx
 | 
			
		||||
	movl %edx, (%edi)
 | 
			
		||||
 | 
			
		||||
2: # Size of page is 4096 bytes
 | 
			
		||||
	addl $4096, %esi
 | 
			
		||||
	# Size of entries in boot_page_table is 4 bytes
 | 
			
		||||
	addl $4, %edi 
 | 
			
		||||
	# Loop to the next entry if we haven't finished.
 | 
			
		||||
	loop 1b
 | 
			
		||||
 | 
			
		||||
3:	# Map VGA video memory to 0xC03FF00 as "present, writable"
 | 
			
		||||
	movl $(0x000B8000 | 0x003), boot_page_table - 0xC0000000 + 1023 * 4
 | 
			
		||||
 | 
			
		||||
	# Map the page table to both virtual addresss 0x00000000 and 0xC0000000
 | 
			
		||||
	movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
 | 
			
		||||
	movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
 | 
			
		||||
 | 
			
		||||
	# Set cr3 to the address of the boot_page_directory
 | 
			
		||||
	movl $(boot_page_directory - 0xC0000000), %ecx
 | 
			
		||||
	movl %ecx, %cr3
 | 
			
		||||
 | 
			
		||||
	# Enable paging and the write-protect bit
 | 
			
		||||
	movl %cr0, %ecx
 | 
			
		||||
	orl $0x80010000, %ecx
 | 
			
		||||
	movl %ecx, %cr0
 | 
			
		||||
 | 
			
		||||
	# Jump to higher half with an absolute jump
 | 
			
		||||
	lea 4f, %ecx
 | 
			
		||||
	jmp *%ecx
 | 
			
		||||
 | 
			
		||||
.section .text
 | 
			
		||||
4:
 | 
			
		||||
	# At this point, paging is fully set up and enabled
 | 
			
		||||
isPaging:
 | 
			
		||||
	/* push the pointer to the Multiboot information structure*/
 | 
			
		||||
	pushl %ebx
 | 
			
		||||
 | 
			
		||||
	/* push the magic value */
 | 
			
		||||
	pushl %eax
 | 
			
		||||
	call prekernelSetup
 | 
			
		||||
 | 
			
		||||
	# Unmap the identity mapping as it is now unnecessary  
 | 
			
		||||
	movl $0, boot_page_directory + 0
 | 
			
		||||
	
 | 
			
		||||
	# Reload cr3 to force tlb flush 
 | 
			
		||||
	movl %cr3, %ecx
 | 
			
		||||
	movl %ecx, %cr3
 | 
			
		||||
 | 
			
		||||
	/*Setup the stack pointer to point to the beginning of our stack */
 | 
			
		||||
	/* I believe its a high address growing down to lower adress for the stack on x86*/
 | 
			
		||||
	mov $stack_top, %esp
 | 
			
		||||
 | 
			
		||||
	/*Reset EFLAGS*/
 | 
			
		||||
	pushl $0 
 | 
			
		||||
	popf 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	call early_main
 | 
			
		||||
 | 
			
		||||
	cli
 | 
			
		||||
1:	hlt
 | 
			
		||||
	jmp 1b
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.include "./source/kernel/memory/gdt/gdt.s"
 | 
			
		||||
.include "./source/kernel/irs_table.s"
 | 
			
		||||
.include "./source/kernel/irq_table.s"
 | 
			
		||||
.include "./source/kernel/interrupts/idt/idt.s"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Multiboot 
 | 
			
		||||
 */
 | 
			
		||||
.set ALIGN,    1<<0             /* align loaded modules on page boundaries */
 | 
			
		||||
.set MEMINFO,  1<<1             /* provide memory map */
 | 
			
		||||
.set FLAGS,    ALIGN | MEMINFO  /* this is the Multiboot 'flag' field */
 | 
			
		||||
.set MAGIC,    0x1BADB002       /* 'magic number' lets bootloader find the header */
 | 
			
		||||
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
 | 
			
		||||
 | 
			
		||||
.section .multiboot.data, "aw"
 | 
			
		||||
.align 4
 | 
			
		||||
.long MAGIC
 | 
			
		||||
.long FLAGS
 | 
			
		||||
.long CHECKSUM
 | 
			
		||||
 
 | 
			
		||||
@ -1,39 +0,0 @@
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t GetEFLAGS()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t EFLAGS = 0;
 | 
			
		||||
    asm volatile ("pushfl;" "movl 4(%%esp), %%edx" : "=d"(EFLAGS));
 | 
			
		||||
    return EFLAGS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR0()
 | 
			
		||||
{   
 | 
			
		||||
    uint32_t cr0_value;
 | 
			
		||||
    asm volatile ("movl %%cr0, %%edx" : "=d"(cr0_value));
 | 
			
		||||
    return cr0_value;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR2(){
 | 
			
		||||
    uint32_t cr2_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr2, %%edx": "=d"(cr2_value));
 | 
			
		||||
    return cr2_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR3(){
 | 
			
		||||
    uint32_t cr3_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr3, %%edx": "=d"(cr3_value));
 | 
			
		||||
    return cr3_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR4(){
 | 
			
		||||
    uint32_t cr4_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr4, %%edx": "=d"(cr4_value));
 | 
			
		||||
    return cr4_value;
 | 
			
		||||
}
 | 
			
		||||
@ -1,74 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Based on Intel specifications.
 | 
			
		||||
 | 
			
		||||
C++ interface for the cpu.s assembly file.
 | 
			
		||||
 | 
			
		||||
©Nigel Barink - 2022 
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
*       EFLAGS FUNCTIONS
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
uint32_t GetEFLAGS();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
*       CONTROL_REGISTER_0 FUNCTIONS
 | 
			
		||||
*/
 | 
			
		||||
uint32_t GetCR0();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 struct CR0_Register  {
 | 
			
		||||
        uint8_t PE :1; // Protection Mode Enabled 0
 | 
			
		||||
        uint8_t MP :1; // Monitor co-processor 1
 | 
			
		||||
        uint8_t EM :1; // Emulation 2
 | 
			
		||||
        uint8_t TS :1; // Task switched 3
 | 
			
		||||
        uint8_t ET :1; // Extension Type 4
 | 
			
		||||
        uint8_t NE :1; // Numeric error 5
 | 
			
		||||
        uint16_t Reserved :10; // 6,7,8,9,10,11,12,13,14,15
 | 
			
		||||
        uint8_t WP :1; // Write Protect 16
 | 
			
		||||
        uint8_t Reserved :1; // 17
 | 
			
		||||
        uint8_t AM :1; // Alligment Task 18
 | 
			
		||||
        uint16_t Reserved :10; // 19,20,21,22,23,24,25,26,27,28
 | 
			
		||||
        uint8_t NW :1; // Not-write through 29
 | 
			
		||||
        uint8_t CD :1; // Cache disable 30
 | 
			
		||||
        uint8_t PG :1; // Paging 31
 | 
			
		||||
    };*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define GET_PE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x1)
 | 
			
		||||
#define GET_MP_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x2)
 | 
			
		||||
#define GET_EM_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x3)
 | 
			
		||||
#define GET_TS_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x4)
 | 
			
		||||
#define GET_ET_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x5)
 | 
			
		||||
#define GET_NE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x6)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define GET_PG_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0>>31)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
*       CONTROL_REGISTER_4 FUNCTIONS
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR4();
 | 
			
		||||
 | 
			
		||||
#define GET_PSE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x4)
 | 
			
		||||
#define GET_PAE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x5)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
*       CONTROL_REGISTER_2 FUNCTIONS
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR2();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
*       CONTROL_REGISTER_3 FUNCTIONS
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
uint32_t GetCR3();
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
/**
 | 
			
		||||
 * Kernel definitions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __DEBUG__ false
 | 
			
		||||
#define KERNEL_VERSION 0
 | 
			
		||||
 | 
			
		||||
#define ARCHITECTURE "I386"
 | 
			
		||||
@ -1,38 +0,0 @@
 | 
			
		||||
void ReadFromCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
    unsigned char tvalue, index;
 | 
			
		||||
 | 
			
		||||
    for (index = 0; index < 128; index++)
 | 
			
		||||
    {
 | 
			
		||||
        asm(
 | 
			
		||||
            "cli\n\t"           // Disable interrupts
 | 
			
		||||
            "mov al, index\n\t" // Move index address
 | 
			
		||||
            // since the 0x80 bit of al is not set, NMI is active 
 | 
			
		||||
            "out 0x70,al\n\t" // Copy address to CMOS register
 | 
			
		||||
            // some kind of real delay here is probably best 
 | 
			
		||||
            "in al,0x71\n\t" // Fetch 1 byte to al
 | 
			
		||||
            "sti\n\t"        // Enable interrupts
 | 
			
		||||
            "mov tvalue,al\n\t");
 | 
			
		||||
 | 
			
		||||
        array[index] = tvalue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteTOCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
   unsigned char index;
 | 
			
		||||
 
 | 
			
		||||
   for(index = 0; index < 128; index++)
 | 
			
		||||
   {
 | 
			
		||||
      unsigned char tvalue = array[index];
 | 
			
		||||
      
 | 
			
		||||
       asm("cli\n\t"       // Clear interrupts
 | 
			
		||||
         "mov al,index\n\t"    // move index address
 | 
			
		||||
         "out 0x70,al\n\t"     // copy address to CMOS register
 | 
			
		||||
         // some kind of real delay here is probably best 
 | 
			
		||||
         "mov al,tvalue\n\t"   // move value to al
 | 
			
		||||
         "out 0x71,al\n\t"   // write 1 byte to CMOS
 | 
			
		||||
         "sti\n\\t"   );        // Enable interrupts
 | 
			
		||||
      
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
#include "pit.h"
 | 
			
		||||
 | 
			
		||||
uint32_t pit_tick = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void pit_initialise()
 | 
			
		||||
{
 | 
			
		||||
    asm volatile("CLI");
 | 
			
		||||
 | 
			
		||||
#ifdef __VERBOSE__
 | 
			
		||||
    printf("Init PIT!\n");
 | 
			
		||||
#endif
 | 
			
		||||
    // clear mask for IRQ 0 
 | 
			
		||||
    uint8_t value = inb(0x21) & ~(1<< 0);
 | 
			
		||||
    outb(0x21, value);
 | 
			
		||||
 | 
			
		||||
    io_wait();
 | 
			
		||||
 | 
			
		||||
    const int freq = 500;
 | 
			
		||||
 | 
			
		||||
    uint32_t divisor = 1193180 / freq;
 | 
			
		||||
 | 
			
		||||
    outb(PIT_COMMAND, 0x36);
 | 
			
		||||
 | 
			
		||||
    uint8_t l = (uint8_t) (divisor & 0xFF);
 | 
			
		||||
    uint8_t h = (uint8_t) ( (divisor>>8) & 0xff);
 | 
			
		||||
 | 
			
		||||
    outb(PIT_DATA_0, l);
 | 
			
		||||
    outb(PIT_DATA_0,h);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    asm volatile("STI");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void get_pit_count()
 | 
			
		||||
{
 | 
			
		||||
    asm volatile ("CLI");
 | 
			
		||||
 | 
			
		||||
    outb(PIT_COMMAND, 0);
 | 
			
		||||
    uint16_t count = inb(PIT_DATA_0);
 | 
			
		||||
    count |= inb(PIT_DATA_0) << 8;
 | 
			
		||||
 | 
			
		||||
    printf("PIT count: 0x%x\n", count); 
 | 
			
		||||
 | 
			
		||||
    asm volatile("STI");   
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pit_count()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../../io.h"
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#define PIT_DATA_0 0x40
 | 
			
		||||
#define PIT_DATA_1 0x41
 | 
			
		||||
#define PIT_DATA_2 0x42
 | 
			
		||||
#define PIT_COMMAND 0x43
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern uint32_t pit_tick;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void pit_initialise();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void get_pit_count();
 | 
			
		||||
 | 
			
		||||
void set_pit_count();
 | 
			
		||||
@ -1,51 +0,0 @@
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
 | 
			
		||||
KeyPressInfo keyPress {};
 | 
			
		||||
 | 
			
		||||
void KeyHandled(){
 | 
			
		||||
    keyPress.ScanCode= 0x00;
 | 
			
		||||
    keyPress.PressedModifiers = 0x00;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char getASCIIKey(){
 | 
			
		||||
    char keyPressed;
 | 
			
		||||
    // Wait until a key is pressed  
 | 
			
		||||
    while(keyPress.ScanCode == 0x00) {
 | 
			
		||||
        asm volatile ("NOP");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    // Translate keycode to ascii 
 | 
			
		||||
    // Probably a lookup table might be handy 
 | 
			
		||||
    // Until 0x37
 | 
			
		||||
     const char* ASCIILookUp =
 | 
			
		||||
      "\01234567890-=\0\0QWERTYUIOP[]\0\0ASDFGHJKL;\'`\0\\ZXCVBNM,./\0"; 
 | 
			
		||||
     
 | 
			
		||||
     uint8_t ASCII_Index = keyPress.ScanCode - 3  ;
 | 
			
		||||
     //printf("ASCII_INDEX: %x\n", ASCII_Index);
 | 
			
		||||
     keyPressed = ASCIILookUp[ASCII_Index];
 | 
			
		||||
 | 
			
		||||
    KeyHandled();
 | 
			
		||||
 | 
			
		||||
    return keyPressed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t getKey(){
 | 
			
		||||
    // Wait until a key is pressed 
 | 
			
		||||
    while(keyPress.ScanCode == 0x00){
 | 
			
		||||
        asm volatile ("NOP");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if( keyPress.ScanCode > 0x37){
 | 
			
		||||
        keyPress.ScanCode = 0x00;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t ScanCode = keyPress.ScanCode;
 | 
			
		||||
   // KeyHandled();
 | 
			
		||||
 | 
			
		||||
    return  ScanCode ;
 | 
			
		||||
}
 | 
			
		||||
@ -1,34 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
enum ScanCodeSet {
 | 
			
		||||
    None            =   0,
 | 
			
		||||
    ScanCodeSet1    =   1,
 | 
			
		||||
    ScanCodeSet2    =   2,
 | 
			
		||||
    ScanCodeSet3    =   3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum Modifiers {
 | 
			
		||||
    LSHIFT  =   1,
 | 
			
		||||
    RSHIFT  =   2,
 | 
			
		||||
 | 
			
		||||
    LCTRL   =   3,
 | 
			
		||||
    RCTRL   =   4,
 | 
			
		||||
 | 
			
		||||
    LALT    =   5,
 | 
			
		||||
    RALT    =   6
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct KeyPressInfo{ 
 | 
			
		||||
    uint8_t PressedModifiers;
 | 
			
		||||
    uint8_t ScanCode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern KeyPressInfo keyPress;
 | 
			
		||||
 | 
			
		||||
void KeyHandled();
 | 
			
		||||
 | 
			
		||||
char getASCIIKey();
 | 
			
		||||
uint8_t getKey();
 | 
			
		||||
@ -1,8 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../../vfs/File.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FAT16 : File  {
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
@ -1,395 +0,0 @@
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
#include "../../drivers/pit/pit.h"
 | 
			
		||||
#include "../../drivers/ps-2/keyboard.h"
 | 
			
		||||
#include "../../cpu.h"
 | 
			
		||||
IDT_entry idt_table[256];
 | 
			
		||||
IDT_ptr idt_ptr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void set_id_entry (uint8_t num , uint32_t base, uint16_t sel,  uint8_t flags){
 | 
			
		||||
    idt_table[num].offset_1 = base & 0xFFFF;
 | 
			
		||||
    idt_table[num].selector = sel;
 | 
			
		||||
    idt_table[num].zero = 0;
 | 
			
		||||
    idt_table[num].type_attr = flags;
 | 
			
		||||
    idt_table[num].offset_2 = (base >> 16) & 0xFFFF;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void irs_handler (registers regs) {
 | 
			
		||||
     uint32_t FaultingAddress;
 | 
			
		||||
        //printf("(IRS) Interrupt number: %d \r", regs.int_no);
 | 
			
		||||
        switch (regs.int_no)
 | 
			
		||||
        {
 | 
			
		||||
        case 0:
 | 
			
		||||
            // Divide Error #DE
 | 
			
		||||
            printf("#DE\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 1:
 | 
			
		||||
            // Debug Exception #DB
 | 
			
		||||
            printf("#DB\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 2:
 | 
			
		||||
            // NMI Interrupt 
 | 
			
		||||
            printf("#NMI\n");
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 3:
 | 
			
		||||
            // Breakpoint Exception #BP
 | 
			
		||||
            printf("#BP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 4:
 | 
			
		||||
            // Overflow Exception #OF
 | 
			
		||||
            printf("#OF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 5:
 | 
			
		||||
            // BOUND Range Exceeded Exception #BR
 | 
			
		||||
            printf("#BR\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 6:
 | 
			
		||||
            // Invalid OpCode Exception #UD 
 | 
			
		||||
            printf("#UD\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 7:
 | 
			
		||||
            // Device Not Available Exception  #NM
 | 
			
		||||
            printf("#NM\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 8:
 | 
			
		||||
            // Double Fault Exception #DF
 | 
			
		||||
            printf("#DF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 9:
 | 
			
		||||
            // Coprocessor Segment Overrun
 | 
			
		||||
            printf("Coprocessor Segment overrun!\n");
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 10:
 | 
			
		||||
            // Invalid TSS Exception #TS
 | 
			
		||||
            printf("#TS\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 11:
 | 
			
		||||
            // Segment Not Present #NP
 | 
			
		||||
            printf("#NP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 12:
 | 
			
		||||
            // Stack Fault Exception #SS
 | 
			
		||||
            printf("#SS\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 13:
 | 
			
		||||
            // General Protection Exception #GP
 | 
			
		||||
            printf("#GP\n");
 | 
			
		||||
 | 
			
		||||
            printf("Accessing memory caused a general protectuion exception.\n");
 | 
			
		||||
            
 | 
			
		||||
            printf("Fault due to entry at index: %d", (regs.err_code >> 3 & 0xFFF ) );
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 0   ){
 | 
			
		||||
                printf("* Index references GDT");
 | 
			
		||||
            }
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 1  ){
 | 
			
		||||
                printf("* Index references IDT");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 2   ){
 | 
			
		||||
                printf("* Index references LDT");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 4  ){
 | 
			
		||||
                printf("* Index references IDT");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if( regs.err_code & 0x1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("* Originated externally!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            __asm__("cli;" "1: hlt;" "jmp 1b;");
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 14:
 | 
			
		||||
            // Page Fault Exception #PF
 | 
			
		||||
            printf("#PF\n");
 | 
			
		||||
 | 
			
		||||
            FaultingAddress = GetCR2();
 | 
			
		||||
            printf("Accessing the linear address 0x%x resulted in a page fault!\n\n", FaultingAddress);
 | 
			
		||||
        
 | 
			
		||||
            // Error code of 32 bits are on the stack
 | 
			
		||||
            // CR2 register contains the 32-bit linear virtual address that generated the exception
 | 
			
		||||
            // See Intel Software Developers manual Volume 3A Part 1 page 236 for more info
 | 
			
		||||
            #define PF_ERR_PRESENT_BIT 0x1
 | 
			
		||||
            #define PF_ERR_WRITE_BIT 0x2
 | 
			
		||||
            #define PF_ERR_USER_BIT 0x3
 | 
			
		||||
            #define PF_ERR_RESERVERD_WRITE_BIT 0x4
 | 
			
		||||
            #define PF_ERR_INSTRUCTION_FETCH_BIT 0x5
 | 
			
		||||
            #define PF_ERR_PROTECTION_KEY_BIT 0x6
 | 
			
		||||
            #define PF_ERR_SHADOW_STACK_BIT 0x7
 | 
			
		||||
            #define PF_ERR_SOFTWARE_GUARD_EXTENSION_BIT 0xE
 | 
			
		||||
 | 
			
		||||
            printf("REASON: \n\n");
 | 
			
		||||
 | 
			
		||||
         
 | 
			
		||||
            if (regs.err_code & PF_ERR_PRESENT_BIT ){
 | 
			
		||||
                printf("* Page protection violation!\n");
 | 
			
		||||
            } else{
 | 
			
		||||
                printf("* Page not-present!\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_WRITE_BIT){
 | 
			
		||||
                printf("* Write access violation!\n");
 | 
			
		||||
            } else{
 | 
			
		||||
                printf("* Read access violation!\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_USER_BIT){
 | 
			
		||||
                printf("* Violation from user-space (CPL=3)\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
 | 
			
		||||
                printf("* Caused by an instruction fetch. \n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
                Check the error code to figure out what happened here
 | 
			
		||||
            */
 | 
			
		||||
            __asm__("cli;" "1: hlt;" "jmp 1b;");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
    
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 16:
 | 
			
		||||
            // x87 FPU Floating-point Error #MF
 | 
			
		||||
            printf("#MF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 17:
 | 
			
		||||
            // Alignment Check Exception #AC
 | 
			
		||||
            printf("#AC\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 18:
 | 
			
		||||
            // Machine-Check Exception #MC
 | 
			
		||||
            printf("#MC\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 19:
 | 
			
		||||
            // SIMD Floating-point Exception #XM
 | 
			
		||||
            printf("#XM\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 20:
 | 
			
		||||
             // Virtualization Exception #VE
 | 
			
		||||
            printf("#VE\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 21:
 | 
			
		||||
             // Control Protection Exception #CP
 | 
			
		||||
            printf("#CP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            // PANIC!!!
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
        
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void irq_handler (registers regs) {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    switch (regs.int_no) {
 | 
			
		||||
    case 0:
 | 
			
		||||
            pit_tick++;
 | 
			
		||||
        break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        // Keyboard interrupt !!
 | 
			
		||||
 | 
			
		||||
        int scan;
 | 
			
		||||
        int i;/*register*/
 | 
			
		||||
 | 
			
		||||
        // Read scancode 
 | 
			
		||||
        scan = inb(0x60);
 | 
			
		||||
        
 | 
			
		||||
        // Send ack message!
 | 
			
		||||
        i = inb(0x61);
 | 
			
		||||
        outb(0x61, i|0x80);
 | 
			
		||||
        outb(0x61, i);
 | 
			
		||||
 | 
			
		||||
        // NOTE: check for special scan codes 
 | 
			
		||||
        // e.g. modifiers etc..
 | 
			
		||||
        if( scan < 0x37){
 | 
			
		||||
            //printf("Read from IO: 0x%x\n", scan);
 | 
			
		||||
            keyPress.ScanCode = scan ;
 | 
			
		||||
            //printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        break;    
 | 
			
		||||
    case 12:
 | 
			
		||||
        // PS2 Mouse interrupt 
 | 
			
		||||
        printf("Mouse event triggered!");
 | 
			
		||||
        //int event = inb(0x60);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        printf("Interrupt happened!");
 | 
			
		||||
        printf("Received INT: 0x%x\n", regs.int_no);
 | 
			
		||||
        break;
 | 
			
		||||
    }        
 | 
			
		||||
 | 
			
		||||
    outb(0x20, 0x20); // send end of interrupt to master
 | 
			
		||||
 | 
			
		||||
    if ( regs.int_no > 8 && regs.int_no <= 15) {
 | 
			
		||||
        outb(0xA0, 0x20); // send end of interrupt to slave 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    if( regs.int_no == 13){
 | 
			
		||||
        printf(" Error code: %d \n", regs.err_code);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_idt(){
 | 
			
		||||
    // Initialise the IDT pointer
 | 
			
		||||
    idt_ptr.length = sizeof(IDT_entry) * 255;
 | 
			
		||||
    idt_ptr.base = (uint32_t)&idt_table;
 | 
			
		||||
 | 
			
		||||
#ifdef __VERBOSE__
 | 
			
		||||
    printf("Init IDT\n");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // TODO: Set everything to zero first
 | 
			
		||||
 | 
			
		||||
    set_id_entry(0,  (uint32_t) irs0 , 0x08, 0x8F);
 | 
			
		||||
    set_id_entry(1,  (uint32_t) irs1 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(2,  (uint32_t) irs2 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(3,  (uint32_t) irs3 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(4,  (uint32_t) irs4 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(5,  (uint32_t) irs5 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(6,  (uint32_t) irs6 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(7,  (uint32_t) irs7 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(8,  (uint32_t) irs8 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(9,  (uint32_t) irs9 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); 
 | 
			
		||||
    set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); 
 | 
			
		||||
    set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //print_serial("Remapping PIC\n");
 | 
			
		||||
    PIC_remap(0x20, 0x28);
 | 
			
		||||
 | 
			
		||||
    // clear mask for IRQ 12
 | 
			
		||||
    uint8_t value = inb(0x21) & ~(1<< 12);
 | 
			
		||||
    outb(0x21, value);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // pic IRQ Table
 | 
			
		||||
    set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); // PS2 Keyboard
 | 
			
		||||
    set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); // PS2 Mouse
 | 
			
		||||
    set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    idt_flush((uint32_t)&idt_ptr);
 | 
			
		||||
}
 | 
			
		||||
@ -1,85 +0,0 @@
 | 
			
		||||
#include "lib/string.h" 
 | 
			
		||||
#include "definitions.h"
 | 
			
		||||
 | 
			
		||||
#include "prekernel/bootstructure.h"
 | 
			
		||||
 | 
			
		||||
#include "drivers/vga/VBE.h"
 | 
			
		||||
#include "drivers/pit/pit.h"
 | 
			
		||||
 | 
			
		||||
#include "memory/PhysicalMemoryManager.h"
 | 
			
		||||
#include "memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "memory/KernelHeap.h"
 | 
			
		||||
#include "memory/gdt/gdtc.h"
 | 
			
		||||
 | 
			
		||||
#include "interrupts/idt/idt.h"
 | 
			
		||||
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "serial.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
 | 
			
		||||
#include "terminal/kterm.h"
 | 
			
		||||
 | 
			
		||||
#include "supervisorterminal/superVisorTerminal.h"
 | 
			
		||||
 | 
			
		||||
extern "C" void kernel_main ();
 | 
			
		||||
void ProcessBootInfo();
 | 
			
		||||
 | 
			
		||||
extern "C" void kernel_main ()
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Show a little banner for cuteness
 | 
			
		||||
     */
 | 
			
		||||
    printf("|===    BarinkOS       ===|\n");
 | 
			
		||||
    startSuperVisorTerminal();
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" void early_main()
 | 
			
		||||
{
 | 
			
		||||
    init_serial();
 | 
			
		||||
 | 
			
		||||
    kterm_init();
 | 
			
		||||
    printf("Allocated blocks: 0x%x \n", GetUsedBlocks());
 | 
			
		||||
 | 
			
		||||
    initGDT();
 | 
			
		||||
    init_idt();
 | 
			
		||||
 | 
			
		||||
    // Enable interrupts
 | 
			
		||||
    asm volatile("STI");
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
    initHeap();
 | 
			
		||||
 | 
			
		||||
    printf("TRY ALLOCATING 4 BYTES\n");
 | 
			
		||||
    uint32_t* MyVariable = (uint32_t*) malloc(4); // allocate 4 bytes using my heap
 | 
			
		||||
    free(MyVariable);
 | 
			
		||||
 | 
			
		||||
    // test heap allocation
 | 
			
		||||
    
 | 
			
		||||
    struct KernelInfo {
 | 
			
		||||
        int bar;
 | 
			
		||||
        bool foo;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    KernelInfo* MyInfo = (KernelInfo*) malloc(sizeof(KernelInfo));
 | 
			
		||||
 | 
			
		||||
    MyInfo->bar = 6;
 | 
			
		||||
    MyInfo->foo = false;
 | 
			
		||||
    printf("bar contains %d\n", MyInfo->bar);
 | 
			
		||||
    free(MyInfo);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("Enable Protected mode and jump to kernel main\n");
 | 
			
		||||
 | 
			
		||||
	asm volatile("mov %cr0, %eax ");
 | 
			
		||||
    asm volatile("or $1, %eax");
 | 
			
		||||
    asm volatile("mov %eax, %cr0"); // re-enable protected mode ? 
 | 
			
		||||
 | 
			
		||||
    pit_initialise();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    kernel_main();
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
#include "string.h"
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char* str) {
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
    while(str[len]){
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num ){
 | 
			
		||||
    for( int i = 0; i < num ; i++){
 | 
			
		||||
        
 | 
			
		||||
        if( str1[i] < str2[i]){
 | 
			
		||||
            return -1;
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        if( str1[i] > str2[i] ){
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -1,42 +0,0 @@
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
 
 | 
			
		||||
/* Tell where the various sections of the object files will be put in the final
 | 
			
		||||
   kernel image. */
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
	. = 0x00100000;  /* place code at 1MB mark*/
 | 
			
		||||
 
 | 
			
		||||
	_kernel_start	= .;
 | 
			
		||||
	kernel_begin	= .; /*  For legacy reasons */
 | 
			
		||||
	
 | 
			
		||||
	.multiboot.data : {
 | 
			
		||||
		*(.multiboot.data)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.multiboot.text : {
 | 
			
		||||
		*(multiboot.text)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	. += 0xC0000000; /* Addresses in the following code need to be above the 3Gb mark */
 | 
			
		||||
	.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
		*(.text)
 | 
			
		||||
	}
 | 
			
		||||
	.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
		*(.rodata)
 | 
			
		||||
	}
 | 
			
		||||
	.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
		*(.data)
 | 
			
		||||
	}
 | 
			
		||||
	.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
		*(COMMON)
 | 
			
		||||
		*(.bss)
 | 
			
		||||
		*(.bootstrap_stack)
 | 
			
		||||
	}
 | 
			
		||||
	_kernel_end = .;
 | 
			
		||||
	kernel_end = .; /* For legacy reasons */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,88 +0,0 @@
 | 
			
		||||
#include "KernelHeap.h"
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
// Size of heap meta data is 5 bytes 
 | 
			
		||||
struct heap_block{
 | 
			
		||||
    uint8_t Used;
 | 
			
		||||
    uint32_t Size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
uint32_t heap_size;
 | 
			
		||||
heap_block* start ;
 | 
			
		||||
 | 
			
		||||
void* malloc(size_t size)
 | 
			
		||||
{
 | 
			
		||||
    printf("Received request for %d bytes of memory\n", size);
 | 
			
		||||
    heap_block* current = start;
 | 
			
		||||
 | 
			
		||||
    // look for a free block
 | 
			
		||||
    while(current <  start + heap_size)
 | 
			
		||||
    {
 | 
			
		||||
        if(current->Size >= size && current->Used == false )
 | 
			
		||||
        {
 | 
			
		||||
            // We found a spot 
 | 
			
		||||
            printf("Block found!\n");
 | 
			
		||||
 | 
			
		||||
            // Set the spot to in-use 
 | 
			
		||||
            current->Used = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // split the block 
 | 
			
		||||
            printf("Split block.\n");
 | 
			
		||||
            uint32_t oldSize = current->Size;
 | 
			
		||||
            current->Size = size;
 | 
			
		||||
 | 
			
		||||
            heap_block* new_block = current + sizeof(heap_block) + current->Size;
 | 
			
		||||
            new_block->Size = oldSize - ( sizeof(heap_block) + size);
 | 
			
		||||
            new_block->Used = false;
 | 
			
		||||
 | 
			
		||||
            // return the free address 
 | 
			
		||||
            // NOTE: added an offset from the initial address to accomodate for 
 | 
			
		||||
            // meta-data.
 | 
			
		||||
            return current + sizeof(heap_block);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        current += current->Size + sizeof(heap_block);
 | 
			
		||||
    }   
 | 
			
		||||
 | 
			
		||||
    // If we are here we need more memory so we should 
 | 
			
		||||
    // probably ask the VMM for more 
 | 
			
		||||
    // TODO: ask for more memory | Extend kernel heap
 | 
			
		||||
    
 | 
			
		||||
    printf("ERROR: OUT OF HEAP MEMORY CONDITION IS NOT IMPLEMENTED. HEAP NEEDS TO BE EXTENDED!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free(void* addr)
 | 
			
		||||
{
 | 
			
		||||
    // clear the free boolean that corresponds to this adddress
 | 
			
		||||
    // This should be fairly simple
 | 
			
		||||
    heap_block* allocatedBlock = (heap_block*)(addr - sizeof(heap_block));
 | 
			
		||||
    allocatedBlock->Used = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void initHeap()
 | 
			
		||||
{
 | 
			
		||||
    // put the start of our kernel heap 1 page after the kernel_end address
 | 
			
		||||
    // Lets calculate the address 
 | 
			
		||||
    printf("FIND SUITABLE HEAP_ADDRESS\n");
 | 
			
		||||
    uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0);
 | 
			
		||||
    uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096;
 | 
			
		||||
    printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS);
 | 
			
		||||
 | 
			
		||||
    // NOTE: we can't check if the mapping has failed or not here!
 | 
			
		||||
    AllocatePage(HEAP_ADDRESS);
 | 
			
		||||
    start = (heap_block*) HEAP_ADDRESS;
 | 
			
		||||
    heap_size = 4096;
 | 
			
		||||
 | 
			
		||||
    printf("Clear heap\n");
 | 
			
		||||
    // Clear the heap 
 | 
			
		||||
    printf("set at 0x%x %d bytes to zero\n", start , heap_size);
 | 
			
		||||
    memset((void*)start, 0x00,  heap_size /4);
 | 
			
		||||
 | 
			
		||||
    printf("Init first heap block\n");
 | 
			
		||||
    // initialzie 
 | 
			
		||||
    start->Size = heap_size - sizeof(heap_block);
 | 
			
		||||
    start->Used = false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
 | 
			
		||||
void initHeap();
 | 
			
		||||
 | 
			
		||||
void* malloc (size_t size );
 | 
			
		||||
void free(void* addr);
 | 
			
		||||
 | 
			
		||||
@ -1,115 +0,0 @@
 | 
			
		||||
#include "./PhysicalMemoryManager.h"
 | 
			
		||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
const uint32_t KERNEL_OFFSET = 0xC0000000;
 | 
			
		||||
 | 
			
		||||
uint32_t* memoryBitMap;
 | 
			
		||||
uint32_t pmmap_size;
 | 
			
		||||
uint32_t max_blocks;
 | 
			
		||||
int used_blocks;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SetupPhysicalMemoryManager(uint32_t mapAddress, uint32_t memorySize ) 
 | 
			
		||||
{
 | 
			
		||||
     /*
 | 
			
		||||
        Every byte contains 8 pages
 | 
			
		||||
        A page is 4096 kib 
 | 
			
		||||
        Every block (1 bit) represent an page 
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    // Set the maximum number of blocks
 | 
			
		||||
    max_blocks = (uint32_t)memorySize / BLOCK_SIZE ;
 | 
			
		||||
    printf("Max Blocks: %d\n", max_blocks);
 | 
			
		||||
    
 | 
			
		||||
    // Set size of the bitmap 
 | 
			
		||||
    uint32_t bitmap_size = max_blocks / 32;
 | 
			
		||||
    printf("Bitmap size: %d bytes\n",bitmap_size);
 | 
			
		||||
 | 
			
		||||
    // Set blocks used to zero
 | 
			
		||||
    used_blocks = max_blocks;
 | 
			
		||||
    
 | 
			
		||||
    // set the address of the memory bitmap
 | 
			
		||||
    memoryBitMap = (uint32_t*) mapAddress;
 | 
			
		||||
 | 
			
		||||
    // Set all places in memory as free
 | 
			
		||||
    memset(memoryBitMap, 0xFFFFFFFF,  max_blocks / 32  ); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NOTE: This can only give blocks of 4kb at a time!
 | 
			
		||||
//         We might at some point want to allocate multiple blocks at once.
 | 
			
		||||
void* allocate_block() {
 | 
			
		||||
    uint8_t blocks_available = max_blocks - used_blocks;
 | 
			
		||||
    // Are there any blocks available?
 | 
			
		||||
    if( blocks_available <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Find 1 free block somewhere
 | 
			
		||||
    int free_block_index = bitmap_first_unset(memoryBitMap, max_blocks / 8 );
 | 
			
		||||
 | 
			
		||||
    if(free_block_index == -1)
 | 
			
		||||
    {
 | 
			
		||||
        printf("Could not find a good block!\n");
 | 
			
		||||
        // Could not find a block
 | 
			
		||||
        return (void*)0xFFFF;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(free_block_index == 0)
 | 
			
		||||
        printf("Somethings wrong!!!\n");
 | 
			
		||||
 | 
			
		||||
    // Set the block to be used!
 | 
			
		||||
    bitmap_unset(memoryBitMap, free_block_index);
 | 
			
		||||
    // Increase the used_block count!
 | 
			
		||||
    used_blocks++;
 | 
			
		||||
    printf("used blocks: 0x%x\n", used_blocks);
 | 
			
		||||
    // return the pointer to the physical address
 | 
			
		||||
    return (void*) (BLOCK_SIZE * free_block_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_block(void* p) {
 | 
			
		||||
    // If it is a null pointer we don't need to do anything.
 | 
			
		||||
    if(p==0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // calculate the index into the bitmap
 | 
			
		||||
    int index  = ((uint32_t) p) / BLOCK_SIZE;
 | 
			
		||||
    
 | 
			
		||||
    // set the block to be free
 | 
			
		||||
    bitmap_set(memoryBitMap, index);
 | 
			
		||||
    used_blocks--;
 | 
			
		||||
    printf("used blocks: 0x%x, after free\n", used_blocks);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void allocate_region(uint32_t startAddress, uint32_t size) {
 | 
			
		||||
    // every bit should be 4KiB 
 | 
			
		||||
    // every byte is 8*4KiB = 32KiB
 | 
			
		||||
    
 | 
			
		||||
    int NumberOfBlocksToAllocate = ( size / 1024) / 4  / 8 + 1;
 | 
			
		||||
    int startBlock = (startAddress / 1024) / 4 / 8 ;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < NumberOfBlocksToAllocate; i++)
 | 
			
		||||
    {
 | 
			
		||||
        bitmap_unset(memoryBitMap, startBlock + i);// allocate region causes #PF Exception
 | 
			
		||||
        used_blocks++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void deallocate_region(uint32_t  StartAddress , uint32_t size ) {
 | 
			
		||||
    // reverse of what happened in allocate_region
 | 
			
		||||
    int NumberOfBlocks = (size / 1024) / 4 / 8 + 1;
 | 
			
		||||
    int startBlock = (StartAddress / 1024) / 4 / 8;
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; i < NumberOfBlocks; i++)
 | 
			
		||||
    {
 | 
			
		||||
        bitmap_set(memoryBitMap, startBlock + i);
 | 
			
		||||
        used_blocks --;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetUsedBlocks (){
 | 
			
		||||
    return used_blocks;
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "../prekernel/bootstructure.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../lib/mem.h"
 | 
			
		||||
#include "../bitmap.h"
 | 
			
		||||
 | 
			
		||||
#define BLOCK_SIZE 4092 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SetupPhysicalMemoryManager(uint32_t mapAddress, uint32_t memorySize);
 | 
			
		||||
 | 
			
		||||
void* allocate_block();
 | 
			
		||||
void free_block(void* ptr);
 | 
			
		||||
 | 
			
		||||
void allocate_region(uint32_t address, uint32_t size);
 | 
			
		||||
void deallocate_region(uint32_t address, uint32_t size);
 | 
			
		||||
 | 
			
		||||
int GetUsedBlocks();
 | 
			
		||||
@ -1,93 +0,0 @@
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
extern uint32_t boot_page_directory[1024] ;
 | 
			
		||||
extern uint32_t boot_page_table[1024];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void flush_cr3(){
 | 
			
		||||
    asm volatile("movl %cr3, %ecx;"
 | 
			
		||||
	             "movl %ecx, %cr3");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void AllocatePage(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
    printf("Allocation happening at PDE: %d PTE: %d\n", PageDirectoryEntryIndex, PageTableEntryIndex);
 | 
			
		||||
 | 
			
		||||
    // check if the page directory entry is marked as present 
 | 
			
		||||
    if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) 
 | 
			
		||||
    {
 | 
			
		||||
        printf("Directory entry is marked as present\n");
 | 
			
		||||
        uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ;
 | 
			
		||||
        page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
 | 
			
		||||
        printf("Page table address: 0x%x\n", (uint32_t)page_table);
 | 
			
		||||
 | 
			
		||||
        // check if the page table entry is marked as present 
 | 
			
		||||
        if ( page_table[PageTableEntryIndex] & 0x1 )
 | 
			
		||||
        {   
 | 
			
		||||
            printf("page already present!\n");
 | 
			
		||||
            return;
 | 
			
		||||
        } else{
 | 
			
		||||
            printf("Mapping a physical page.\n");
 | 
			
		||||
            // Map the entry to a physical page
 | 
			
		||||
            page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
 | 
			
		||||
            flush_cr3();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("Mapping a new page directory entry with a page table\n");
 | 
			
		||||
        // mark the page table as present and allocate a physical block for it
 | 
			
		||||
        boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
 | 
			
		||||
        flush_cr3();
 | 
			
		||||
   
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FreePage(uint32_t vaddr )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
    uint32_t* pageTable = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000 + 0xC0000000);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void* physicalAddressToFree = (void*)(pageTable[PageTableEntryIndex] & 0xFFFFE000 + 0xC0000000);
 | 
			
		||||
    free_block(physicalAddressToFree);
 | 
			
		||||
 | 
			
		||||
    pageTable[PageTableEntryIndex] = 0x0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Immediate_Map (  uint32_t vaddr, uint32_t paddr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Immediate_Unmap(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: I will implement lazy unmapping for now 
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
}
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../cpu.h"
 | 
			
		||||
#include "PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SetupVMM();
 | 
			
		||||
 | 
			
		||||
void AllocatePage(uint32_t v_addr );
 | 
			
		||||
void FreePage(uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
void Immediate_Map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
void Immediate_Unmap (uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
// void Demand_map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
// void Demand_Unmap (uint32_t v_addr);
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
extern "C" const uint32_t kernel_begin;
 | 
			
		||||
extern "C" const uint32_t kernel_end;
 | 
			
		||||
 | 
			
		||||
#define IS_AVAILABLE_MEM(MEM_TYPE) MEM_TYPE & 0x1
 | 
			
		||||
#define IS_ACPI_MEM(MEM_TYPE) MEM_TYPE & 0x2
 | 
			
		||||
#define IS_RESERVED_MEM(MEM_TYPE) MEM_TYPE & 0x4
 | 
			
		||||
#define IS_NVS_MEMORY(MEM_TYPE) MEM_TYPE & 0x8
 | 
			
		||||
#define IS_BADRAM_MEMORY(MEM_TYPE) MEM_TYPE & 0x10
 | 
			
		||||
           
 | 
			
		||||
 | 
			
		||||
struct BootInfoBlock {
 | 
			
		||||
    bool MapIsInvalid;
 | 
			
		||||
    uint32_t bootDeviceID ;
 | 
			
		||||
 | 
			
		||||
    uint32_t GrubModuleCount;
 | 
			
		||||
 | 
			
		||||
    bool ValidSymbolTable;
 | 
			
		||||
    uint32_t SymbolTableAddr;
 | 
			
		||||
    uint32_t SymbolTabSize;
 | 
			
		||||
    uint32_t SymbolStrSize;
 | 
			
		||||
 | 
			
		||||
    bool ValidELFHeader;
 | 
			
		||||
 | 
			
		||||
    bool EnabledVBE;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
@ -1,140 +0,0 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "multiboot.h"
 | 
			
		||||
#include "../memory/PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
#define VADDR_TO_PADDR(vaddr) (vaddr - 0xC0000000)
 | 
			
		||||
#define PADDR_TO_VADDR(paddr) (paddr + 0xC0000000)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi) 
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        * Check Multiboot magic number
 | 
			
		||||
        */ 
 | 
			
		||||
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
 | 
			
		||||
        {
 | 
			
		||||
                // PANIC!!
 | 
			
		||||
                return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mbi = PADDR_TO_VADDR(mbi);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // Setup the physical memory manager immmediatly 
 | 
			
		||||
        // Doing so saves the complications of doing it later when 
 | 
			
		||||
        // paging is enabled 
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        If we got a memory map from our bootloader we 
 | 
			
		||||
        should be parsing it to find out the memory regions available.
 | 
			
		||||
        */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 6))
 | 
			
		||||
        {  
 | 
			
		||||
               
 | 
			
		||||
                // Calculate total memory size 
 | 
			
		||||
                uint32_t RAM_size = 0;
 | 
			
		||||
                for(
 | 
			
		||||
                        multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) mbi->mmap_addr;
 | 
			
		||||
                         (unsigned long)mmap < mbi->mmap_addr + mbi->mmap_length;
 | 
			
		||||
                          mmap += mmap->size +sizeof(mmap->size)
 | 
			
		||||
                ){
 | 
			
		||||
                        RAM_size += mmap->len;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                // Call SetupPhysicalMemoryManager at its physical address 
 | 
			
		||||
                SetupPhysicalMemoryManager ( (uint32_t)VADDR_TO_PADDR(&kernel_end), RAM_size);
 | 
			
		||||
                
 | 
			
		||||
                for(
 | 
			
		||||
                        multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) mbi->mmap_addr;
 | 
			
		||||
                         (unsigned long)mmap < mbi->mmap_addr + mbi->mmap_length;
 | 
			
		||||
                          mmap += mmap->size +sizeof(mmap->size)
 | 
			
		||||
                ){
 | 
			
		||||
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE)
 | 
			
		||||
                                deallocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_RESERVED)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_NVS)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_BADRAM)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
               
 | 
			
		||||
               
 | 
			
		||||
                // Allocate the kernel
 | 
			
		||||
                allocate_region( (uint32_t)&kernel_begin, ( (uint32_t)&kernel_end - (uint32_t)&kernel_begin)- 0xC0000000 );
 | 
			
		||||
 | 
			
		||||
                // Allocate the memory region below 1MB
 | 
			
		||||
                allocate_region(0x0000000, 0x00100000);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
                // We didn't get a memory map from our bootloader.
 | 
			
		||||
                // PANIC!!!!
 | 
			
		||||
                return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // allocate a full block for the other boot info!
 | 
			
		||||
        BootInfoBlock* BIB = (BootInfoBlock*) allocate_block();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /* is boot device valid ? */
 | 
			
		||||
        if (CHECK_FLAG (mbi->flags, 1))
 | 
			
		||||
        {
 | 
			
		||||
                BIB->bootDeviceID = mbi->boot_device;
 | 
			
		||||
        } else{
 | 
			
		||||
                BIB->bootDeviceID = 0x11111111;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Are mods_* valid? */
 | 
			
		||||
        if(CHECK_FLAG ( mbi->flags, 3)){
 | 
			
		||||
                multiboot_module_t *mod;
 | 
			
		||||
                uint32_t i;
 | 
			
		||||
 | 
			
		||||
                BIB->GrubModuleCount = mbi->mods_count;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
 | 
			
		||||
                        
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Is the symbol table of a.out valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 4))
 | 
			
		||||
        {
 | 
			
		||||
        // NOTE: Do something with it.. (Store it , process it etc...)
 | 
			
		||||
        // printf("- Valid Symbol Table available at 0x%x.\n Tab Size: %d, str Size: %d\n", BootInfo->SymbolTableAddr, BootInfo->SymbolTabSize, BootInfo->SymbolStrSize);
 | 
			
		||||
                BIB->ValidSymbolTable = true;
 | 
			
		||||
                multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
 | 
			
		||||
 | 
			
		||||
        } else{
 | 
			
		||||
                BIB->ValidSymbolTable = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Is the section header table of ELF valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 5))
 | 
			
		||||
        {
 | 
			
		||||
                  // NOTE: Do something with it.. (Store it , process it etc...)
 | 
			
		||||
                BIB->ValidELFHeader = true;
 | 
			
		||||
                multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
 | 
			
		||||
 | 
			
		||||
        }else{
 | 
			
		||||
                BIB->ValidELFHeader = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Draw diagonal blue line */
 | 
			
		||||
        if (CHECK_FLAG (mbi->flags, 12)){
 | 
			
		||||
                BIB->EnabledVBE = true;
 | 
			
		||||
 | 
			
		||||
                   // NOTE: Do something with it.. (Store it , process it etc...)
 | 
			
		||||
        } else{
 | 
			
		||||
                BIB->EnabledVBE;
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
@ -1,58 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "terminal/kterm.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#define PORT 0x3f8 
 | 
			
		||||
static int init_serial() {
 | 
			
		||||
 | 
			
		||||
#ifdef __VERBOSE__
 | 
			
		||||
   printf("Init Serial\n");
 | 
			
		||||
#endif
 | 
			
		||||
   
 | 
			
		||||
   outb(PORT + 1, 0x00);    // Disable all interrupts
 | 
			
		||||
   outb(PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
 | 
			
		||||
   outb(PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
 | 
			
		||||
   outb(PORT + 1, 0x00);    //                  (hi byte)
 | 
			
		||||
   outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
 | 
			
		||||
   outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
 | 
			
		||||
   outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
 | 
			
		||||
   outb(PORT + 4, 0x1E);    // Set in loopback mode, test the serial chip
 | 
			
		||||
   outb(PORT + 0, 0xAE);    // Test serial chip (send byte 0xAE and check if serial returns same byte)
 | 
			
		||||
 
 | 
			
		||||
   // Check if serial is faulty (i.e: not same byte as sent)
 | 
			
		||||
   if(inb(PORT + 0) != 0xAE) {
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
   // If serial is not faulty set it in normal operation mode
 | 
			
		||||
   // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
 | 
			
		||||
   outb(PORT + 4, 0x0F);
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int is_transmit_empty() {
 | 
			
		||||
   return inb(PORT + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void write_serial(char a) {
 | 
			
		||||
   while (is_transmit_empty() == 0);
 | 
			
		||||
 
 | 
			
		||||
   outb(PORT,a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int serial_received() {
 | 
			
		||||
   return inb(PORT + 5) & 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
char read_serial() {
 | 
			
		||||
   while (serial_received() == 0);
 | 
			
		||||
 
 | 
			
		||||
   return inb(PORT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_serial(const char* string ){
 | 
			
		||||
    for(size_t i = 0; i < strlen(string); i ++){
 | 
			
		||||
        write_serial(string[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,72 +0,0 @@
 | 
			
		||||
#include "superVisorTerminal.h"
 | 
			
		||||
 | 
			
		||||
void startSuperVisorTerminal(){
 | 
			
		||||
    while (true){
 | 
			
		||||
           
 | 
			
		||||
           printf("SUPERVISOR:>$ " );
 | 
			
		||||
            int characterCount = 0;
 | 
			
		||||
            char command[10] = "";
 | 
			
		||||
         
 | 
			
		||||
            // NOTE: lets just show a kernel prompt                
 | 
			
		||||
            uint8_t ScanCode = getKey();
 | 
			
		||||
            while( ScanCode  != 0x1C )
 | 
			
		||||
            {
 | 
			
		||||
                char character = getASCIIKey();
 | 
			
		||||
                kterm_put(character );
 | 
			
		||||
                // wHAT THE HELL
 | 
			
		||||
 | 
			
		||||
                if( characterCount  < 10 ){
 | 
			
		||||
                    command[characterCount] = character;  
 | 
			
		||||
                    characterCount++;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ScanCode = getKey(); 
 | 
			
		||||
            }
 | 
			
		||||
            printf("\n");
 | 
			
		||||
            KeyHandled();
 | 
			
		||||
         
 | 
			
		||||
 | 
			
		||||
            if ( strncmp("DATE", command , characterCount ) == 0 )
 | 
			
		||||
            {
 | 
			
		||||
                 read_rtc();
 | 
			
		||||
                 printf("======= Time & Date ==========\n");
 | 
			
		||||
                 printf("   - Date:     %02d-%02d-%02d\n",day, month, year);
 | 
			
		||||
                 printf("   - Time:     %02d:%02d:%02d\n" , hour, minute, second);
 | 
			
		||||
                 printf("   - Ticks:    %09d\n", pit_tick);            
 | 
			
		||||
            }
 | 
			
		||||
            else if( strncmp ("MEMORY" , command , characterCount) == 0 )
 | 
			
		||||
            {
 | 
			
		||||
                // Show memory layout
 | 
			
		||||
                printf("========= Memory ==========\n");
 | 
			
		||||
                printf("Not Available!\n");
 | 
			
		||||
                printf("Kernel MemoryMap:\n");
 | 
			
		||||
                printf("Frames used: -- \n");   
 | 
			
		||||
                printf("Available Memory:-- \n");
 | 
			
		||||
                printf("Reserved Memory: -- bytes\n");
 | 
			
		||||
            }
 | 
			
		||||
            else if(strncmp("TEST", command, characterCount) == 0)
 | 
			
		||||
            {
 | 
			
		||||
                // TEST #DE exception
 | 
			
		||||
               asm volatile ("MOV $4, %AX ;  MOV $0, %BX ; DIV %BX"); // IRS 0
 | 
			
		||||
            }
 | 
			
		||||
            else if (strncmp("VERSION", command , characterCount) == 0)
 | 
			
		||||
            {
 | 
			
		||||
                // Show version information 
 | 
			
		||||
                printf("========= Version ========\n");
 | 
			
		||||
                printf("Kernel v%d\n", 0);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else if(strncmp("CLEAR", command, characterCount) == 0)
 | 
			
		||||
            {
 | 
			
		||||
                kterm_init();
 | 
			
		||||
                printf("|===    BarinkOS       ===|\n");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                printf("Unknown command\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }   
 | 
			
		||||
}
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../time.h"
 | 
			
		||||
#include "../drivers/pit/pit.h"
 | 
			
		||||
#include "../drivers/ps-2/keyboard.h"
 | 
			
		||||
#include "../memory/PhysicalMemoryManager.h"
 | 
			
		||||
#include "../lib/string.h"
 | 
			
		||||
 | 
			
		||||
void startSuperVisorTerminal();
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#define CURRENT_YEAR        2021
 | 
			
		||||
 
 | 
			
		||||
                           
 | 
			
		||||
extern int century_register;     
 | 
			
		||||
extern unsigned char second;
 | 
			
		||||
extern unsigned char minute;
 | 
			
		||||
extern unsigned char hour;
 | 
			
		||||
extern unsigned char day;
 | 
			
		||||
extern unsigned char month;
 | 
			
		||||
extern unsigned int year;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
enum {
 | 
			
		||||
      cmos_address = 0x70,
 | 
			
		||||
      cmos_data    = 0x71
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
int get_update_in_progress_flag();
 | 
			
		||||
unsigned char get_RTC_register();
 | 
			
		||||
void read_rtc();
 | 
			
		||||
void delay(int t);
 | 
			
		||||
							
								
								
									
										3
									
								
								src/grub.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/grub.cfg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
menuentry "BarinkOS"{
 | 
			
		||||
    multiboot /boot/myos.bin
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								src/gui/Graphics.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/gui/Graphics.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
class Graphics {
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										7
									
								
								src/gui/Widget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/gui/Widget.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Widget{
 | 
			
		||||
    virtual void draw();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										17
									
								
								src/gui/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/gui/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#include "cursor.h"
 | 
			
		||||
 | 
			
		||||
    void Cursor::draw(){
 | 
			
		||||
        for(int i = 0; i <  this->width; i++){
 | 
			
		||||
            for(int j = 0; j <  this->height; j++){
 | 
			
		||||
                if(this->bitmap[j * this->width + i] == 1 ){
 | 
			
		||||
                        putPixel(i + this->x,j + this->y, 0xFF000000);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Cursor::Cursor(int x, int y){
 | 
			
		||||
        this->x = x;
 | 
			
		||||
        this->y = y;
 | 
			
		||||
    }
 | 
			
		||||
							
								
								
									
										38
									
								
								src/gui/cursor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/gui/cursor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../kernel/drivers/vesa/vesa.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Cursor{
 | 
			
		||||
    public:
 | 
			
		||||
    void draw();
 | 
			
		||||
    Cursor(int x, int y);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        int x;
 | 
			
		||||
        int y;
 | 
			
		||||
        const int width= 16;
 | 
			
		||||
        const int height= 10;
 | 
			
		||||
        const int bitmap [160] = {
 | 
			
		||||
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
 | 
			
		||||
 | 
			
		||||
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
			
		||||
        };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										33
									
								
								src/gui/window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/gui/window.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
#include "window.h"
 | 
			
		||||
 | 
			
		||||
int Window::getWidth(){
 | 
			
		||||
    return this->rect.width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Window::getHeight(){
 | 
			
		||||
    return this->rect.height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Window::setWidth(int& width){
 | 
			
		||||
    this->rect.width = width;
 | 
			
		||||
}
 | 
			
		||||
void Window::setHeight(int& height){
 | 
			
		||||
    this->rect.height = height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Window::getX(){
 | 
			
		||||
    return this->rect.x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Window::getY(){
 | 
			
		||||
    return this->rect.y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window::Window (Rect& rect , uint32_t colour){
 | 
			
		||||
    this->rect = rect;
 | 
			
		||||
    this->Background_colour = colour;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Window::draw(){
 | 
			
		||||
    drawRect(this->getX() , this->getY() , this->getWidth() , this->getHeight() ,this->Background_colour );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/gui/window.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/gui/window.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../kernel/drivers/vesa/vesa.h"
 | 
			
		||||
#include "Widget.h"
 | 
			
		||||
 | 
			
		||||
struct Rect {
 | 
			
		||||
    int width;
 | 
			
		||||
    int height;
 | 
			
		||||
    int x;
 | 
			
		||||
    int y;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Window : Widget{
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    int getX();
 | 
			
		||||
    int getY();
 | 
			
		||||
 | 
			
		||||
    int getWidth();
 | 
			
		||||
    int getHeight();
 | 
			
		||||
    void setWidth(int&);
 | 
			
		||||
    void setHeight(int&);
 | 
			
		||||
 | 
			
		||||
    Window (Rect& rect , uint32_t colour);
 | 
			
		||||
    void draw();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Rect rect;
 | 
			
		||||
    uint32_t Background_colour;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										87
									
								
								src/kernel/boot.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/kernel/boot.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Multiboot 
 | 
			
		||||
 */
 | 
			
		||||
.set ALIGN,    1<<0             		/* align loaded modules on page boundaries */
 | 
			
		||||
.set MEMINFO,  1<<1             		/* provide memory map */
 | 
			
		||||
.set VIDEO,	   1<<2						/* provide video mode */
 | 
			
		||||
.set FLAGS,    ALIGN | MEMINFO | VIDEO  /* this is the Multiboot 'flag' field */
 | 
			
		||||
.set MAGIC,    0x1BADB002       		/* 'magic number' lets bootloader find the header */
 | 
			
		||||
.set CHECKSUM, -(MAGIC + FLAGS) 		/* checksum of above, to prove we are multiboot */
 | 
			
		||||
 | 
			
		||||
.section .multiboot
 | 
			
		||||
.align 4
 | 
			
		||||
.long MAGIC
 | 
			
		||||
.long FLAGS
 | 
			
		||||
.long CHECKSUM
 | 
			
		||||
.long 0 # unused
 | 
			
		||||
.long 0 # .
 | 
			
		||||
.long 0 # .
 | 
			
		||||
.long 0 # .
 | 
			
		||||
.long 0 # unused
 | 
			
		||||
.long 0 # set graphics mode
 | 
			
		||||
.long 800 # screen witdh
 | 
			
		||||
.long 600 # screen height
 | 
			
		||||
.long 32 # bpp
 | 
			
		||||
 | 
			
		||||
.section .bss
 | 
			
		||||
.align 16
 | 
			
		||||
stack_bottom:
 | 
			
		||||
.skip 16384 # 16 KiB
 | 
			
		||||
stack_top:
 | 
			
		||||
 
 | 
			
		||||
.section .text
 | 
			
		||||
.include "./src/kernel/irs_table.s"
 | 
			
		||||
.include "./src/kernel/irq_table.s"
 | 
			
		||||
.include "./src/kernel/idt/idt.s"
 | 
			
		||||
.include "./src/kernel/paging.s"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.global _start
 | 
			
		||||
.type _start, @function
 | 
			
		||||
_start:
 | 
			
		||||
	/*Setup the stack pointer to point to the beginning of our stack */
 | 
			
		||||
	/* I believe its a high address growing down to lower adress for the stack on x86*/
 | 
			
		||||
	mov $stack_top, %esp
 | 
			
		||||
 | 
			
		||||
	/*Reset EFLAGS*/
 | 
			
		||||
	pushl $0 
 | 
			
		||||
	popf 
 | 
			
		||||
 | 
			
		||||
	/* push the pointer to the Multiboot information structure*/
 | 
			
		||||
	pushl %ebx
 | 
			
		||||
 | 
			
		||||
	/* push the magic value */
 | 
			
		||||
	pushl %eax
 | 
			
		||||
	
 | 
			
		||||
	call early_main
 | 
			
		||||
	cli
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
.include "./src/kernel/gdt/gdt.s"
 | 
			
		||||
 | 
			
		||||
	loadIDT:
 | 
			
		||||
		#load idt
 | 
			
		||||
		call init_idt
 | 
			
		||||
        sti
 | 
			
		||||
        
 | 
			
		||||
        # Try enable A20
 | 
			
		||||
		# mov $0x2401, %ax
 | 
			
		||||
		# int $0x15
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		# enable protected mode
 | 
			
		||||
		mov %cr0, %eax 
 | 
			
		||||
		or $1, %eax
 | 
			
		||||
		mov %eax, %cr0
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		call kernel_main
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		cli
 | 
			
		||||
	1:	hlt
 | 
			
		||||
		jmp 1b
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.size _start, . - _start
 | 
			
		||||
							
								
								
									
										108
									
								
								src/kernel/bootcheck.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/kernel/bootcheck.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "bootloader/multiboot.h"
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
#include "../gui/window.h"
 | 
			
		||||
#include "../gui/cursor.h"
 | 
			
		||||
#include "tty/kterm.h"
 | 
			
		||||
#include "drivers/vesa/vesa.h"
 | 
			
		||||
 | 
			
		||||
void CheckMBT ( multiboot_info_t*  mbt  ){
 | 
			
		||||
  /* Set MBI to the addresss of the multiboot information structure*/
 | 
			
		||||
  multiboot_info_t * mbi = (multiboot_info_t *) mbt;
 | 
			
		||||
 | 
			
		||||
  /* Print out the flags */
 | 
			
		||||
  printf("flags = 0x%8x\n", (unsigned) mbi->flags);
 | 
			
		||||
 | 
			
		||||
  /* Are mem_* valid? */
 | 
			
		||||
  if ( CHECK_FLAG(mbi->flags,0)){
 | 
			
		||||
      printf("mem_lower = %uKB, mem_upper = %uKB\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* is boot device valid ? */
 | 
			
		||||
  if (CHECK_FLAG (mbi->flags, 1)){
 | 
			
		||||
      printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* is the command line passed? */
 | 
			
		||||
  if (CHECK_FLAG ( mbi->flags,2)){
 | 
			
		||||
      printf("cmdline = %s\n", (char *) mbi->cmdline);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Are mods_* valid? */
 | 
			
		||||
  if(CHECK_FLAG ( mbi->flags, 3)){
 | 
			
		||||
      multiboot_module_t *mod;
 | 
			
		||||
      uint32_t i;
 | 
			
		||||
 | 
			
		||||
      printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
 | 
			
		||||
 | 
			
		||||
      for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
 | 
			
		||||
          printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Bits 4 and 5 are mutually exclusive! */
 | 
			
		||||
  if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){
 | 
			
		||||
      printf("Both bits 4 and 5 are set.\n");
 | 
			
		||||
      return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Is the symbol table of a.out valid? */
 | 
			
		||||
  if (CHECK_FLAG(mbi->flags, 4)){
 | 
			
		||||
      multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
 | 
			
		||||
 | 
			
		||||
      printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", 
 | 
			
		||||
      (unsigned) multiboot_aout_sym->tabsize,
 | 
			
		||||
      (unsigned) multiboot_aout_sym->strsize,
 | 
			
		||||
      (unsigned) multiboot_aout_sym->addr);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Is the section header table of ELF valid? */
 | 
			
		||||
  if (CHECK_FLAG(mbi->flags, 5)){
 | 
			
		||||
      multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
 | 
			
		||||
 | 
			
		||||
      printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
 | 
			
		||||
      (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
 | 
			
		||||
      (unsigned) multiboot_elf_sec->addr, (unsigned)  multiboot_elf_sec->shndx);
 | 
			
		||||
      
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Draw diagonal blue line */
 | 
			
		||||
  if (CHECK_FLAG (mbt->flags, 11)){
 | 
			
		||||
    printf("Can draw!");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Init vesa driver
 | 
			
		||||
    initVBEDevice(mbt); 
 | 
			
		||||
 | 
			
		||||
    // Fill screen with blue
 | 
			
		||||
                                                // colours AARRGGBB
 | 
			
		||||
    drawRect(0, 0 , VbeModeInfo->width,VbeModeInfo->height, 0xFF0000FF);
 | 
			
		||||
 | 
			
		||||
    // Create two windows
 | 
			
		||||
    Rect rect_window1 {};
 | 
			
		||||
    Rect rect_window2 {};
 | 
			
		||||
    rect_window1.height =200;
 | 
			
		||||
    rect_window1.width = 300;
 | 
			
		||||
    rect_window1.x = 50;
 | 
			
		||||
    rect_window1.y = 50;
 | 
			
		||||
 | 
			
		||||
    rect_window2.height =200;
 | 
			
		||||
    rect_window2.width = 300;
 | 
			
		||||
    rect_window2.x = 300;
 | 
			
		||||
    rect_window2.y = 200;
 | 
			
		||||
 | 
			
		||||
    Window window_1 ( rect_window1, 0xFF00F0FF);
 | 
			
		||||
    Window window_2 (rect_window2, 0xFFAACCDD);
 | 
			
		||||
 | 
			
		||||
    window_1.draw();
 | 
			
		||||
    window_2.draw();
 | 
			
		||||
 | 
			
		||||
    Cursor cursor (70,100);
 | 
			
		||||
 | 
			
		||||
    cursor.draw();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/kernel/cpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/kernel/cpu.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#include <cpuid.h> // NOTE: Only available in GCC 
 | 
			
		||||
// NOT currently usefull!
 | 
			
		||||
/*    static int get_model(){
 | 
			
		||||
        int ebx, unused;
 | 
			
		||||
        __cpuid(0, unused, ebx, unused, unused);
 | 
			
		||||
        return ebx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum {
 | 
			
		||||
        CPUID_FEAT_EDX_APIC = 1 << 9
 | 
			
		||||
    };
 | 
			
		||||
    static int check_apic (){
 | 
			
		||||
        unsigned int eax, unused, edx;
 | 
			
		||||
        __get_cpuid(1, &eax, &unused, &unused, &edx);
 | 
			
		||||
        return  edx & CPUID_FEAT_EDX_APIC;
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										17
									
								
								src/kernel/disk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/kernel/disk.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a
 | 
			
		||||
// storage device
 | 
			
		||||
 | 
			
		||||
// PRIMARY_ATA_BUS
 | 
			
		||||
// 0x1F0 through 0x1F7 
 | 
			
		||||
 | 
			
		||||
// SECONDARY_ATA_BUS
 | 
			
		||||
// 0x170 through 0x177
 | 
			
		||||
 | 
			
		||||
#define DEVICE_CONTROL_REGISTER 0x3F6
 | 
			
		||||
#define DEVICE_CONTROL_ALTERNATE 0x376
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// IRQ14 Primary bus interrupt
 | 
			
		||||
// IRQ15 Secondary bus interrupt
 | 
			
		||||
							
								
								
									
										136
									
								
								src/kernel/drivers/vesa/vesa.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/kernel/drivers/vesa/vesa.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
#include "vesa.h"
 | 
			
		||||
VbeInfoBlock* vbeInfo;
 | 
			
		||||
vbe_mode_info_structure* VbeModeInfo;
 | 
			
		||||
 | 
			
		||||
void initVBEDevice(multiboot_info_t* mbt){
 | 
			
		||||
    print_serial("initVBEDevice");
 | 
			
		||||
 | 
			
		||||
    vbeInfo = (VbeInfoBlock*) mbt->vbe_control_info;
 | 
			
		||||
    printf_serial("Signature: %s, V0x%x\n", vbeInfo->VbeSignature, vbeInfo->VbeVersion);
 | 
			
		||||
 | 
			
		||||
    VbeModeInfo = (vbe_mode_info_structure*) mbt->vbe_mode_info;
 | 
			
		||||
 | 
			
		||||
    printf_serial("VESA video mode info: Width: %d Height: %d BPP: %d\n", VbeModeInfo->width, VbeModeInfo->height , VbeModeInfo->bpp);
 | 
			
		||||
    printf_serial("VideoMemory Location: 0x%x \n", VbeModeInfo->framebuffer );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void putPixel( int x, int y , uint32_t colour){
 | 
			
		||||
   // printf_serial("putPixel x: %d, y: %d\n", x, y);
 | 
			
		||||
                    ///fb + mbt->framebuffer_pitch * y + 4 * x ,NOTE: this calculation is very important 
 | 
			
		||||
    *(uint32_t*) (  VbeModeInfo->framebuffer + VbeModeInfo->pitch * y + 4  * x ) = colour;
 | 
			
		||||
}
 | 
			
		||||
void drawLine(int x1, int y1, int x2, int y2, uint32_t colour ){
 | 
			
		||||
    print_serial("drawline\n");
 | 
			
		||||
    // See Bresenham's line algorithm
 | 
			
		||||
    int deltaX = x2 - x1;
 | 
			
		||||
    int deltaY = y2 - y1;
 | 
			
		||||
    int D = 2 * deltaY - deltaX;
 | 
			
		||||
    int y = y1;
 | 
			
		||||
 | 
			
		||||
    for ( int x = x1; x < x2; x++){
 | 
			
		||||
      putPixel(x,y, colour);
 | 
			
		||||
      if( D > 0){
 | 
			
		||||
        y +=1;
 | 
			
		||||
        D = D - 2 * deltaX;
 | 
			
		||||
      }
 | 
			
		||||
      D = D + 2 * deltaY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
void drawRect ( int x, int y, int width, int height, uint32_t colour ){
 | 
			
		||||
    print_serial("drawRect\n");
 | 
			
		||||
    for ( int i = x; i < x + width; i ++)
 | 
			
		||||
    {
 | 
			
		||||
      for(int j = y; j < y + height; j++){
 | 
			
		||||
        
 | 
			
		||||
        putPixel(i,j, colour);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void blueDiagnalLineTest(multiboot_info_t* mbt){
 | 
			
		||||
    multiboot_uint32_t color;
 | 
			
		||||
    unsigned i;
 | 
			
		||||
    void *fb = (void *) (unsigned long) mbt->framebuffer_addr;
 | 
			
		||||
 | 
			
		||||
     switch (mbt->framebuffer_type)
 | 
			
		||||
        {
 | 
			
		||||
        case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
 | 
			
		||||
          {
 | 
			
		||||
            unsigned best_distance, distance;
 | 
			
		||||
            struct multiboot_color *palette;
 | 
			
		||||
            
 | 
			
		||||
            palette = (struct multiboot_color *) mbt->framebuffer_palette_addr;
 | 
			
		||||
 | 
			
		||||
            color = 0;
 | 
			
		||||
            best_distance = 4*256*256;
 | 
			
		||||
            
 | 
			
		||||
            for (i = 0; i < mbt->framebuffer_palette_num_colors; i++)
 | 
			
		||||
              {
 | 
			
		||||
                distance = (0xff - palette[i].blue) * (0xff - palette[i].blue)
 | 
			
		||||
                  + palette[i].red * palette[i].red
 | 
			
		||||
                  + palette[i].green * palette[i].green;
 | 
			
		||||
                if (distance < best_distance)
 | 
			
		||||
                  {
 | 
			
		||||
                    color = i;
 | 
			
		||||
                    best_distance = distance;
 | 
			
		||||
                  }
 | 
			
		||||
              }
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
 | 
			
		||||
          color = ((1 << mbt->framebuffer_blue_mask_size) - 1) 
 | 
			
		||||
            << mbt->framebuffer_blue_field_position;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
 | 
			
		||||
          color = '\\' | 0x0100;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          color = 0xffffffff;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      for (i = 0; i < mbt->framebuffer_width
 | 
			
		||||
             && i < mbt->framebuffer_height; i++)
 | 
			
		||||
        {
 | 
			
		||||
          switch (mbt->framebuffer_bpp)
 | 
			
		||||
            {
 | 
			
		||||
            case 8:
 | 
			
		||||
              {
 | 
			
		||||
                multiboot_uint8_t *pixel = (multiboot_uint8_t*)fb + mbt->framebuffer_pitch * i + i;
 | 
			
		||||
                *pixel = color;
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
            case 15:
 | 
			
		||||
            case 16:
 | 
			
		||||
              {
 | 
			
		||||
                multiboot_uint16_t *pixel
 | 
			
		||||
                  = (multiboot_uint16_t*)fb + mbt->framebuffer_pitch * i + 2 * i;
 | 
			
		||||
                *pixel = color;
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
            case 24:
 | 
			
		||||
              {
 | 
			
		||||
                multiboot_uint32_t *pixel
 | 
			
		||||
                  = (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 3 * i;
 | 
			
		||||
                *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case 32:
 | 
			
		||||
              {
 | 
			
		||||
                multiboot_uint32_t *pixel
 | 
			
		||||
                  = (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 4 * i;
 | 
			
		||||
                *pixel = color;
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								src/kernel/drivers/vesa/vesa.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/kernel/drivers/vesa/vesa.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../../bootloader/multiboot.h"
 | 
			
		||||
#include "../../serial.h"
 | 
			
		||||
 | 
			
		||||
struct vbe_mode_info_structure{
 | 
			
		||||
        uint16_t attributes;
 | 
			
		||||
        uint8_t window_a;
 | 
			
		||||
        uint8_t window_b;
 | 
			
		||||
        uint16_t granularity;
 | 
			
		||||
        uint16_t window_size;
 | 
			
		||||
        uint16_t segment_a;
 | 
			
		||||
        uint16_t segment_b;
 | 
			
		||||
        uint32_t win_func_ptr;
 | 
			
		||||
        uint16_t pitch;
 | 
			
		||||
        uint16_t width;
 | 
			
		||||
        uint16_t height;
 | 
			
		||||
        uint8_t w_char;
 | 
			
		||||
        uint8_t y_char;
 | 
			
		||||
        uint8_t planes;
 | 
			
		||||
        uint8_t bpp;
 | 
			
		||||
        uint8_t banks;
 | 
			
		||||
        uint8_t memory_model;
 | 
			
		||||
        uint8_t bank_size;
 | 
			
		||||
        uint8_t image_pages;
 | 
			
		||||
        uint8_t reserved0;
 | 
			
		||||
 | 
			
		||||
        uint8_t red_mask;
 | 
			
		||||
        uint8_t red_position;
 | 
			
		||||
        uint8_t green_mask;
 | 
			
		||||
        uint8_t green_position;
 | 
			
		||||
        uint8_t blue_mask;
 | 
			
		||||
        uint8_t blue_position;
 | 
			
		||||
        uint8_t reserved_mask;
 | 
			
		||||
        uint8_t reserved_position;
 | 
			
		||||
        uint8_t direct_color_attributes;
 | 
			
		||||
 | 
			
		||||
        uint32_t framebuffer;
 | 
			
		||||
        uint32_t off_screen_mem_off;
 | 
			
		||||
        uint16_t off_screen_mem_size;
 | 
			
		||||
        uint8_t reserved1[206];
 | 
			
		||||
      }__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct VbeInfoBlock {
 | 
			
		||||
        char VbeSignature[4];
 | 
			
		||||
        uint16_t VbeVersion;
 | 
			
		||||
        uint16_t OemStringPtr;
 | 
			
		||||
        uint8_t Capabilities;
 | 
			
		||||
        uint16_t VideoModePtr;
 | 
			
		||||
        uint16_t TotalMemory;
 | 
			
		||||
      }__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
extern VbeInfoBlock* vbeInfo;
 | 
			
		||||
extern vbe_mode_info_structure* VbeModeInfo;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void initVBEDevice(multiboot_info_t* mbt);
 | 
			
		||||
 | 
			
		||||
void blueDiagnalLineTest(multiboot_info_t* mbt);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Primitive drawing functions  
 | 
			
		||||
void putPixel( int x, int y , uint32_t colour);
 | 
			
		||||
void drawLine(int x1, int y1, int x2, int y2, uint32_t colour );
 | 
			
		||||
void drawRect ( int x, int y, int width, int height, uint32_t colour );
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#include "gdtc.h"
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#include "../tty/kterm.h"
 | 
			
		||||
 | 
			
		||||
#define NULL_SEGMENT          0
 | 
			
		||||
#define KERNEL_CODE_SEGMENT   1
 | 
			
		||||
@ -29,9 +29,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
 | 
			
		||||
 | 
			
		||||
void initGDT(){
 | 
			
		||||
 | 
			
		||||
#ifdef __VERBOSE__
 | 
			
		||||
      printf("Init GDT!\n");
 | 
			
		||||
#endif
 | 
			
		||||
      // NULL segment
 | 
			
		||||
      add_descriptor(NULL_SEGMENT, 0,0,0,0);
 | 
			
		||||
 | 
			
		||||
@ -51,8 +48,15 @@ void initGDT(){
 | 
			
		||||
      gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
 | 
			
		||||
      gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
 | 
			
		||||
 | 
			
		||||
      printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable));
 | 
			
		||||
      printf("Hello GDT!\n");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      LoadGlobalDescriptorTable();
 | 
			
		||||
 | 
			
		||||
//      while (true)
 | 
			
		||||
//         asm volatile("hlt");
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										149
									
								
								src/kernel/idt/idt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/kernel/idt/idt.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,149 @@
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
//#include "scancodes/set1.h"
 | 
			
		||||
 | 
			
		||||
IDT_entry idt_table[256];
 | 
			
		||||
IDT_ptr idt_ptr;
 | 
			
		||||
 | 
			
		||||
void set_id_entry (uint8_t num , uint32_t base, uint16_t sel,  uint8_t flags){
 | 
			
		||||
    idt_table[num].offset_1 = base & 0xFFFF;
 | 
			
		||||
    idt_table[num].selector = sel;
 | 
			
		||||
    idt_table[num].zero = 0;
 | 
			
		||||
    idt_table[num].type_attr = flags;
 | 
			
		||||
    idt_table[num].offset_2 = (base >> 16) & 0xFFFF;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void irs_handler (registers regs) {
 | 
			
		||||
        kterm_writestring("received interrupt!\n");
 | 
			
		||||
     
 | 
			
		||||
        printf("(IRS) Interrupt number: %d \n", regs.int_no);
 | 
			
		||||
 | 
			
		||||
        if( regs.int_no == 13){
 | 
			
		||||
            printf(" Error code: %d \n", regs.err_code);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
  
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void irq_handler (registers regs) {
 | 
			
		||||
        
 | 
			
		||||
     
 | 
			
		||||
        if ( regs.int_no != 0) {
 | 
			
		||||
            kterm_writestring("received interrupt!\n");
 | 
			
		||||
            printf("(IRQ) Interrupt number: %d \n", regs.int_no);
 | 
			
		||||
        
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if ( regs.int_no == 1 ){
 | 
			
		||||
            // Keyboard interrupt !!
 | 
			
		||||
 | 
			
		||||
            int scan;
 | 
			
		||||
            /*register*/int i;
 | 
			
		||||
 | 
			
		||||
            // Read scancode 
 | 
			
		||||
 | 
			
		||||
            scan = inb(0x60);
 | 
			
		||||
            
 | 
			
		||||
            // Send ack message!
 | 
			
		||||
            i = inb(0x61);
 | 
			
		||||
            outb(0x61, i|0x80);
 | 
			
		||||
            outb(0x61, i);
 | 
			
		||||
            kterm_writestring("A key was pressed/released\n");
 | 
			
		||||
            printf( "Scancode: %x\n", scan);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        outb(0x20, 0x20); // send end of interrupt to master
 | 
			
		||||
 | 
			
		||||
        if ( regs.int_no > 8 && regs.int_no <= 15) {
 | 
			
		||||
            outb(0xA0, 0x20); // send end of interrupt to slave 
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
       
 | 
			
		||||
        if( regs.int_no == 13){
 | 
			
		||||
            printf(" Error code: %d \n", regs.err_code);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void init_idt(){
 | 
			
		||||
    // Initialise the IDT pointer
 | 
			
		||||
    idt_ptr.length = sizeof(IDT_entry) * 255;
 | 
			
		||||
    idt_ptr.base = (uint32_t)&idt_table;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // TODO: Set everything to zero first
 | 
			
		||||
 | 
			
		||||
    set_id_entry(0,  (uint32_t) irs0 , 0x08, 0x8F);
 | 
			
		||||
    set_id_entry(1,  (uint32_t) irs1 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(2,  (uint32_t) irs2 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(3,  (uint32_t) irs3 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(4,  (uint32_t) irs4 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(5,  (uint32_t) irs5 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(6,  (uint32_t) irs6 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(7,  (uint32_t) irs7 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(8,  (uint32_t) irs8 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(9,  (uint32_t) irs9 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); 
 | 
			
		||||
    set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); 
 | 
			
		||||
    set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //print_serial("Remapping PIC\n");
 | 
			
		||||
    PIC_remap(0x20, 0x28);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // pic IRQ Table
 | 
			
		||||
    set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    idt_flush((uint32_t)&idt_ptr);
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "../../drivers/vga/colors.h"
 | 
			
		||||
#include "../../drivers/pic/pic.h"
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
#include "stddef.h"
 | 
			
		||||
#include "../vga/colors.h"
 | 
			
		||||
#include "../pic/pic.h"
 | 
			
		||||
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#include "../tty/kterm.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
@ -22,7 +22,7 @@ unsigned int inl_p(unsigned short ){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void b_p(unsigned char , unsigned short ){
 | 
			
		||||
void outb_p(unsigned char , unsigned short ){
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
void outw(unsigned short , unsigned short ){
 | 
			
		||||
							
								
								
									
										60
									
								
								src/kernel/kernel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/kernel/kernel.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
#include "kernel.h"
 | 
			
		||||
#define GB4 524288
 | 
			
		||||
#define GB2 262144
 | 
			
		||||
extern "C" void kernel_main (void);
 | 
			
		||||
extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigned char addr , unsigned char pixelWidth, unsigned pitch );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    extern "C" void early_main(unsigned long magic, unsigned long addr){
 | 
			
		||||
        /** initialize terminal interface */ 
 | 
			
		||||
       // kterm_init();
 | 
			
		||||
        
 | 
			
		||||
        printf("Magic flag 0x%8x\n", magic);
 | 
			
		||||
        printf("Magic must be 0x%8x\n", MULTIBOOT_BOOTLOADER_MAGIC);
 | 
			
		||||
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
 | 
			
		||||
            printf("Invalid magic number: 0x%8x\n",  magic);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CheckMBT(  (multiboot_info_t *) addr);
 | 
			
		||||
 | 
			
		||||
        multiboot_info_t* mbt = (multiboot_info_t*) addr;
 | 
			
		||||
 | 
			
		||||
        /* Are mmap_* valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbt->flags, 6)){
 | 
			
		||||
            PhysicalMemoryManager_initialise( mbt->mmap_addr,  GB2/* Seriously dangerous hardcoded memory value*/);
 | 
			
		||||
            PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length);
 | 
			
		||||
            PhysicalMemoryManager_deinitialise_kernel();
 | 
			
		||||
            extern uint8_t* kernel_begin;
 | 
			
		||||
            extern uint8_t* kernel_end;
 | 
			
		||||
 | 
			
		||||
            printf("Kernel MemoryMap:\n");
 | 
			
		||||
            printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);         
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initGDT();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      kernel_main();
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern "C" void kernel_main (void) {
 | 
			
		||||
 | 
			
		||||
        printf("call to init serial\n");
 | 
			
		||||
        init_serial();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        while (true){
 | 
			
		||||
            //Read time indefinetely 
 | 
			
		||||
            read_rtc();
 | 
			
		||||
            printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d  [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
       
 | 
			
		||||
    }   
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
extern "C"{
 | 
			
		||||
   #include "../libc/include/string.h" 
 | 
			
		||||
}
 | 
			
		||||
#include "vga/VBE.h"
 | 
			
		||||
#include "tty/kterm.h"
 | 
			
		||||
 | 
			
		||||
#include "./bootloader/multiboot.h"
 | 
			
		||||
#include "bootcheck.h"
 | 
			
		||||
#include "memory/PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
#include "gdt/gdtc.h"
 | 
			
		||||
#include "idt/idt.h"
 | 
			
		||||
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "serial.h"
 | 
			
		||||
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
#define PANIC(message) {  return; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This needs to be moved! */
 | 
			
		||||
/**
 | 
			
		||||
 *      simple delay function 
 | 
			
		||||
 **/
 | 
			
		||||
void delay(int t){
 | 
			
		||||
    volatile int i,j;
 | 
			
		||||
    for(i=0;i<t;i++)
 | 
			
		||||
        for(j=0;j<25000;j++)
 | 
			
		||||
            asm("NOP");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/kernel/kstructures/bitmap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/kernel/kstructures/bitmap.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void bitmap_set( uint32_t* map , int index )
 | 
			
		||||
{
 | 
			
		||||
    map[index/32] |= (1 << (index % 32));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void bitmap_unset(uint32_t* map , int index)
 | 
			
		||||
{
 | 
			
		||||
    map[index/32] &= ~(1 << (index % 32));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int bitmap_first_unset( uint32_t* map , int size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t rem_bits = size % 32;
 | 
			
		||||
    for(uint32_t i = 0; i < size/32; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if(map[i] != 0xFFFFFFFF){
 | 
			
		||||
            for(int j = 0; j < 32; j++){
 | 
			
		||||
                if(!(map[i] & (1<< j))){
 | 
			
		||||
                    return (i*32) + j;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(rem_bits){
 | 
			
		||||
        for(uint32_t j = 0; j < rem_bits; j++){
 | 
			
		||||
            if(!(map[size/32] & (1 << j ))){
 | 
			
		||||
                return size + j; // Original author divided size by 32 and then multiplied it by 32 which is a net zero calculation ?!?
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/kernel/linker.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/kernel/linker.ld
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
/* The bootloader will look at this image and start execution at the symbol
 | 
			
		||||
   designated as the entry point. */
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
 
 | 
			
		||||
/* Tell where the various sections of the object files will be put in the final
 | 
			
		||||
   kernel image. */
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	/* Begin putting sections at 1 MiB, a conventional place for kernels to be
 | 
			
		||||
	   loaded at by the bootloader. */
 | 
			
		||||
	. = 1M;
 | 
			
		||||
 	kernel_begin = .;
 | 
			
		||||
	/* First put the multiboot header, as it is required to be put very early
 | 
			
		||||
	   early in the image or the bootloader won't recognize the file format.
 | 
			
		||||
	   Next we'll put the .text section. */
 | 
			
		||||
	.text BLOCK(4K) : ALIGN(4K)
 | 
			
		||||
	{
 | 
			
		||||
		*(.multiboot)
 | 
			
		||||
		*(.text)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
	/* Read-only data. */
 | 
			
		||||
	.rodata BLOCK(4K) : ALIGN(4K)
 | 
			
		||||
	{
 | 
			
		||||
		*(.rodata)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
	/* Read-write data (initialized) */
 | 
			
		||||
	.data BLOCK(4K) : ALIGN(4K)
 | 
			
		||||
	{
 | 
			
		||||
		*(.data)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
	/* Read-write data (uninitialized) and stack */
 | 
			
		||||
	.bss BLOCK(4K) : ALIGN(4K)
 | 
			
		||||
	{
 | 
			
		||||
		*(COMMON)
 | 
			
		||||
		*(.bss)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
	/* The compiler may produce other sections, by default it will put them in
 | 
			
		||||
	   a segment with the same name. Simply add stuff here as needed. */
 | 
			
		||||
 | 
			
		||||
	kernel_end = .;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								src/kernel/memory/PageDirectory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/kernel/memory/PageDirectory.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
#include "PageDirectory.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void PageDirectory::enable(){
 | 
			
		||||
    // https://wiki.osdev.org/Setting_Up_Paging
 | 
			
		||||
    //set each entry to not present
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i = 0; i < 1024; i++)
 | 
			
		||||
    {
 | 
			
		||||
        // This sets the following flags to the pages:
 | 
			
		||||
        //   Supervisor: Only kernel-mode can access them
 | 
			
		||||
        //   Write Enabled: It can be both read from and written to
 | 
			
		||||
        //   Not Present: The page table is not present
 | 
			
		||||
        this->page_directory[i] = 0x00000002;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // holds the physical address where we want to start mapping these pages to.
 | 
			
		||||
    // in this case, we want to map these pages to the very beginning of memory.
 | 
			
		||||
 | 
			
		||||
    //we will fill all 1024 entries in the table, mapping 4 megabytes
 | 
			
		||||
    for(unsigned int i = 0; i < 1024; i++)
 | 
			
		||||
    {
 | 
			
		||||
        // As the address is page aligned, it will always leave 12 bits zeroed.
 | 
			
		||||
        // Those bits are used by the attributes ;)
 | 
			
		||||
        first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // attributes: supervisor level, read/write, present
 | 
			
		||||
    this->page_directory[0] = ((unsigned int)first_page_table) | 3;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    loadPageDirectory(this->page_directory);
 | 
			
		||||
    enablePaging();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
 | 
			
		||||
{
 | 
			
		||||
    from = from & 0xFFFFF000; // Discard the bits we don't want
 | 
			
		||||
    for (; size > 0; from += 4096, first_pte++)
 | 
			
		||||
    {
 | 
			
		||||
        *first_pte = from | 1; // makr page present.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										28
									
								
								src/kernel/memory/PageDirectory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/kernel/memory/PageDirectory.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
extern "C" void loadPageDirectory (uint32_t* addr );
 | 
			
		||||
extern "C" void enablePaging();
 | 
			
		||||
typedef uintptr_t address_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define KB 1024
 | 
			
		||||
 | 
			
		||||
static const int MAX_PAGES =  1024 * KB; // 4GB , 4kB/page
 | 
			
		||||
static volatile address_t pmem_stack[MAX_PAGES];
 | 
			
		||||
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct page_directory_entry {};
 | 
			
		||||
struct page_table_entry{};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PageDirectory {
 | 
			
		||||
    public:
 | 
			
		||||
    void enable ();
 | 
			
		||||
    
 | 
			
		||||
    private:
 | 
			
		||||
    uint32_t page_directory[1024] __attribute__((aligned(4096)));
 | 
			
		||||
    uint32_t first_page_table[1024] __attribute__((aligned(4096)));
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										38
									
								
								src/kernel/memory/PageFrameAllocator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/kernel/memory/PageFrameAllocator.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
#include "PageFrameAllocator.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MemoryInfo memInfo {};
 | 
			
		||||
void mapMultibootMemoryMap( multiboot_info_t *mbt){
 | 
			
		||||
    printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
 | 
			
		||||
    (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
 | 
			
		||||
    multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
 | 
			
		||||
 | 
			
		||||
    for (;  (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length;  mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
 | 
			
		||||
 | 
			
		||||
            if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
 | 
			
		||||
                memInfo.memorySizeInBytes +=  mmap->len;   
 | 
			
		||||
            } else {
 | 
			
		||||
                memInfo.reservedMemoryInBytes += mmap->len;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            print_Multiboot_memory_Map(mmap);
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
    uint32_t memorySizeInGiB = memInfo.memorySizeInBytes / 1073741824; 
 | 
			
		||||
 | 
			
		||||
    printf("Available Memory: 0x%x bytes, 0x%x GiB\n",  memInfo.memorySizeInBytes, memorySizeInGiB );
 | 
			
		||||
    printf("Reserved Memory: 0x%x bytes\n",  memInfo.reservedMemoryInBytes );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap){
 | 
			
		||||
    printf(
 | 
			
		||||
        "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
 | 
			
		||||
        (unsigned) mmap->size,
 | 
			
		||||
        (unsigned) (mmap->addr >> 32),
 | 
			
		||||
        (unsigned) (mmap->addr & 0xffffffff),
 | 
			
		||||
        (unsigned) (mmap->len >> 32),
 | 
			
		||||
        (unsigned) (mmap->len & 0xffffffff),
 | 
			
		||||
        (unsigned) mmap->type
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/kernel/memory/PageFrameAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/kernel/memory/PageFrameAllocator.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../arch/i386/tty/kterm.h"
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../bootloader/multiboot.h"
 | 
			
		||||
 | 
			
		||||
struct MemoryInfo{
 | 
			
		||||
    uint32_t memorySizeInBytes = 0;
 | 
			
		||||
    uint32_t reservedMemoryInBytes = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void *kernel_begin;
 | 
			
		||||
extern void *kernel_end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void print_Multiboot_memory_Map(multiboot_memory_map_t*);
 | 
			
		||||
void mapMultibootMemoryMap(multiboot_info_t*);
 | 
			
		||||
							
								
								
									
										118
									
								
								src/kernel/memory/PhysicalMemoryManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/kernel/memory/PhysicalMemoryManager.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,118 @@
 | 
			
		||||
#include "PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
size_t mem_size = 0;
 | 
			
		||||
int used_blocks = 0;
 | 
			
		||||
size_t max_blocks = 0;
 | 
			
		||||
uint32_t* pmmap = 0;
 | 
			
		||||
size_t pmmap_size = 0; 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_initialise(uint32_t physicalmemorymap_address, size_t size )
 | 
			
		||||
{
 | 
			
		||||
    mem_size = size;
 | 
			
		||||
    max_blocks = KB_TO_BLOCKS(mem_size);
 | 
			
		||||
 | 
			
		||||
    used_blocks = max_blocks;
 | 
			
		||||
 | 
			
		||||
    pmmap = (uint32_t*) physicalmemorymap_address;
 | 
			
		||||
 | 
			
		||||
    if(max_blocks % BLOCKS_PER_WORD)
 | 
			
		||||
        pmmap_size++;
 | 
			
		||||
    
 | 
			
		||||
    memset(pmmap, 0xFF, pmmap_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_region_initialise(uint32_t base, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    size_t blocks = size /BLOCK_SIZE;
 | 
			
		||||
    uint32_t align = base / BLOCK_SIZE;
 | 
			
		||||
 | 
			
		||||
    for(size_t i = 0 ; i < blocks; i ++)
 | 
			
		||||
    {
 | 
			
		||||
        bitmap_unset(pmmap, align++);
 | 
			
		||||
        used_blocks--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bitmap_set(pmmap, 0);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_region_deinitialise(uint32_t base, size_t size )
 | 
			
		||||
{
 | 
			
		||||
    size_t blocks = size / BLOCK_SIZE;
 | 
			
		||||
    uint32_t align = base / BLOCK_SIZE;
 | 
			
		||||
 | 
			
		||||
    for(size_t i = 0 ; i < blocks; i++ )
 | 
			
		||||
    {
 | 
			
		||||
        bitmap_set(pmmap, align++);
 | 
			
		||||
        used_blocks++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_initialise_available_regions(uint32_t mmap_, uint32_t mmap_end_)
 | 
			
		||||
{
 | 
			
		||||
    multiboot_memory_map_t *mmap = (multiboot_memory_map_t*)mmap_;
 | 
			
		||||
    multiboot_memory_map_t *mmap_end= (multiboot_memory_map_t*) mmap_end_;
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; mmap < mmap_end ; mmap++, i++)
 | 
			
		||||
    {   
 | 
			
		||||
        if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE)
 | 
			
		||||
        {
 | 
			
		||||
            PhysicalMemoryManager_region_initialise((uint32_t) mmap->addr, (size_t) mmap->len);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_deinitialise_kernel()
 | 
			
		||||
{
 | 
			
		||||
    extern uint8_t kernel_begin;
 | 
			
		||||
    extern uint8_t kernel_end;
 | 
			
		||||
 | 
			
		||||
    size_t kernel_size = (size_t) &kernel_end - (size_t) &kernel_begin;
 | 
			
		||||
 | 
			
		||||
    uint32_t pmmap_size_aligned = pmmap_size;
 | 
			
		||||
    if(!IS_ALIGNED(pmmap_size_aligned, BLOCK_SIZE))
 | 
			
		||||
    {
 | 
			
		||||
        pmmap_size_aligned = ALIGN(pmmap_size_aligned, BLOCK_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_begin, kernel_size);
 | 
			
		||||
    PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_end, pmmap_size_aligned);
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* PhysicalMemoryManager_allocate_block()
 | 
			
		||||
{
 | 
			
		||||
    if(used_blocks - max_blocks <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int p_index = bitmap_first_unset(pmmap, p_index );
 | 
			
		||||
 | 
			
		||||
    if(p_index == -1){
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bitmap_set(pmmap, p_index);
 | 
			
		||||
    used_blocks++;
 | 
			
		||||
 | 
			
		||||
    return (void*) (BLOCK_SIZE * p_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PhysicalMemoryManager_free_block(void* p){
 | 
			
		||||
    if(p==0){
 | 
			
		||||
        return ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t p_addr = (uint32_t) p;
 | 
			
		||||
 | 
			
		||||
    int index  = p_addr / BLOCK_SIZE;
 | 
			
		||||
    bitmap_unset(pmmap, index);
 | 
			
		||||
 | 
			
		||||
    used_blocks--;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								src/kernel/memory/PhysicalMemoryManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/kernel/memory/PhysicalMemoryManager.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../bootloader/multiboot.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "../../libc/include/mem.h"
 | 
			
		||||
#include "../kstructures/bitmap.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BLOCK_SIZE 4092
 | 
			
		||||
#define BLOCKS_PER_WORD 32
 | 
			
		||||
 | 
			
		||||
#define KB_TO_BLOCKS(x) (((x) * 1024 ) / BLOCK_SIZE)
 | 
			
		||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void PhysicalMemoryManager_initialise(uint32_t, size_t);
 | 
			
		||||
 | 
			
		||||
extern void PhysicalMemoryManager_region_initialise(uint32_t, size_t);
 | 
			
		||||
extern void PhysicalMemoryManager_region_deinitialise(uint32_t,size_t);
 | 
			
		||||
 | 
			
		||||
extern void PhysicalMemoryManager_initialise_available_regions(uint32_t, uint32_t);
 | 
			
		||||
extern void PhysicalMemoryManager_deinitialise_kernel();
 | 
			
		||||
 | 
			
		||||
extern void* PhysicalMemoryManager_allocate_block();
 | 
			
		||||
extern void PhysicalMemoryManager_free_block(void* p);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t mem_size;
 | 
			
		||||
extern int used_blocks;
 | 
			
		||||
extern size_t max_blocks;
 | 
			
		||||
extern uint32_t* pmmap;
 | 
			
		||||
extern size_t pmmap_size ; 
 | 
			
		||||
							
								
								
									
										33
									
								
								src/kernel/memory/SlabAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/kernel/memory/SlabAllocator.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
/**
 | 
			
		||||
 *  We'll need something to this effect to allocate memory in the kernel
 | 
			
		||||
 *  this will hopefully someday implement a full slab allocator 
 | 
			
		||||
 **/
 | 
			
		||||
enum SlabState {
 | 
			
		||||
    empty,
 | 
			
		||||
    partial,
 | 
			
		||||
    full 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class CacheSlab {
 | 
			
		||||
    const int SlabSize = 4000;
 | 
			
		||||
    void* start = 0x0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Allocator {
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        Allocator();
 | 
			
		||||
        ~Allocator();
 | 
			
		||||
 | 
			
		||||
        void* kmalloc( int size );
 | 
			
		||||
        void kfree (void* address);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        CacheSlab** _cache;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										20
									
								
								src/kernel/paging.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/kernel/paging.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
.globl enablePaging
 | 
			
		||||
enablePaging:
 | 
			
		||||
	push %ebp
 | 
			
		||||
	mov %esp, %ebp
 | 
			
		||||
	mov %cr0, %eax
 | 
			
		||||
	or $0x80000000, %eax
 | 
			
		||||
	mov %eax, %cr0
 | 
			
		||||
	mov %ebp, %esp
 | 
			
		||||
	pop %ebp
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.globl loadPageDirectory
 | 
			
		||||
loadPageDirectory:
 | 
			
		||||
	push %ebp
 | 
			
		||||
	mov %esp, %ebp
 | 
			
		||||
	mov 8(%esp), %eax
 | 
			
		||||
	mov %eax, %cr3
 | 
			
		||||
	mov %ebp, %esp
 | 
			
		||||
	pop %ebp
 | 
			
		||||
	ret
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../../io.h"
 | 
			
		||||
#include "../io.h"
 | 
			
		||||
 | 
			
		||||
#define PIC1		0x20		/* IO base address for master PIC */
 | 
			
		||||
#define PIC2		0xA0		/* IO base address for slave PIC */
 | 
			
		||||
							
								
								
									
										133
									
								
								src/kernel/serial.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/kernel/serial.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,133 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "tty/kterm.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
 | 
			
		||||
#define PORT 0x3f8 
 | 
			
		||||
 | 
			
		||||
inline static int init_serial() {
 | 
			
		||||
   outb(PORT + 1, 0x00);    // Disable all interrupts
 | 
			
		||||
   outb(PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
 | 
			
		||||
   outb(PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
 | 
			
		||||
   outb(PORT + 1, 0x00);    //                  (hi byte)
 | 
			
		||||
   outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
 | 
			
		||||
   outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
 | 
			
		||||
   outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
 | 
			
		||||
   outb(PORT + 4, 0x1E);    // Set in loopback mode, test the serial chip
 | 
			
		||||
   outb(PORT + 0, 0xAE);    // Test serial chip (send byte 0xAE and check if serial returns same byte)
 | 
			
		||||
 
 | 
			
		||||
   // Check if serial is faulty (i.e: not same byte as sent)
 | 
			
		||||
   if(inb(PORT + 0) != 0xAE) {
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
   // If serial is not faulty set it in normal operation mode
 | 
			
		||||
   // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
 | 
			
		||||
   outb(PORT + 4, 0x0F);
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int is_transmit_empty() {
 | 
			
		||||
   return inb(PORT + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
inline void write_serial(char a) {
 | 
			
		||||
   while (is_transmit_empty() == 0);
 | 
			
		||||
 
 | 
			
		||||
   outb(PORT,a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int serial_received() {
 | 
			
		||||
   return inb(PORT + 5) & 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
inline char read_serial() {
 | 
			
		||||
   while (serial_received() == 0);
 | 
			
		||||
 
 | 
			
		||||
   return inb(PORT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void print_serial(const char* string ){
 | 
			
		||||
    for(size_t i = 0; i < strlen(string); i ++){
 | 
			
		||||
        write_serial(string[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void printf_serial ( const char *format, ...) {
 | 
			
		||||
   
 | 
			
		||||
    char **arg = (char **)&format;
 | 
			
		||||
    int c;
 | 
			
		||||
    char buf[20];
 | 
			
		||||
 | 
			
		||||
    arg++;
 | 
			
		||||
    
 | 
			
		||||
    while ((c = *format++) != 0){
 | 
			
		||||
        if( c != '%')
 | 
			
		||||
            write_serial(c);
 | 
			
		||||
        else{
 | 
			
		||||
            char *p, *p2;
 | 
			
		||||
            int pad0 = 0, pad = 0;
 | 
			
		||||
 | 
			
		||||
            c = *format++;
 | 
			
		||||
            if(c =='0'){
 | 
			
		||||
                pad0 = 1;
 | 
			
		||||
                c = *format++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( c >= '0' && c <= '9'){
 | 
			
		||||
                pad = c - '0';
 | 
			
		||||
                c = *format++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (c)
 | 
			
		||||
            {
 | 
			
		||||
            case 'd':
 | 
			
		||||
             
 | 
			
		||||
            case 'u':
 | 
			
		||||
            case 'x':
 | 
			
		||||
                itoa(buf, c, *((int *) arg++));
 | 
			
		||||
 | 
			
		||||
                p = buf;
 | 
			
		||||
                goto string;
 | 
			
		||||
                break;
 | 
			
		||||
            
 | 
			
		||||
            case 's':
 | 
			
		||||
                p = *arg++;
 | 
			
		||||
                if(!p)
 | 
			
		||||
                    p = "(null)";
 | 
			
		||||
                
 | 
			
		||||
                string: 
 | 
			
		||||
                    for (p2 = p; *p2; p2++);
 | 
			
		||||
                    for (; p2 < p + pad; p2++)
 | 
			
		||||
                        write_serial(pad0 ? '0': ' ');
 | 
			
		||||
                    while (*p)
 | 
			
		||||
                        write_serial(*p++);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                write_serial(*((int *)arg++));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
        kterm_writestring("Writing to COM1 serial port:");
 | 
			
		||||
        init_serial();
 | 
			
		||||
        write_serial('A');
 | 
			
		||||
        write_serial('B');
 | 
			
		||||
        write_serial('C');
 | 
			
		||||
        write_serial('D');
 | 
			
		||||
        write_serial('E');
 | 
			
		||||
 | 
			
		||||
        char Character_received = read_serial();
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
        kterm_writestring("received from COM 1: \n");
 | 
			
		||||
        kterm_put(Character_received);
 | 
			
		||||
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include "time.h"
 | 
			
		||||
 | 
			
		||||
// Set by ACPI table parsing code if possible
 | 
			
		||||
int century_register = 0x00;     
 | 
			
		||||
#define CURRENT_YEAR        2021                            // Change this each year!
 | 
			
		||||
 
 | 
			
		||||
int century_register = 0x00;                                // Set by ACPI table parsing code if possible
 | 
			
		||||
 
 | 
			
		||||
unsigned char second;
 | 
			
		||||
unsigned char minute;
 | 
			
		||||
unsigned char hour;
 | 
			
		||||
@ -10,6 +10,12 @@ unsigned char month;
 | 
			
		||||
unsigned int year;
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
enum {
 | 
			
		||||
      cmos_address = 0x70,
 | 
			
		||||
      cmos_data    = 0x71
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
int get_update_in_progress_flag() {
 | 
			
		||||
      outb(cmos_address, 0x0A);
 | 
			
		||||
      return (inb(cmos_data) & 0x80);
 | 
			
		||||
@ -103,9 +109,45 @@ void read_rtc() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void delay(int t){
 | 
			
		||||
    volatile int i,j;
 | 
			
		||||
    for(i=0;i<t;i++)
 | 
			
		||||
        for(j=0;j<25000;j++)
 | 
			
		||||
            asm("NOP");
 | 
			
		||||
/*
 | 
			
		||||
void ReadFromCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
    unsigned char tvalue, index;
 | 
			
		||||
 | 
			
		||||
    for (index = 0; index < 128; index++)
 | 
			
		||||
    {
 | 
			
		||||
        asm(
 | 
			
		||||
            "cli\n\t"           // Disable interrupts
 | 
			
		||||
            "mov al, index\n\t" // Move index address
 | 
			
		||||
            // since the 0x80 bit of al is not set, NMI is active 
 | 
			
		||||
            "out 0x70,al\n\t" // Copy address to CMOS register
 | 
			
		||||
            // some kind of real delay here is probably best 
 | 
			
		||||
            "in al,0x71\n\t" // Fetch 1 byte to al
 | 
			
		||||
            "sti\n\t"        // Enable interrupts
 | 
			
		||||
            "mov tvalue,al\n\t");
 | 
			
		||||
 | 
			
		||||
        array[index] = tvalue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void WriteTOCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
   unsigned char index;
 | 
			
		||||
 
 | 
			
		||||
   for(index = 0; index < 128; index++)
 | 
			
		||||
   {
 | 
			
		||||
      unsigned char tvalue = array[index];
 | 
			
		||||
      
 | 
			
		||||
       asm("cli\n\t"       // Clear interrupts
 | 
			
		||||
         "mov al,index\n\t"    // move index address
 | 
			
		||||
         "out 0x70,al\n\t"     // copy address to CMOS register
 | 
			
		||||
         // some kind of real delay here is probably best 
 | 
			
		||||
         "mov al,tvalue\n\t"   // move value to al
 | 
			
		||||
         "out 0x71,al\n\t"   // write 1 byte to CMOS
 | 
			
		||||
         "sti\n\\t"   );        // Enable interrupts
 | 
			
		||||
      
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
@ -21,8 +21,7 @@ void kterm_init () {
 | 
			
		||||
    kterm_row = 0;
 | 
			
		||||
    kterm_column = 0;
 | 
			
		||||
    kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
 | 
			
		||||
    kterm_buffer = (uint16_t*) 0xC03FF000;
 | 
			
		||||
    
 | 
			
		||||
    kterm_buffer = (uint16_t*) 0xB8000;
 | 
			
		||||
    for (size_t y = 0; y < VGA_HEIGHT; y++ ){
 | 
			
		||||
        for( size_t x = 0; x < VGA_WIDTH; x++){
 | 
			
		||||
            const size_t index = y * VGA_WIDTH + x;
 | 
			
		||||
@ -32,6 +31,7 @@ void kterm_init () {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void kterm_resetcolor(){
 | 
			
		||||
     kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
 | 
			
		||||
}
 | 
			
		||||
@ -42,7 +42,9 @@ void kterm_setcolor(uint8_t color){
 | 
			
		||||
 | 
			
		||||
void kterm_putat (char c, uint8_t color, size_t x, size_t y ) {
 | 
			
		||||
    const size_t index = y * VGA_WIDTH + x;
 | 
			
		||||
 | 
			
		||||
    kterm_buffer[index] = vga_entry(c, color);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){
 | 
			
		||||
@ -135,7 +137,7 @@ void kterm_writestring(const char* data ){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d) {
 | 
			
		||||
void itoa (char *buf, int base, int d) {
 | 
			
		||||
    char *p = buf;
 | 
			
		||||
    char *p1, *p2;
 | 
			
		||||
    unsigned long ud = d;
 | 
			
		||||
@ -172,7 +174,7 @@ static void itoa (char *buf, int base, int d) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...) {
 | 
			
		||||
    
 | 
			
		||||
    return;
 | 
			
		||||
    char **arg = (char **)&format;
 | 
			
		||||
    int c;
 | 
			
		||||
    char buf[20];
 | 
			
		||||
@ -1,13 +1,15 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include "../drivers/vga/colors.h"
 | 
			
		||||
#include "../vga/colors.h"
 | 
			
		||||
#include "../io.h"
 | 
			
		||||
 | 
			
		||||
#include "../lib/string.h"
 | 
			
		||||
 | 
			
		||||
extern "C"{
 | 
			
		||||
    #include "./../../libc/include/string.h"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kterm_init();
 | 
			
		||||
 | 
			
		||||
@ -31,6 +33,13 @@ uint16_t get_cursor_position();
 | 
			
		||||
int get_cursor_x (uint16_t cursor_pos);
 | 
			
		||||
int get_cursor_y (uint16_t cursor_pos);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C"  void itoa (char *buf, int base, int d);
 | 
			
		||||
void printf ( const char *format, ...);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define KernelTag "[Kernel]: "
 | 
			
		||||
#define AS_KERNEL() (  kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
 | 
			
		||||
                       kterm_write(KernelTag, 10 ), \
 | 
			
		||||
                       kterm_resetcolor())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
inline void* memset (void* ptr, int value, size_t num){
 | 
			
		||||
    for( int i = 0; i < num; i++ )
 | 
			
		||||
    {
 | 
			
		||||
        unsigned char* data  = (unsigned char*)ptr+ i;
 | 
			
		||||
        *data = (unsigned char)value;
 | 
			
		||||
        int* data  = (int*)ptr+ i;
 | 
			
		||||
        *data = value;
 | 
			
		||||
    }
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/libc/include/string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/libc/include/string.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
#include "string.h"
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char* str) {
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
    while(str[len]){
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,3 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
size_t strlen(const char* str);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num );
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user