Merge into main the new state of the operating system/kernel #1
							
								
								
									
										13
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile
									
									
									
									
									
								
							@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++ 
 | 
			
		||||
CFLAGS =  -ffreestanding -O2 -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
OFILES =	$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o
 | 
			
		||||
OFILES =	$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o
 | 
			
		||||
 | 
			
		||||
SRC_DIR = src
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
@ -24,7 +24,7 @@ all: clean build
 | 
			
		||||
build: build_kernel run 
 | 
			
		||||
 | 
			
		||||
run:
 | 
			
		||||
	$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio
 | 
			
		||||
	$(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std
 | 
			
		||||
 | 
			
		||||
build_kernel: $(OBJ_LINK_LIST)
 | 
			
		||||
	
 | 
			
		||||
@ -55,5 +55,12 @@ $(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)/MMU.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti 
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti 
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ ________________________
 | 
			
		||||
The first scrolling boot screen. 😲
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<img src="screenshots/WIP_interruptHandling.png"></img>
 | 
			
		||||
W.I.P - Working on interrupt handling
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
 | 
			
		||||
### The goal
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								screenshots/Screenshot from 2021-06-21 14-26-39.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/Screenshot from 2021-06-21 14-26-39.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								screenshots/WIP_interruptHandling.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/WIP_interruptHandling.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -20,10 +20,430 @@ stack_bottom:
 | 
			
		||||
.skip 16384 # 16 KiB
 | 
			
		||||
stack_top:
 | 
			
		||||
 
 | 
			
		||||
.section .text
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Interupt handlers
 | 
			
		||||
*/
 | 
			
		||||
# NOTE: I have no clue how I should use these macros.
 | 
			
		||||
# Have tried to use them in a myriad of ways, none would actually work
 | 
			
		||||
.macro irs_NoErrCode code:req
 | 
			
		||||
	.globl irs\code
 | 
			
		||||
	irs\code:
 | 
			
		||||
		cli 
 | 
			
		||||
		pushb $0
 | 
			
		||||
		pushb \code
 | 
			
		||||
		jmp irs_common
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
.macro irs_ErrCode code
 | 
			
		||||
	.globl irs\code
 | 
			
		||||
	irs\code:
 | 
			
		||||
		cli
 | 
			
		||||
		pushb \code
 | 
			
		||||
		jmp irs_common
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
.globl irs0
 | 
			
		||||
irs0:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $0
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs1
 | 
			
		||||
irs1:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $1
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs2
 | 
			
		||||
irs2:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $2
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs3
 | 
			
		||||
irs3:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $3
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs4
 | 
			
		||||
irs4:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $4
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs5
 | 
			
		||||
irs5:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $5
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs6
 | 
			
		||||
irs6:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $6
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs7
 | 
			
		||||
irs7:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $7
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs8
 | 
			
		||||
irs8:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $8
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs9
 | 
			
		||||
irs9:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $9
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs10
 | 
			
		||||
irs10:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $10
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs11
 | 
			
		||||
irs11:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $11
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs12
 | 
			
		||||
irs12:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $12
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs13
 | 
			
		||||
irs13:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $13
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs14
 | 
			
		||||
irs14:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $14
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs15
 | 
			
		||||
irs15:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $15
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs16
 | 
			
		||||
irs16:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $16
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs17
 | 
			
		||||
irs17:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $17
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs18
 | 
			
		||||
irs18:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $18
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs19
 | 
			
		||||
irs19:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $19
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs20
 | 
			
		||||
irs20:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $20
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs21
 | 
			
		||||
irs21:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $21
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs22
 | 
			
		||||
irs22:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $22
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs23
 | 
			
		||||
irs23:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $23
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs24
 | 
			
		||||
irs24:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $24
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs25
 | 
			
		||||
irs25:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $25
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs26
 | 
			
		||||
irs26:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $26
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs27
 | 
			
		||||
irs27:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $27
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs28
 | 
			
		||||
irs28:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $28
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs29
 | 
			
		||||
irs29:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $29
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs30
 | 
			
		||||
irs30:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $30
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
.globl irs31
 | 
			
		||||
irs31:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $31
 | 
			
		||||
	jmp irs_common
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.globl irq0
 | 
			
		||||
irq0:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $0
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq1
 | 
			
		||||
irq1:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $1
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq2
 | 
			
		||||
irq2:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $2
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq3
 | 
			
		||||
irq3:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $3
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq4
 | 
			
		||||
irq4:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $4
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq5
 | 
			
		||||
irq5:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $5
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq6
 | 
			
		||||
irq6:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $6
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq7
 | 
			
		||||
irq7:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $7
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq8
 | 
			
		||||
irq8:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $8
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq9
 | 
			
		||||
irq9:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $9
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq10
 | 
			
		||||
irq10:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $10
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq11
 | 
			
		||||
irq11:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $11
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.globl irq12
 | 
			
		||||
irq12:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $12
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq13
 | 
			
		||||
irq13:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $13
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq14
 | 
			
		||||
irq14:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $14
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
.globl irq15
 | 
			
		||||
irq15:
 | 
			
		||||
	cli 
 | 
			
		||||
	push $0
 | 
			
		||||
	push $15
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
irq_common:
 | 
			
		||||
	pusha
 | 
			
		||||
 | 
			
		||||
	mov %ds, %ax
 | 
			
		||||
	push %eax
 | 
			
		||||
 | 
			
		||||
	mov $0x10, %ax
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	call irq_handler
 | 
			
		||||
 | 
			
		||||
	pop %eax
 | 
			
		||||
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	popa
 | 
			
		||||
	add  $8, %esp  # cleans push error and irs code
 | 
			
		||||
	sti
 | 
			
		||||
	iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
irs_common:
 | 
			
		||||
	pusha 				# Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	mov %ds, %ax
 | 
			
		||||
	push %eax
 | 
			
		||||
 | 
			
		||||
	/* load the kernel data segment descriptor*/
 | 
			
		||||
 | 
			
		||||
	mov $0x10, %ax
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	call irs_handler
 | 
			
		||||
 | 
			
		||||
	pop %eax
 | 
			
		||||
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	popa
 | 
			
		||||
	add  $8, %esp  # cleans push error and irs code
 | 
			
		||||
	sti
 | 
			
		||||
	iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
 | 
			
		||||
 | 
			
		||||
.globl idt_flush
 | 
			
		||||
idt_flush:
 | 
			
		||||
	mov 4(%esp), %eax
 | 
			
		||||
	lidt (%eax)
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.globl enablePaging
 | 
			
		||||
enablePaging:
 | 
			
		||||
	push %ebp
 | 
			
		||||
@ -35,7 +455,6 @@ enablePaging:
 | 
			
		||||
	pop %ebp
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.globl loadPageDirectory
 | 
			
		||||
loadPageDirectory:
 | 
			
		||||
	push %ebp
 | 
			
		||||
@ -46,25 +465,91 @@ loadPageDirectory:
 | 
			
		||||
	pop %ebp
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.section .text
 | 
			
		||||
.global _start
 | 
			
		||||
.type _start, @function
 | 
			
		||||
_start:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
	/*Setup the stack pointer to point to the beginning of our stack */
 | 
			
		||||
	/* I believe its a hight address growing down to lower adress for the stack on x86*/
 | 
			
		||||
	mov $stack_top, %esp
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	call _init
 | 
			
		||||
	call kernel_main
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
	call early_main
 | 
			
		||||
	cli
 | 
			
		||||
1:	hlt
 | 
			
		||||
	jmp 1b
 | 
			
		||||
 
 | 
			
		||||
	load_gdt:
 | 
			
		||||
		lgdt gdt
 | 
			
		||||
 | 
			
		||||
.size _start, . - _start
 | 
			
		||||
		# set the segment selecters
 | 
			
		||||
 | 
			
		||||
		movw $0x10, %ax 
 | 
			
		||||
		movw %ax, %ds
 | 
			
		||||
		movw %ax, %es
 | 
			
		||||
		movw %ax, %fs
 | 
			
		||||
		movw %ax, %gs
 | 
			
		||||
		movw %ax, %ss
 | 
			
		||||
		ljmp $0x08, $flush 
 | 
			
		||||
		
 | 
			
		||||
		flush:
 | 
			
		||||
        
 | 
			
		||||
		
 | 
			
		||||
		#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
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	/* Tell processor to use our gdt*/
 | 
			
		||||
	gdt: 
 | 
			
		||||
		.word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons
 | 
			
		||||
		.int gdt_start # linear address of our GDT
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
.att_syntax
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.size _start, . - _start
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Create the GDT
 | 
			
		||||
*/
 | 
			
		||||
.section .data
 | 
			
		||||
gdt_start:
 | 
			
		||||
gdt_null:
 | 
			
		||||
.long 0x0
 | 
			
		||||
.long 0x0
 | 
			
		||||
 | 
			
		||||
gdt_kcode:
 | 
			
		||||
.word 0xFFFF             # limit
 | 
			
		||||
.word 0x0                # base
 | 
			
		||||
.byte 0x0                # base
 | 
			
		||||
.byte 0b10011010         # 1st flags | type flags
 | 
			
		||||
.byte 0b11001111         # 2nd flags | limit
 | 
			
		||||
.byte 0x0                # base
 | 
			
		||||
 | 
			
		||||
gdt_kdata:
 | 
			
		||||
.word 0xFFFF             # limit
 | 
			
		||||
.word 0x0                # base
 | 
			
		||||
.byte 0x0                # base
 | 
			
		||||
.byte 0b10010010         # 1st flags | type flags
 | 
			
		||||
.byte 0b11001111         # 2nd flags | limit
 | 
			
		||||
.byte 0x0                # base
 | 
			
		||||
gdt_end:
 | 
			
		||||
							
								
								
									
										29
									
								
								src/kernel/arch/i386/gdt/gdtc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/kernel/arch/i386/gdt/gdtc.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
#include "gdtc.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
gdtEntry_t gdt[3];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
 | 
			
		||||
   uint8_t gran){
 | 
			
		||||
   gdt[num].lBase      = (base & 0xFFFF);
 | 
			
		||||
   gdt[num].mBase      = (base >> 16) & 0xFF;
 | 
			
		||||
   gdt[num].hBase      = (base >> 24) & 0xFF;
 | 
			
		||||
 | 
			
		||||
   gdt[num].lLimit      = (limit & 0xFFFF);
 | 
			
		||||
   gdt[num].granularity   = ((limit >> 16) & 0x0F);
 | 
			
		||||
 | 
			
		||||
   gdt[num].granularity   |= (gran & 0xF0);
 | 
			
		||||
   gdt[num].access      = access;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setupGdt(){
 | 
			
		||||
   gdtPointer.limit   = (sizeof(gdtEntry_t) * 3) - 1;
 | 
			
		||||
   gdtPointer.base      = &gdt;
 | 
			
		||||
 | 
			
		||||
   gdtSetGate(0, 0, 0, 0, 0);
 | 
			
		||||
   gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
 | 
			
		||||
   gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
 | 
			
		||||
 | 
			
		||||
   loadGdt();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/kernel/arch/i386/gdt/gdtc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/kernel/arch/i386/gdt/gdtc.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
extern "c"{
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
   uint16_t           lLimit;
 | 
			
		||||
   uint16_t           lBase;
 | 
			
		||||
   uint8_t            mBase;
 | 
			
		||||
   uint8_t            access;
 | 
			
		||||
   uint8_t            granularity;
 | 
			
		||||
   uint8_t            hBase;
 | 
			
		||||
} gdtEntry_t;
 | 
			
		||||
 | 
			
		||||
struct {
 | 
			
		||||
   uint16_t limit;
 | 
			
		||||
   uint32_t base;
 | 
			
		||||
} gdtPointer;
 | 
			
		||||
 | 
			
		||||
extern void loadGdt();
 | 
			
		||||
void setupGdt();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								src/kernel/arch/i386/idt/idt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								src/kernel/arch/i386/idt/idt.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,146 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								src/kernel/arch/i386/idt/idt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/kernel/arch/i386/idt/idt.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
#include "stddef.h"
 | 
			
		||||
#include "../vga/colors.h"
 | 
			
		||||
#include "../pic/pic.h"
 | 
			
		||||
 | 
			
		||||
extern "C"{
 | 
			
		||||
    #include "../tty/kterm.h"
 | 
			
		||||
}
 | 
			
		||||
#define AS_KERNEL() (  kterm_writestring("[KERNEL]:"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
    struct __attribute__((__packed__)) IDT_entry {
 | 
			
		||||
        uint16_t offset_1;
 | 
			
		||||
        uint16_t selector;
 | 
			
		||||
        uint8_t zero;
 | 
			
		||||
        uint8_t type_attr;
 | 
			
		||||
        uint16_t offset_2;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct __attribute__((__packed__)) IDT_ptr {
 | 
			
		||||
        unsigned short length;
 | 
			
		||||
        unsigned long base;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct registers {
 | 
			
		||||
        uint32_t ds;                  // Data segment selector
 | 
			
		||||
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
 | 
			
		||||
        uint32_t int_no, err_code;    // Interrupt number and error code (if applicable)
 | 
			
		||||
        uint32_t eip, cs, eflags, useresp, ss; 
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    extern void idt_flush(uint32_t); 
 | 
			
		||||
    void set_id_entry (uint8_t num , uint32_t base, uint16_t sel,  uint8_t flags);
 | 
			
		||||
    void init_idt();
 | 
			
		||||
 | 
			
		||||
    void irq_handler (registers regs);
 | 
			
		||||
 | 
			
		||||
    void irs_handler (registers regs);
 | 
			
		||||
 | 
			
		||||
    extern void irs0 ();
 | 
			
		||||
    extern void irs1 ();
 | 
			
		||||
    extern void irs2 ();
 | 
			
		||||
    extern void irs3 ();
 | 
			
		||||
    extern void irs4 ();
 | 
			
		||||
    extern void irs5 ();
 | 
			
		||||
    extern void irs6 ();
 | 
			
		||||
    extern void irs7 ();
 | 
			
		||||
    extern void irs8 ();
 | 
			
		||||
    extern void irs9 ();
 | 
			
		||||
    extern void irs10 ();
 | 
			
		||||
    extern void irs11 ();
 | 
			
		||||
    extern void irs12 ();
 | 
			
		||||
    extern void irs13 ();
 | 
			
		||||
    extern void irs14 ();
 | 
			
		||||
    extern void irs15 ();
 | 
			
		||||
    extern void irs16 ();
 | 
			
		||||
    extern void irs17 ();
 | 
			
		||||
    extern void irs18 ();
 | 
			
		||||
    extern void irs19 ();
 | 
			
		||||
    extern void irs20 ();
 | 
			
		||||
    extern void irs21 ();
 | 
			
		||||
    extern void irs22 ();
 | 
			
		||||
    extern void irs23 ();
 | 
			
		||||
    extern void irs24 ();
 | 
			
		||||
    extern void irs25 ();
 | 
			
		||||
    extern void irs26 ();
 | 
			
		||||
    extern void irs27 ();
 | 
			
		||||
    extern void irs28 ();
 | 
			
		||||
    extern void irs29 ();
 | 
			
		||||
    extern void irs30 ();
 | 
			
		||||
    extern void irs31 ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										184
									
								
								src/kernel/arch/i386/idt/scancodes/set1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								src/kernel/arch/i386/idt/scancodes/set1.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,184 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ScanCode set 1 
 | 
			
		||||
int ScanCodeToKeyCode [0xD8];
 | 
			
		||||
 | 
			
		||||
/* key pressed scancode */ 
 | 
			
		||||
ScanCodeToKeyCode[0x01] = 4017;   // escape pressed
 | 
			
		||||
ScanCodeToKeyCode[0x02] = 4018;   // 1 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x03] = 4019;   // 2 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x04] = 4020;   // 3 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x05] =""   // 4 pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x06] =""   // 5 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x07] =""   // 6 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x08] =""   // 7 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x09] =""   // 8 pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x0A] =""   // 9 pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x0B] =""   // 0 (zero) pressed
 | 
			
		||||
ScanCodeToKeyCode[0x0C] =""   // - pressed
 | 
			
		||||
ScanCodeToKeyCode[0x0D] =""   // = pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x0E] =""   // backspace pressed
 | 
			
		||||
ScanCodeToKeyCode[0x0F] =""   // tab pressed
 | 
			
		||||
ScanCodeToKeyCode[0x10] =""  	// Q pressed
 | 
			
		||||
ScanCodeToKeyCode[0x11] =""   // W pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x12] ="" 	// E pressed
 | 
			
		||||
ScanCodeToKeyCode[0x13] ="" 	// R pressed
 | 
			
		||||
ScanCodeToKeyCode[0x14] ="" 	// T pressed
 | 
			
		||||
ScanCodeToKeyCode[0x15] ="" 	// Y pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x16] ="" 	// U pressed
 | 
			
		||||
ScanCodeToKeyCode[0x17] ="" 	// I pressed
 | 
			
		||||
ScanCodeToKeyCode[0x18] ="" 	// O pressed
 | 
			
		||||
ScanCodeToKeyCode[0x19] ="" 	// P pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x1A] =""   // [ pressed
 | 
			
		||||
ScanCodeToKeyCode[0x1B] =""   // ] pressed
 | 
			
		||||
ScanCodeToKeyCode[0x1C] =""   // enter pressed
 | 
			
		||||
ScanCodeToKeyCode[0x1D] =""   // left control pressed
 | 
			
		||||
ScanCodeToKeyCode[0x1E] ="" 	// A pressed
 | 
			
		||||
ScanCodeToKeyCode[0x1F] ="" 	// S pressed
 | 
			
		||||
ScanCodeToKeyCode[0x20] ="" 	// D pressed
 | 
			
		||||
ScanCodeToKeyCode[0x21] ="" 	// F pressed
 | 
			
		||||
ScanCodeToKeyCode[0x22] ="" 	// G pressed
 | 
			
		||||
ScanCodeToKeyCode[0x23] ="" 	// H pressed
 | 
			
		||||
ScanCodeToKeyCode[0x24] ="" 	// J pressed
 | 
			
		||||
ScanCodeToKeyCode[0x25] ="" 	// K pressed
 | 
			
		||||
ScanCodeToKeyCode[0x26] ="" 	// L pressed
 | 
			
		||||
ScanCodeToKeyCode[0x27] =""   //  ; pressed
 | 
			
		||||
ScanCodeToKeyCode[0x28] =""   // ' (single quote) pressed
 | 
			
		||||
ScanCodeToKeyCode[0x29] =""   // ` (back tick) pressed
 | 
			
		||||
ScanCodeToKeyCode[0x2A] =""   // left shift pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x2B] =""   // \ pressed
 | 
			
		||||
ScanCodeToKeyCode[0x2C] ="" 	// Z pressed
 | 
			
		||||
ScanCodeToKeyCode[0x2D] ="" 	// X pressed
 | 
			
		||||
ScanCodeToKeyCode[0x2E] ="" 	// C pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x2F] ="" 	// V pressed
 | 
			
		||||
ScanCodeToKeyCode[0x30] ="" 	// B pressed
 | 
			
		||||
ScanCodeToKeyCode[0x31] ="" 	// N pressed
 | 
			
		||||
ScanCodeToKeyCode[0x32] ="" 	// M pressed
 | 
			
		||||
ScanCodeToKeyCode[0x33] =""   // , pressed
 | 
			
		||||
ScanCodeToKeyCode[0x34] =""   // . pressed
 | 
			
		||||
ScanCodeToKeyCode[0x35] =""   // / pressed
 | 
			
		||||
ScanCodeToKeyCode[0x36] =""   // right shift pressed
 | 
			
		||||
ScanCodeToKeyCode[0x37] =""   // (keypad) * pressed
 | 
			
		||||
ScanCodeToKeyCode[0x38] =""   // left alt pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x39] =""   // space pressed	
 | 
			
		||||
ScanCodeToKeyCode[0x3A] =""   // CapsLock pressed
 | 
			
		||||
ScanCodeToKeyCode[0x3B] =""   // F1 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x3C] =""   // F2 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x3D] =""   // F3 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x3E] ="" 	// F4 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x3F] ="" 	// F5 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x40] ="" 	// F6 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x41] ="" 	// F7 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x42] ="" 	// F8 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x43] ="" 	// F9 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x44] ="" 	// F10 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x45] ="" 	// NumberLock pressed
 | 
			
		||||
ScanCodeToKeyCode[0x46] ="" 	// ScrollLock pressed
 | 
			
		||||
ScanCodeToKeyCode[0x47] ="" 	// (keypad) 7 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x48] ="" 	// (keypad) 8 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x49] ="" 	// (keypad) 9 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4A] ="" 	// (keypad) - pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4B] ="" 	// (keypad) 4 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4C] ="" 	// (keypad) 5 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4D] ="" 	// (keypad) 6 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4E] ="" 	// (keypad) + pressed
 | 
			
		||||
ScanCodeToKeyCode[0x4F] ="" 	// (keypad) 1 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x50] ="" 	// (keypad) 2 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x51] ="" 	// (keypad) 3 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x52] ="" 	// (keypad) 0 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x53] ="" 	// (keypad) . pressed
 | 
			
		||||
ScanCodeToKeyCode[0x57] ="" 	// F11 pressed
 | 
			
		||||
ScanCodeToKeyCode[0x58] ="" 	// F12 pressed						
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* key released scanCode.""*/
 | 
			
		||||
ScanCodeToKeyCode[0x81] ="" 	// escape released
 | 
			
		||||
ScanCodeToKeyCode[0x82] ="" 	// 1 released
 | 
			
		||||
ScanCodeToKeyCode[0x83] ="" 	// 2 released
 | 
			
		||||
ScanCodeToKeyCode[0x84] ="" 	// 3 released
 | 
			
		||||
ScanCodeToKeyCode[0x85] ="" 	// 4 released
 | 
			
		||||
ScanCodeToKeyCode[0x86] ="" 	// 5 released
 | 
			
		||||
ScanCodeToKeyCode[0x87] ="" 	// 6 released
 | 
			
		||||
ScanCodeToKeyCode[0x88] ="" 	// 7 released
 | 
			
		||||
ScanCodeToKeyCode[0x89] ="" 	// 8 released
 | 
			
		||||
ScanCodeToKeyCode[0x8A] ="" 	// 9 released
 | 
			
		||||
ScanCodeToKeyCode[0x8B] ="" 	// 0 (zero) released
 | 
			
		||||
ScanCodeToKeyCode[0x8C] ="" 	// - released
 | 
			
		||||
ScanCodeToKeyCode[0x8D] ="" 	// = released
 | 
			
		||||
ScanCodeToKeyCode[0x8E] ="" 	// backspace released
 | 
			
		||||
ScanCodeToKeyCode[0x8F] ="" 	// tab released
 | 
			
		||||
ScanCodeToKeyCode[0x90] ="" 	// Q released
 | 
			
		||||
ScanCodeToKeyCode[0x91] ="" 	// W released
 | 
			
		||||
ScanCodeToKeyCode[0x92] ="" 	// E released
 | 
			
		||||
ScanCodeToKeyCode[0x93] ="" 	// R released
 | 
			
		||||
ScanCodeToKeyCode[0x94] ="" 	// T released
 | 
			
		||||
ScanCodeToKeyCode[0x95] ="" 	// Y released	
 | 
			
		||||
ScanCodeToKeyCode[0x96] ="" 	// U released
 | 
			
		||||
ScanCodeToKeyCode[0x97] ="" 	// I released
 | 
			
		||||
ScanCodeToKeyCode[0x98] ="" 	// O released	
 | 
			
		||||
ScanCodeToKeyCode[0x99] ="" 	// P released
 | 
			
		||||
ScanCodeToKeyCode[0x9A] ="" 	// [ released	
 | 
			
		||||
ScanCodeToKeyCode[0x9B] ="" 	// ] released
 | 
			
		||||
ScanCodeToKeyCode[0x9C] ="" 	// enter released
 | 
			
		||||
ScanCodeToKeyCode[0x9D] ="" 	// left control released
 | 
			
		||||
ScanCodeToKeyCode[0x9E] ="" 	// A released
 | 
			
		||||
ScanCodeToKeyCode[0x9F] ="" 	// S released
 | 
			
		||||
ScanCodeToKeyCode[0xA0] ="" 	// D released
 | 
			
		||||
ScanCodeToKeyCode[0xA1] ="" 	// F released
 | 
			
		||||
ScanCodeToKeyCode[0xA2] ="" 	// G released
 | 
			
		||||
ScanCodeToKeyCode[0xA3] ="" 	// H released
 | 
			
		||||
ScanCodeToKeyCode[0xA4] ="" 	// J released
 | 
			
		||||
ScanCodeToKeyCode[0xA5] ="" 	// K released
 | 
			
		||||
ScanCodeToKeyCode[0xA6] ="" 	// L released
 | 
			
		||||
ScanCodeToKeyCode[0xA7] ="" 	//  ; released
 | 
			
		||||
ScanCodeToKeyCode[0xA8] ="" 	// ' (single quote) released
 | 
			
		||||
ScanCodeToKeyCode[0xA9] ="" 	// ` (back tick) released
 | 
			
		||||
ScanCodeToKeyCode[0xAA] ="" 	// left shift released
 | 
			
		||||
ScanCodeToKeyCode[0xAB] ="" 	// \ released
 | 
			
		||||
ScanCodeToKeyCode[0xAC] ="" 	// Z released	
 | 
			
		||||
ScanCodeToKeyCode[0xAD] ="" 	// X released	
 | 
			
		||||
ScanCodeToKeyCode[0xAE] ="" 	// C released	
 | 
			
		||||
ScanCodeToKeyCode[0xAF] ="" 	// V released
 | 
			
		||||
ScanCodeToKeyCode[0xB0] ="" 	// B released	
 | 
			
		||||
ScanCodeToKeyCode[0xB1] ="" 	// N released	
 | 
			
		||||
ScanCodeToKeyCode[0xB2] ="" 	// M released	
 | 
			
		||||
ScanCodeToKeyCode[0xB3] ="" 	// , released
 | 
			
		||||
ScanCodeToKeyCode[0xB4] ="" 	// . released	
 | 
			
		||||
ScanCodeToKeyCode[0xB5] ="" 	// / released	
 | 
			
		||||
ScanCodeToKeyCode[0xB6] ="" 	// right shift released
 | 
			
		||||
ScanCodeToKeyCode[0xB7] ="" 	// (keypad) * released
 | 
			
		||||
ScanCodeToKeyCode[0xB8] ="" 	// left alt released	
 | 
			
		||||
ScanCodeToKeyCode[0xB9] ="" 	// space released	
 | 
			
		||||
ScanCodeToKeyCode[0xBA] ="" 	// CapsLock released	
 | 
			
		||||
ScanCodeToKeyCode[0xBB] ="" 	// F1 released
 | 
			
		||||
ScanCodeToKeyCode[0xBC] ="" 	// F2 released	
 | 
			
		||||
ScanCodeToKeyCode[0xBD] ="" 	// F3 released	
 | 
			
		||||
ScanCodeToKeyCode[0xBE] ="" 	// F4 released	
 | 
			
		||||
ScanCodeToKeyCode[0xBF] ="" 	// F5 released
 | 
			
		||||
ScanCodeToKeyCode[0xC0] ="" 	// F6 released	
 | 
			
		||||
ScanCodeToKeyCode[0xC1] ="" 	// F7 released	
 | 
			
		||||
ScanCodeToKeyCode[0xC2] ="" 	// F8 released	
 | 
			
		||||
ScanCodeToKeyCode[0xC3] ="" 	// F9 released
 | 
			
		||||
ScanCodeToKeyCode[0xC4] ="" 	// F10 released
 | 
			
		||||
ScanCodeToKeyCode[0xC5] ="" 	// NumberLock released
 | 
			
		||||
ScanCodeToKeyCode[0xC6] ="" 	// ScrollLock released
 | 
			
		||||
ScanCodeToKeyCode[0xC7] ="" 	// (keypad) 7 released
 | 
			
		||||
ScanCodeToKeyCode[0xC8] ="" 	// (keypad) 8 released	
 | 
			
		||||
ScanCodeToKeyCode[0xC9] ="" 	// (keypad) 9 released	
 | 
			
		||||
ScanCodeToKeyCode[0xCA] ="" 	// (keypad) - released	
 | 
			
		||||
ScanCodeToKeyCode[0xCB] ="" 	// (keypad) 4 released
 | 
			
		||||
ScanCodeToKeyCode[0xCC] ="" 	// (keypad) 5 released	
 | 
			
		||||
ScanCodeToKeyCode[0xCD] ="" 	// (keypad) 6 released	
 | 
			
		||||
ScanCodeToKeyCode[0xCE] ="" 	// (keypad) + released	
 | 
			
		||||
ScanCodeToKeyCode[0xCF] ="" 	// (keypad) 1 released
 | 
			
		||||
ScanCodeToKeyCode[0xD0] ="" 	// (keypad) 2 released	
 | 
			
		||||
ScanCodeToKeyCode[0xD1] ="" 	// (keypad) 3 released	
 | 
			
		||||
ScanCodeToKeyCode[0xD2] ="" 	// (keypad) 0 released	
 | 
			
		||||
ScanCodeToKeyCode[0xD3] ="" 	// (keypad) . released
 | 
			
		||||
ScanCodeToKeyCode[0xD7] ="" 	// F11 released
 | 
			
		||||
ScanCodeToKeyCode[0xD8] ="" 	// F12 released					
 | 
			
		||||
							
								
								
									
										62
									
								
								src/kernel/arch/i386/pic/pic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/kernel/arch/i386/pic/pic.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
#include "pic.h"
 | 
			
		||||
 | 
			
		||||
extern "C" void PIC_sendEOI (unsigned char irq){
 | 
			
		||||
    if(irq >= 8)
 | 
			
		||||
        outb(PIC2_COMMAND, PIC_EOI);
 | 
			
		||||
    outb(PIC1_COMMAND, PIC_EOI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Helper func */
 | 
			
		||||
static uint16_t __pic_get_irq_reg(int ocw3)
 | 
			
		||||
{
 | 
			
		||||
    /* OCW3 to PIC CMD to get the register values.  PIC2 is chained, and
 | 
			
		||||
     * represents IRQs 8-15.  PIC1 is IRQs 0-7, with 2 being the chain */
 | 
			
		||||
    outb(PIC1_COMMAND, ocw3);
 | 
			
		||||
    outb(PIC2_COMMAND, ocw3);
 | 
			
		||||
    return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
/* Returns the combined value of the cascaded PICs irq request register */
 | 
			
		||||
uint16_t pic_get_irr(void)
 | 
			
		||||
{
 | 
			
		||||
    return __pic_get_irq_reg(PIC_READ_IRR);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
/* Returns the combined value of the cascaded PICs in-service register */
 | 
			
		||||
uint16_t pic_get_isr(void)
 | 
			
		||||
{
 | 
			
		||||
    return __pic_get_irq_reg(PIC_READ_ISR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void PIC_remap (int offset1, int offset2 ){
 | 
			
		||||
    unsigned char a1, a2;
 | 
			
		||||
 | 
			
		||||
    a1 = inb(PIC1_DATA);
 | 
			
		||||
    a2 = inb(PIC2_DATA);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Start initialization
 | 
			
		||||
 | 
			
		||||
    outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC1_DATA, offset1);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC2_DATA, offset2);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC1_DATA, 4);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC2_DATA, 2);
 | 
			
		||||
    io_wait();
 | 
			
		||||
 | 
			
		||||
    outb(PIC1_DATA, ICW4_8086);
 | 
			
		||||
    io_wait();
 | 
			
		||||
    outb(PIC2_DATA, ICW4_8086);
 | 
			
		||||
    io_wait();
 | 
			
		||||
 | 
			
		||||
    outb(PIC1_DATA, a1);
 | 
			
		||||
    outb(PIC2_DATA, a2);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								src/kernel/arch/i386/pic/pic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/kernel/arch/i386/pic/pic.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../../../io.h"
 | 
			
		||||
 | 
			
		||||
#define PIC1		0x20		/* IO base address for master PIC */
 | 
			
		||||
#define PIC2		0xA0		/* IO base address for slave PIC */
 | 
			
		||||
#define PIC1_COMMAND	PIC1
 | 
			
		||||
#define PIC1_DATA	(PIC1+1)
 | 
			
		||||
#define PIC2_COMMAND	PIC2
 | 
			
		||||
#define PIC2_DATA	(PIC2+1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ICW1_ICW4	0x01		/* ICW4 (not) needed */
 | 
			
		||||
#define ICW1_SINGLE	0x02		/* Single (cascade) mode */
 | 
			
		||||
#define ICW1_INTERVAL4	0x04		/* Call address interval 4 (8) */
 | 
			
		||||
#define ICW1_LEVEL	0x08		/* Level triggered (edge) mode */
 | 
			
		||||
#define ICW1_INIT	0x10		/* Initialization - required! */
 | 
			
		||||
 
 | 
			
		||||
#define ICW4_8086	0x01		/* 8086/88 (MCS-80/85) mode */
 | 
			
		||||
#define ICW4_AUTO	0x02		/* Auto (normal) EOI */
 | 
			
		||||
#define ICW4_BUF_SLAVE	0x08		/* Buffered mode/slave */
 | 
			
		||||
#define ICW4_BUF_MASTER	0x0C		/* Buffered mode/master */
 | 
			
		||||
#define ICW4_SFNM	0x10		/* Special fully nested (not) */
 | 
			
		||||
 | 
			
		||||
#define PIC_EOI 0x20
 | 
			
		||||
#define PIC_READ_IRR 0x0a    /* OCW3 irq ready next CMD read */
 | 
			
		||||
#define PIC_READ_ISR 0x0b    /* OCW3 irq service next CMD read */
 | 
			
		||||
 | 
			
		||||
extern "C"{
 | 
			
		||||
 | 
			
		||||
extern void irq0 ();
 | 
			
		||||
extern void irq1 ();
 | 
			
		||||
extern void irq2 ();
 | 
			
		||||
extern void irq3 ();
 | 
			
		||||
extern void irq4 ();
 | 
			
		||||
extern void irq5 ();
 | 
			
		||||
extern void irq6 ();
 | 
			
		||||
extern void irq7 ();
 | 
			
		||||
extern void irq8 ();
 | 
			
		||||
extern void irq9 ();
 | 
			
		||||
extern void irq10 ();
 | 
			
		||||
extern void irq11 ();
 | 
			
		||||
extern void irq12 ();
 | 
			
		||||
extern void irq13 ();
 | 
			
		||||
extern void irq14 ();
 | 
			
		||||
extern void irq15 ();
 | 
			
		||||
 | 
			
		||||
void PIC_sendEOI (unsigned char irq);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint16_t __pic_get_irq_reg(int ocw3);
 | 
			
		||||
uint16_t pic_get_irr(void);
 | 
			
		||||
uint16_t pic_get_isr(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void PIC_remap (int offset1, int offset2 );
 | 
			
		||||
@ -62,15 +62,17 @@ void kterm_scrollup(){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kterm_put (char c) {
 | 
			
		||||
 
 | 
			
		||||
    if(++kterm_column == VGA_WIDTH || c == '\n' ) {
 | 
			
		||||
        kterm_column = 0;
 | 
			
		||||
        if(kterm_row == VGA_HEIGHT-1) {       
 | 
			
		||||
        if(kterm_row == VGA_HEIGHT-1 ) {       
 | 
			
		||||
            kterm_scrollup();
 | 
			
		||||
        } else {
 | 
			
		||||
            kterm_row ++;
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
    }
 | 
			
		||||
    if ( c == '\r'){
 | 
			
		||||
        kterm_column = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(c == '\n') return;
 | 
			
		||||
@ -90,3 +92,99 @@ void kterm_writestring(const char* data ){
 | 
			
		||||
    kterm_write(data, strlen(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d) {
 | 
			
		||||
    char *p = buf;
 | 
			
		||||
    char *p1, *p2;
 | 
			
		||||
    unsigned long ud = d;
 | 
			
		||||
    int divisor = 10;
 | 
			
		||||
    if ( base == 'd' && d < 0){
 | 
			
		||||
        *p++ = '-';
 | 
			
		||||
        buf++;
 | 
			
		||||
        ud = -d;
 | 
			
		||||
    } else if (base == 'x'){
 | 
			
		||||
        divisor = 16;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    do { 
 | 
			
		||||
        int remainder = ud % divisor;
 | 
			
		||||
 | 
			
		||||
         *p++ = (remainder < 10 ) ? remainder + '0' : remainder + 'a' -10;
 | 
			
		||||
    } while(ud /= divisor);
 | 
			
		||||
 | 
			
		||||
    /*terminate buf*/
 | 
			
		||||
    *p =0;
 | 
			
		||||
    p1 = buf;
 | 
			
		||||
    p2 = p -1;
 | 
			
		||||
 | 
			
		||||
    while (p1 < p2)
 | 
			
		||||
    {
 | 
			
		||||
        char tmp = *p1;
 | 
			
		||||
        *p1 = *p2;
 | 
			
		||||
        *p2 = tmp;
 | 
			
		||||
        p1++;
 | 
			
		||||
        p2--;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...) {
 | 
			
		||||
    
 | 
			
		||||
    char **arg = (char **)&format;
 | 
			
		||||
    int c;
 | 
			
		||||
    char buf[20];
 | 
			
		||||
 | 
			
		||||
    arg++;
 | 
			
		||||
    
 | 
			
		||||
    while ((c = *format++) != 0){
 | 
			
		||||
        if( c != '%')
 | 
			
		||||
            kterm_put(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++)
 | 
			
		||||
                        kterm_put(pad0 ? '0': ' ');
 | 
			
		||||
                    while (*p)
 | 
			
		||||
                        kterm_put(*p++);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                kterm_put(*((int *)arg++));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -17,7 +17,14 @@ void kterm_write(const char*, size_t);
 | 
			
		||||
void kterm_writestring(const char*);
 | 
			
		||||
void kterm_scrollup();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...);
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d);
 | 
			
		||||
 | 
			
		||||
#define KernelTag "[Kernel]: "
 | 
			
		||||
#define AS_KERNEL() (  kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
 | 
			
		||||
                       kterm_write(KernelTag, 10 ), \
 | 
			
		||||
                       kterm_resetcolor())
 | 
			
		||||
                       kterm_resetcolor())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -56,4 +56,12 @@ void outsw(unsigned short , const void *,
 | 
			
		||||
void outsl(unsigned short , const void *,
 | 
			
		||||
        unsigned long ){
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
void io_wait(void)
 | 
			
		||||
{
 | 
			
		||||
    /* TODO: This is probably fragile. */
 | 
			
		||||
    asm volatile ( "jmp 1f\n\t"
 | 
			
		||||
                   "1:jmp 2f\n\t"
 | 
			
		||||
                   "2:" );
 | 
			
		||||
}
 | 
			
		||||
@ -40,4 +40,5 @@ void outsb(unsigned short port, const void *addr,
 | 
			
		||||
void outsw(unsigned short port, const void *addr,
 | 
			
		||||
        unsigned long count);
 | 
			
		||||
void outsl(unsigned short port, const void *addr,
 | 
			
		||||
        unsigned long count);
 | 
			
		||||
        unsigned long count);
 | 
			
		||||
void io_wait();
 | 
			
		||||
@ -16,7 +16,6 @@ class Test {
 | 
			
		||||
         ~Test();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Test::Test(){
 | 
			
		||||
    kterm_writestring("Create a test object\n");
 | 
			
		||||
};
 | 
			
		||||
@ -52,7 +51,6 @@ static int init_serial() {
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int is_transmit_empty() {
 | 
			
		||||
   return inb(PORT + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
@ -73,6 +71,11 @@ char read_serial() {
 | 
			
		||||
   return inb(PORT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_serial(const char* string ){
 | 
			
		||||
    for(size_t i = 0; i < strlen(string); i ++){
 | 
			
		||||
        write_serial(string[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
@ -92,12 +95,32 @@ void test_serial(){
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
    void early_main(){
 | 
			
		||||
 | 
			
		||||
       init_serial();
 | 
			
		||||
       print_serial("\033[31;42mEarly main called!\n");
 | 
			
		||||
   
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void kernel_main (void) {
 | 
			
		||||
       
 | 
			
		||||
        print_serial("Kernel main called!\n");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /** initialize terminal interface */ 
 | 
			
		||||
        kterm_init();
 | 
			
		||||
 | 
			
		||||
        /** Setup the MMU **/
 | 
			
		||||
        //kterm_writestring("Starting MMU...\n");
 | 
			
		||||
        //auto mmu = MMU();
 | 
			
		||||
        //mmu.enable();
 | 
			
		||||
        //kterm_writestring("MMU enabled!\n");
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /** Wrtite stuff to the screen to test the terminal**/ 
 | 
			
		||||
        kterm_writestring("Hello world!\n");
 | 
			
		||||
        kterm_writestring("We got newline support!\n");
 | 
			
		||||
@ -114,22 +137,27 @@ extern "C" {
 | 
			
		||||
        auto testObject = Test();
 | 
			
		||||
        testObject.printMe();
 | 
			
		||||
 | 
			
		||||
        /** Setup the MMU **/
 | 
			
		||||
        kterm_writestring("Starting MMU...\n");
 | 
			
		||||
        auto mmu = MMU();
 | 
			
		||||
        mmu.enable();
 | 
			
		||||
        kterm_writestring("MMU enabled!\n");
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /** test interrupt handlers **/
 | 
			
		||||
        //asm volatile ("int $0x03");
 | 
			
		||||
 | 
			
		||||
        //asm volatile ("int $0x04");
 | 
			
		||||
 | 
			
		||||
        while (true){
 | 
			
		||||
            //Read time indefinetely 
 | 
			
		||||
            read_rtc();
 | 
			
		||||
            printf( "UTC time: %2d-%2d-%2d %2d:%2d:%2d  : (YY-MM-DD h:mm:ss)\r" ,year, month, day, hour, minute, second);
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /** Lets start using the serial port for debugging .. **/
 | 
			
		||||
        // Hopefully once we go into realmode or do something that
 | 
			
		||||
        // cause the screen to go black.. this serial comms part will give
 | 
			
		||||
        // some situational awareness
 | 
			
		||||
        //Serial serialbus = Serial::init();
 | 
			
		||||
 | 
			
		||||
        test_serial();
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    }   
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,10 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include "../libc/include/string.h"
 | 
			
		||||
#include "arch/i386/tty/kterm.h"
 | 
			
		||||
    #include "../libc/include/string.h"
 | 
			
		||||
    #include "arch/i386/tty/kterm.h"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "arch/i386/idt/idt.h"
 | 
			
		||||
#include "MMU.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								src/kernel/time.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/kernel/time.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,151 @@
 | 
			
		||||
#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;
 | 
			
		||||
unsigned char day;
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
unsigned char get_RTC_register(int reg) {
 | 
			
		||||
      outb(cmos_address, reg);
 | 
			
		||||
      return inb(cmos_data);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void read_rtc() {
 | 
			
		||||
      unsigned char century;
 | 
			
		||||
      unsigned char last_second;
 | 
			
		||||
      unsigned char last_minute;
 | 
			
		||||
      unsigned char last_hour;
 | 
			
		||||
      unsigned char last_day;
 | 
			
		||||
      unsigned char last_month;
 | 
			
		||||
      unsigned char last_year;
 | 
			
		||||
      unsigned char last_century;
 | 
			
		||||
      unsigned char registerB;
 | 
			
		||||
 
 | 
			
		||||
      // Note: This uses the "read registers until you get the same values twice in a row" technique
 | 
			
		||||
      //       to avoid getting dodgy/inconsistent values due to RTC updates
 | 
			
		||||
 
 | 
			
		||||
      while (get_update_in_progress_flag());                // Make sure an update isn't in progress
 | 
			
		||||
      second = get_RTC_register(0x00);
 | 
			
		||||
      minute = get_RTC_register(0x02);
 | 
			
		||||
      hour = get_RTC_register(0x04);
 | 
			
		||||
      day = get_RTC_register(0x07);
 | 
			
		||||
      month = get_RTC_register(0x08);
 | 
			
		||||
      year = get_RTC_register(0x09);
 | 
			
		||||
      if(century_register != 0) {
 | 
			
		||||
            century = get_RTC_register(century_register);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      do {
 | 
			
		||||
            last_second = second;
 | 
			
		||||
            last_minute = minute;
 | 
			
		||||
            last_hour = hour;
 | 
			
		||||
            last_day = day;
 | 
			
		||||
            last_month = month;
 | 
			
		||||
            last_year = year;
 | 
			
		||||
            last_century = century;
 | 
			
		||||
 
 | 
			
		||||
            while (get_update_in_progress_flag());           // Make sure an update isn't in progress
 | 
			
		||||
            second = get_RTC_register(0x00);
 | 
			
		||||
            minute = get_RTC_register(0x02);
 | 
			
		||||
            hour = get_RTC_register(0x04);
 | 
			
		||||
            day = get_RTC_register(0x07);
 | 
			
		||||
            month = get_RTC_register(0x08);
 | 
			
		||||
            year = get_RTC_register(0x09);
 | 
			
		||||
            if(century_register != 0) {
 | 
			
		||||
                  century = get_RTC_register(century_register);
 | 
			
		||||
            }
 | 
			
		||||
      } while( (last_second != second) || (last_minute != minute) || (last_hour != hour) ||
 | 
			
		||||
               (last_day != day) || (last_month != month) || (last_year != year) ||
 | 
			
		||||
               (last_century != century) );
 | 
			
		||||
 
 | 
			
		||||
      registerB = get_RTC_register(0x0B);
 | 
			
		||||
 
 | 
			
		||||
      // Convert BCD to binary values if necessary
 | 
			
		||||
 
 | 
			
		||||
      if (!(registerB & 0x04)) {
 | 
			
		||||
            second = (second & 0x0F) + ((second / 16) * 10);
 | 
			
		||||
            minute = (minute & 0x0F) + ((minute / 16) * 10);
 | 
			
		||||
            hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
 | 
			
		||||
            day = (day & 0x0F) + ((day / 16) * 10);
 | 
			
		||||
            month = (month & 0x0F) + ((month / 16) * 10);
 | 
			
		||||
            year = (year & 0x0F) + ((year / 16) * 10);
 | 
			
		||||
            if(century_register != 0) {
 | 
			
		||||
                  century = (century & 0x0F) + ((century / 16) * 10);
 | 
			
		||||
            }
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      // Convert 12 hour clock to 24 hour clock if necessary
 | 
			
		||||
 
 | 
			
		||||
      if (!(registerB & 0x02) && (hour & 0x80)) {
 | 
			
		||||
            hour = ((hour & 0x7F) + 12) % 24;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      // Calculate the full (4-digit) year
 | 
			
		||||
 
 | 
			
		||||
      if(century_register != 0) {
 | 
			
		||||
            year += century * 100;
 | 
			
		||||
      } else {
 | 
			
		||||
            year += (CURRENT_YEAR / 100) * 100;
 | 
			
		||||
            if(year < CURRENT_YEAR) year += 100;
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
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
 | 
			
		||||
      
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										27
									
								
								src/kernel/timer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/kernel/timer.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
#include "timer.h"
 | 
			
		||||
 | 
			
		||||
uint32_t tick = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void timer_callback (registers_t regs ){
 | 
			
		||||
    tick ++ ;
 | 
			
		||||
    kterm_writestring ("tick passed!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_timer (uint32_t frequency){
 | 
			
		||||
    // register timer callback
 | 
			
		||||
 | 
			
		||||
    uint32_t divisor = 1193180 / frequency;
 | 
			
		||||
 | 
			
		||||
    // Send the commmand byte
 | 
			
		||||
    outb(0x43, 0x36);
 | 
			
		||||
 | 
			
		||||
    // Divisor has to be sent byt-wise , so will send lower then upper bytes
 | 
			
		||||
    uint8_t low = (uint8_t) (divisor & 0xFF);
 | 
			
		||||
    uint8_t high = (uint8_t) ((divisor >> 8) & 0xFF);
 | 
			
		||||
 | 
			
		||||
    outb(0x40, low);
 | 
			
		||||
    outb(0x40, high);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								src/kernel/timer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/kernel/timer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
void init_timer (uint32_t frequency);
 | 
			
		||||
		Reference in New Issue
	
	Block a user