Merge kaleid to boot
This commit is contained in:
commit
13d4e41983
|
@ -2,7 +2,11 @@
|
||||||
|
|
||||||
Fully open-source operating system from scratch (WIP), released under the GNU GPL version 3.0
|
Fully open-source operating system from scratch (WIP), released under the GNU GPL version 3.0
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
Branch boot : Development focused on the bootloader of OS/K
|
Branch boot : Development focused on the bootloader of OS/K
|
||||||
|
=======
|
||||||
|
Branch kaleid : Development focused on the Kaleid Kernel.
|
||||||
|
>>>>>>> kaleid
|
||||||
|
|
||||||
For changelog, see src/ChangeLog.
|
For changelog, see src/ChangeLog.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
2018/10/?? - Started talking about making our own OS
|
2018/10/?? - Started talking about making our own OS
|
||||||
2018/11/?? - Name decided & creation of gnu-os-k.eu
|
2018/11/?? - Name decided & creation of os-k.eu
|
||||||
2018/12/06 - Actually started project, began MBR, decided directories organization, created this file and others
|
2018/12/06 - Actually started project, began MBR, decided directories organization, created this file and others
|
||||||
2018/12/08 - MBR actually supports Long Mode Compatibility Verification
|
2018/12/08 - MBR actually supports Long Mode Compatibility Verification
|
||||||
- Added A20 line Enabling to MBR
|
- Added A20 line Enabling to MBR
|
||||||
|
|
92
src/Makefile
92
src/Makefile
|
@ -7,13 +7,16 @@
|
||||||
# Desc: Project Makefile #
|
# Desc: Project Makefile #
|
||||||
#----------------------------------------------------------------------------#
|
#----------------------------------------------------------------------------#
|
||||||
|
|
||||||
CC_NAME="/opt/cross-cc/bin/x86_64-elf-gcc"
|
CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc"
|
||||||
CWARNS=-Wall -Wextra -Werror
|
CC2NAME=gcc # compiler for testing
|
||||||
|
CLDSCR=-T kernel.ld
|
||||||
|
CWARNS= -pedantic -Wall -Wextra -Werror
|
||||||
CFLAGS=-nostdlib -ffreestanding -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2
|
CFLAGS=-nostdlib -ffreestanding -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2
|
||||||
CINCLUDES=-I./kaleid
|
CINCLUDES=-I./kaleid
|
||||||
CDEFINES=
|
CDEFINES=
|
||||||
|
|
||||||
CC=$(CC_NAME) $(CWARNS) $(CFLAGS) $(CDEFINES) $(CINCLUDES)
|
CC=$(CCNAME) $(CWARNS) $(CFLAGS) $(CDEFINES) $(CINCLUDES)
|
||||||
|
KCC=$(CC) -D_KALEID_KERNEL
|
||||||
|
|
||||||
ASM=nasm
|
ASM=nasm
|
||||||
ASMFLAGS=
|
ASMFLAGS=
|
||||||
|
@ -26,6 +29,7 @@ BOOTDIR=boot
|
||||||
COMMDIR=kaleid/common
|
COMMDIR=kaleid/common
|
||||||
KERNDIR=kaleid/kernel
|
KERNDIR=kaleid/kernel
|
||||||
SYSTDIR=kaleid/system
|
SYSTDIR=kaleid/system
|
||||||
|
LINXDIR=kaleid/linux
|
||||||
|
|
||||||
all: bootloader
|
all: bootloader
|
||||||
|
|
||||||
|
@ -52,76 +56,40 @@ testing: bootloader pseudo_kern
|
||||||
# COMMON MAKEFILE
|
# COMMON MAKEFILE
|
||||||
|
|
||||||
COBJDIR=$(OBJDIR)/$(COMMDIR)
|
COBJDIR=$(OBJDIR)/$(COMMDIR)
|
||||||
|
LOBJDIR=$(OBJDIR)/$(LINXDIR)
|
||||||
|
|
||||||
COMM_DEPS=$(COMMDIR)/common.h $(COMMDIR)/assert.h $(COMMDIR)/atomic.h $(COMMDIR)/config.h \
|
COMMDEPS=$(COMMDIR)/common.h $(COMMDIR)/assert.h $(COMMDIR)/atomic.h $(COMMDIR)/config.h \
|
||||||
$(COMMDIR)/status.h
|
$(COMMDIR)/status.h
|
||||||
|
|
||||||
COBJECTS=$(COBJDIR)/lib/string.o
|
COMMOBJS=$(COBJDIR)/lib/string.o $(COBJDIR)/lib/status.o
|
||||||
|
|
||||||
common: common.lib.string.c $(COMM_DEPS)
|
common: $(COMMDEPS) $(COMMDIR)/lib/string.c $(COMMDIR)/lib/status.c
|
||||||
|
$(KCC) -c $(COMMDIR)/lib/string.c -o $(COBJDIR)/lib/string.o
|
||||||
|
$(KCC) -c $(COMMDIR)/lib/status.c -o $(COBJDIR)/lib/status.o
|
||||||
|
|
||||||
common.lib.string.c: $(COMMDIR)/lib/string.c $(COMM_DEPS)
|
CCC=$(CC2NAME) $(CWARNS) $(CDEFINES) $(CINCLUDES)
|
||||||
$(CC) -c $(COMMDIR)/lib/string.c -o $(OBJDIR)/$(COMMDIR)/lib/string.o
|
|
||||||
|
common-test:
|
||||||
|
$(CCC) -c $(COMMDIR)/lib/string.c -o $(COBJDIR)/lib/string.o
|
||||||
|
$(CCC) -c $(COMMDIR)/lib/status.c -o $(COBJDIR)/lib/status.o
|
||||||
|
$(CCC) -c $(LINXDIR)/test-common.c -o $(LOBJDIR)/test-common.o
|
||||||
|
$(CCC) $(COMMOBJS) $(LOBJDIR)/test-common.o -o $(BINDIR)/kaleid-common.elf
|
||||||
|
|
||||||
#----------------------------------------------------------------------------#
|
#----------------------------------------------------------------------------#
|
||||||
# KERNEL MAKEFILE
|
# KERNEL MAKEFILE
|
||||||
|
|
||||||
KOBJDIR=$(OBJDIR)/$(KERNDIR)
|
KOBJDIR=$(OBJDIR)/$(KERNDIR)
|
||||||
|
|
||||||
KERN_DEPS=$(COMM_DEPS) $(KERNDIR)/init.h $(KERNDIR)/io/terminal.h $(KERNDIR)/io/ports.h
|
KERNDEPS=common $(KERNDIR)/init.h $(KERNDIR)/io/terminal.h $(KERNDIR)/io/ports.h $(KERNDIR)/ke/panic.h
|
||||||
|
KERNSRCS=$(KERNDIR)/init.c $(KERNDIR)/ke/panic.c $(KERNDIR)/io/ports.c $(KERNDIR)/io/terminal.c
|
||||||
kernel: common kernel.io.terminal.c kernel.init.c kernel.io.ports.c
|
KERNOBJS=$(KOBJDIR)/init.o $(KOBJDIR)/ke/panic.o $(KOBJDIR)/io/ports.o $(KOBJDIR)/io/terminal.o
|
||||||
$(CC) -o $(BINDIR)/kaleid-kernel.elf \
|
|
||||||
$(COBJECTS) $(KOBJDIR)/init.o \
|
|
||||||
$(KOBJDIR)/io/terminal.o $(KOBJDIR)/io/ports.o
|
|
||||||
|
|
||||||
|
|
||||||
kernel.init.c: $(KERNDIR)/init.c $(KERN_DEPS)
|
|
||||||
$(CC) -c $(KERNDIR)/init.c -o $(KOBJDIR)/init.o
|
|
||||||
|
|
||||||
kernel.io.ports.c: $(KERNDIR)/io/ports.c $(KERN_DEPS)
|
|
||||||
$(CC) -c $(KERNDIR)/io/ports.c -o $(KOBJDIR)/io/ports.o
|
|
||||||
|
|
||||||
kernel.io.terminal.c: $(KERNDIR)/io/terminal.c $(KERN_DEPS)
|
|
||||||
$(CC) -c $(KERNDIR)/io/terminal.c -o $(KOBJDIR)/io/terminal.o
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
kernel: common $(KERNSRCS)
|
||||||
|
$(KCC) -c $(KERNDIR)/init.c -o $(KOBJDIR)/init.o
|
||||||
|
$(KCC) -c $(KERNDIR)/ke/panic.c -o $(KOBJDIR)/ke/panic.o
|
||||||
|
$(KCC) -c $(KERNDIR)/io/ports.c -o $(KOBJDIR)/io/ports.o
|
||||||
|
$(KCC) -c $(KERNDIR)/io/terminal.c -o $(KOBJDIR)/io/terminal.o
|
||||||
|
$(KCC) $(CLDSCR) $(COMMOBJS) $(KERNOBJS) -o $(BINDIR)/kaleid-kernel.elf
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@ GDT64:
|
||||||
NULL_SELECTOR: ;; null selector within 64 bits
|
NULL_SELECTOR: ;; null selector within 64 bits
|
||||||
dw GDT_LENGTH ; limit of GDT
|
dw GDT_LENGTH ; limit of GDT
|
||||||
dw GDT64 ; linear address of GDT
|
dw GDT64 ; linear address of GDT
|
||||||
dd 0x0
|
dd 0x0 ;
|
||||||
|
|
||||||
CODE_SELECTOR: ;; 32-bit code selector (ring 0)
|
CODE_SELECTOR: ;; 32-bit code selector (ring 0)
|
||||||
dw 0x0FFFF ; Segment Limit
|
dw 0x0FFFF ; Segment Limit
|
||||||
db 0x0, 0x0, 0x0 ; Base Address
|
db 0x0, 0x0, 0x0 ; Base Address
|
||||||
|
@ -117,7 +118,7 @@ GDT64:
|
||||||
; | | `---------- DPL !!! 0 for ring 0
|
; | | `---------- DPL !!! 0 for ring 0
|
||||||
; | `----------- DPL (2/2)
|
; | `----------- DPL (2/2)
|
||||||
; `------------ 1 if in physical memory, 0 if page fault
|
; `------------ 1 if in physical memory, 0 if page fault
|
||||||
db 10101111b ; |7|6|5|4|3|2|1|0|
|
db 10101111b ; |7|6|5|4|3|2|1|0|
|
||||||
; | | | | | | | `----- Limit 16
|
; | | | | | | | `----- Limit 16
|
||||||
; | | | | | | `------ Limit 17
|
; | | | | | | `------ Limit 17
|
||||||
; | | | | | `------- Limit 18
|
; | | | | | `------- Limit 18
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
; NeoX ;
|
; NeoX ;
|
||||||
; ;
|
; ;
|
||||||
; Desc: Kernel (second stage) Loader for OS/K INCLUDED FUNCTIONS ;
|
; Desc: Kernel (second stage) Loader for OS/K INCLUDED FUNCTIONS ;
|
||||||
; (x86_64 architecture only) ;
|
; (x86_64 architecture only) ;
|
||||||
;=----------------------------------------------------------------------------=;
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
[BITS 64]
|
[BITS 64]
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
|
@ -33,7 +34,7 @@ write:
|
||||||
; bl : color code ;
|
; bl : color code ;
|
||||||
; esi : string address ;
|
; esi : string address ;
|
||||||
;-----------------------------------------------------------------------;
|
;-----------------------------------------------------------------------;
|
||||||
mov edi, [NextTRAM] ;TRAM ADDRESS
|
mov edi, [NextTRAM] ; TRAM ADDRESS
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
.pLoop:
|
.pLoop:
|
||||||
|
@ -48,7 +49,7 @@ write:
|
||||||
mov al, bl
|
mov al, bl
|
||||||
stosb ; color subpixel
|
stosb ; color subpixel
|
||||||
add qword [NextTRAM], 0x2 ; Cursor moving
|
add qword [NextTRAM], 0x2 ; Cursor moving
|
||||||
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
|
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
|
||||||
jmp .pLoop
|
jmp .pLoop
|
||||||
.pEnd:
|
.pEnd:
|
||||||
pop rdi
|
pop rdi
|
||||||
|
@ -72,3 +73,4 @@ write:
|
||||||
.scroll:
|
.scroll:
|
||||||
; XXX ;
|
; XXX ;
|
||||||
jmp .pLoop
|
jmp .pLoop
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ read_clusters:
|
||||||
add ax, word [UserData] ; add the UserData
|
add ax, word [UserData] ; add the UserData
|
||||||
xor ch, ch
|
xor ch, ch
|
||||||
mov cl, byte [sectorsPerCluster] ; Sectors to read
|
mov cl, byte [sectorsPerCluster] ; Sectors to read
|
||||||
call read_sectors ; Read the sectors
|
call read_sectors ; Read the sectors
|
||||||
pop ax ; Current cluster number
|
pop ax ; Current cluster number
|
||||||
xor dx, dx
|
xor dx, dx
|
||||||
;; Calculate next sector for FAT16 (cluster * 2)
|
;; Calculate next sector for FAT16 (cluster * 2)
|
||||||
|
|
|
@ -79,8 +79,8 @@ go:
|
||||||
|
|
||||||
;; INIT STACK
|
;; INIT STACK
|
||||||
cli
|
cli
|
||||||
mov ax, STACK_SEG ; Init the staaaaaack
|
mov ax, STACK_SEG ; Init the stack
|
||||||
mov ss, ax ; Continue init the staaaaaaaack
|
mov ss, ax ; Continue init the stack
|
||||||
mov sp, STACK_OFF ; Ok man, the stack is in 4K :O
|
mov sp, STACK_OFF ; Ok man, the stack is in 4K :O
|
||||||
sti
|
sti
|
||||||
mov bp, (0x7c0-STACK_SEG) << 4 ; Correct bp (the disk description table)
|
mov bp, (0x7c0-STACK_SEG) << 4 ; Correct bp (the disk description table)
|
||||||
|
@ -88,7 +88,7 @@ go:
|
||||||
;; INITIALIZE BOOT DISK
|
;; INITIALIZE BOOT DISK
|
||||||
or dl, dl ; Verifying dl points actually to the boot drive
|
or dl, dl ; Verifying dl points actually to the boot drive
|
||||||
jz load_root
|
jz load_root
|
||||||
mov byte [Bootdrv], dl ; Another soul (the disk) saved !
|
mov byte [Bootdrv], dl ; Another soul (the disk) saved!
|
||||||
mov ah, 0x08
|
mov ah, 0x08
|
||||||
int 0x13 ; int 0x13 : read drive parameters/geom
|
int 0x13 ; int 0x13 : read drive parameters/geom
|
||||||
jc load_root
|
jc load_root
|
||||||
|
@ -97,7 +97,7 @@ go:
|
||||||
mov dl, dh ; Convert the maximum head number to a word with another vaudou magical trip
|
mov dl, dh ; Convert the maximum head number to a word with another vaudou magical trip
|
||||||
xor dh, dh
|
xor dh, dh
|
||||||
inc dx ; because head numbers start at zero
|
inc dx ; because head numbers start at zero
|
||||||
mov word [heads], dx ; Another soul (the heads number) saved !
|
mov word [heads], dx ; Another soul (the heads number) saved!
|
||||||
|
|
||||||
|
|
||||||
;; LOAD THE ROOT DIRECTORY FROM DISK
|
;; LOAD THE ROOT DIRECTORY FROM DISK
|
||||||
|
@ -117,7 +117,7 @@ load_root:
|
||||||
mov di, BUFFER_SEG ; Set the extra segment to the disk buffer
|
mov di, BUFFER_SEG ; Set the extra segment to the disk buffer
|
||||||
mov es, di
|
mov es, di
|
||||||
mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer
|
mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer
|
||||||
call read_sectors ; Read the sectoooooooors !
|
call read_sectors ; Read the sectors
|
||||||
|
|
||||||
;; FIND THE SECOND STAGE LOADER
|
;; FIND THE SECOND STAGE LOADER
|
||||||
mov di, BUFFER_OFF ; Set es:di to the disk buffer
|
mov di, BUFFER_OFF ; Set es:di to the disk buffer
|
||||||
|
@ -128,7 +128,7 @@ search_root:
|
||||||
mov si, filename ; Load the filename
|
mov si, filename ; Load the filename
|
||||||
mov cx, 11 ; Compare first 11 bytes
|
mov cx, 11 ; Compare first 11 bytes
|
||||||
rep cmpsb ; Compare si and di cx times
|
rep cmpsb ; Compare si and di cx times
|
||||||
je load_fat ; We found the LOADEEEEEEEER!!!
|
je load_fat ; We found the loader
|
||||||
add ax, 32 ; File entry offset
|
add ax, 32 ; File entry offset
|
||||||
mov di, BUFFER_OFF ; Point back to the start of the entry
|
mov di, BUFFER_OFF ; Point back to the start of the entry
|
||||||
add di, ax ; Add the offset to point to the next entry
|
add di, ax ; Add the offset to point to the next entry
|
||||||
|
@ -150,14 +150,14 @@ load_fat:
|
||||||
mov cx, ax ; Store in cx
|
mov cx, ax ; Store in cx
|
||||||
mov ax, word [reservedSectors] ; Convert the first fat on the disk
|
mov ax, word [reservedSectors] ; Convert the first fat on the disk
|
||||||
mov di, BUFFER_OFF ; Set es:di and load the fat sectors into the disk buffer
|
mov di, BUFFER_OFF ; Set es:di and load the fat sectors into the disk buffer
|
||||||
call read_sectors ; Read the sectooooooooooors !!!
|
call read_sectors ; Read the sectors
|
||||||
|
|
||||||
;; LOAD THE CLUSTERS OF THE LOADER AND JUMP
|
;; LOAD THE CLUSTERS OF THE LOADER AND JUMP
|
||||||
mov di, LOAD_SEG
|
mov di, LOAD_SEG
|
||||||
mov es, di ; Set es:bx to where the file will load
|
mov es, di ; Set es:bx to where the file will load
|
||||||
mov di, LOAD_OFF
|
mov di, LOAD_OFF
|
||||||
pop ax ; File cluster restored
|
pop ax ; File cluster restored
|
||||||
call read_clusters ; Read clusters from the file
|
call read_clusters ; Read clusters from the file
|
||||||
mov dl, byte [Bootdrv] ; Pass the boot Bootdrv into dl
|
mov dl, byte [Bootdrv] ; Pass the boot Bootdrv into dl
|
||||||
jmp LOAD_SEG:LOAD_OFF ; Jump to the file loaded!
|
jmp LOAD_SEG:LOAD_OFF ; Jump to the file loaded!
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#ifndef _I386_TYPE_
|
|
||||||
#define _I386_TYPE_
|
|
||||||
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -7,28 +7,45 @@
|
||||||
// Desc: Assertions //
|
// Desc: Assertions //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef __kaleid_assert_h
|
#ifndef _KALCOMM_ASSERT_H
|
||||||
#define __kaleid_assert_h
|
#define _KALCOMM_ASSERT_H
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
|
#error "don't include common/types.h without common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _OSK_SOURCE
|
||||||
|
|
||||||
|
#if !defined(_NO_DEBUG) && !defined(NDEBUG)
|
||||||
|
|
||||||
|
// uses panic() in kernel, abort() in system
|
||||||
|
noreturn void ___assert_handler(const char *, const char *, int, const char *);
|
||||||
|
|
||||||
|
#define assert(x) do{if(unlikely(!(x)))___assert_handler(#x, __FILE__, __LINE__, __func__);}while(0);
|
||||||
|
|
||||||
|
#else // not debugging
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
|
#define NDEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const char *panicstr;
|
#if !defined(_NO_DEBUG)
|
||||||
extern void panic(const char *) __dead;
|
#define _NO_DEBUG 1
|
||||||
|
#endif
|
||||||
#define assert(x) do{if(!(x))panic(#x);}while(0);
|
|
||||||
|
|
||||||
#define assert_never_used(x) do{static bool __anu_##x = FALSE; \
|
|
||||||
assert(__anu_##x == FALSE); __anu_##x = TRUE;}while(0);
|
|
||||||
|
|
||||||
#define assert_used_once(x) do{static bool __anu_##x; assert(__anu_##x == TRUE);} while(0);
|
|
||||||
|
|
||||||
#else // NDEBUG
|
|
||||||
|
|
||||||
#define assert(x)
|
#define assert(x)
|
||||||
#define assert_never_used(x)
|
|
||||||
#define assert_used_once(x)
|
#endif
|
||||||
|
|
||||||
#endif // NDEBUG
|
#else // !defined(_OSK_SOURCE)
|
||||||
|
|
||||||
|
#if defined(_NO_DEBUG) && !defined(NDEBUG)
|
||||||
|
#define NDEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,23 @@
|
||||||
// Desc: Atomic stuff //
|
// Desc: Atomic stuff //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef __kaleid_atomic_h
|
#ifndef _KALCOMM_ATOMIC_H
|
||||||
#define __kaleid_atomic_h
|
#define _KALCOMM_ATOMIC_H
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
|
#error "don't include common/types.h without common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// atomic_t defined in common/types.h
|
// atomic_t defined in common/types.h
|
||||||
|
|
||||||
#define cli() // XXX
|
#ifdef _KALEID_KERNEL
|
||||||
#define sti() // XXX
|
|
||||||
#define hlt() // XXX
|
// only available in the kernel
|
||||||
|
#define cli() asm volatile ("cli")
|
||||||
|
#define sti() asm volatile ("sti")
|
||||||
|
#define hlt() asm volatile ("hlt")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,25 +7,39 @@
|
||||||
// Desc: Standard include file for both kernel/ and system/ //
|
// Desc: Standard include file for both kernel/ and system/ //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
|
#define _KALCOMM_COMMON_H
|
||||||
|
|
||||||
#ifndef __kaleid_common_h
|
#if !defined(_OSK_SOURCE) && (defined(_KALEID_KERNEL) || defined(_KALEID_SYSTEM))
|
||||||
#define __kaleid_common_h
|
#define _OSK_SOURCE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define true 1
|
#if !defined(TRUE) && !defined(FALSE)
|
||||||
#define TRUE 1
|
# define TRUE 1
|
||||||
#define YES 1
|
# define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define false 0
|
#ifdef _OSK_SOURCE
|
||||||
#define FALSE 0
|
# define YES 1
|
||||||
#define NO 0
|
# define NO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NULL ((void*)0)
|
#ifndef NULL
|
||||||
|
# define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PACKED __attribute__((packed))
|
#ifndef PACKED
|
||||||
#define __dead __attribute__((noreturn))
|
# define PACKED __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define THROWS(...)
|
#ifndef noreturn
|
||||||
#define ERRS(...)
|
# define noreturn __attribute__((noreturn))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(likely) && !defined(unlikely)
|
||||||
|
# define likely(x) __builtin_expect((x), 1)
|
||||||
|
# define unlikely(x) __builtin_expect((x), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
|
|
@ -13,18 +13,29 @@
|
||||||
// We may do a script that generates "config.h" for the user, asking about
|
// We may do a script that generates "config.h" for the user, asking about
|
||||||
// the different configuration choices in the terminal.
|
// the different configuration choices in the terminal.
|
||||||
|
|
||||||
#ifndef __kaleid_config_h
|
#ifndef _KALCOMM_CONFIG_H
|
||||||
#define __kaleid_config_h
|
#define _KALCOMM_CONFIG_H
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// General configuration choices //
|
// General configuration choices //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
// Enable multiprocessor support?
|
//
|
||||||
// Right now this has to be left to NO
|
// Enable/disable multiprocessor support
|
||||||
|
//
|
||||||
#define MULTIPROCESSOR NO
|
#define MULTIPROCESSOR NO
|
||||||
|
|
||||||
// etc...
|
//
|
||||||
|
// Enable/disable preemptivity
|
||||||
|
//
|
||||||
|
#define PREEMPTIVE YES
|
||||||
|
|
||||||
|
//
|
||||||
|
// Size of a tabulation in spaces
|
||||||
|
// Default: 4 spaces/tab
|
||||||
|
//
|
||||||
|
#define TABSIZE 4
|
||||||
|
|
||||||
// this file is to be progressively filled
|
// this file is to be progressively filled
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,18 +13,29 @@
|
||||||
// We may do a script that generates "config.h" for the user, asking about
|
// We may do a script that generates "config.h" for the user, asking about
|
||||||
// the different configuration choices in the terminal.
|
// the different configuration choices in the terminal.
|
||||||
|
|
||||||
#ifndef __kaleid_config_h
|
#ifndef _KALCOMM_CONFIG_H
|
||||||
#define __kaleid_config_h
|
#define _KALCOMM_CONFIG_H
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// General configuration choices //
|
// General configuration choices //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
// Enable multiprocessor support?
|
//
|
||||||
// Right now this has to be left to NO
|
// Enable/disable multiprocessor support
|
||||||
|
//
|
||||||
#define MULTIPROCESSOR NO
|
#define MULTIPROCESSOR NO
|
||||||
|
|
||||||
// etc...
|
//
|
||||||
|
// Enable/disable preemptivity
|
||||||
|
//
|
||||||
|
#define PREEMPTIVE YES
|
||||||
|
|
||||||
|
//
|
||||||
|
// Size of a tabulation in spaces
|
||||||
|
// Default: 4 spaces/tab
|
||||||
|
//
|
||||||
|
#define TABSIZE 4
|
||||||
|
|
||||||
// this file is to be progressively filled
|
// this file is to be progressively filled
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Conversion utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_CONVERT_H
|
||||||
|
#define _KALCOMM_CONVERT_H
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
|
#include "common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _OSK_SOURCE
|
||||||
|
# define itoa _osk_itoa
|
||||||
|
# define atoi _osk_atoi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *itoa(int, char *, int);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,52 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Conversion utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "common/convert.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Digits table for bases <=36
|
||||||
|
//
|
||||||
|
static const char digits[36] =
|
||||||
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Integer to string in any base between 2 and 36 (included)
|
||||||
|
//
|
||||||
|
char *itoa(int i, char *str, int base)
|
||||||
|
{
|
||||||
|
int neg = 0;
|
||||||
|
char *orig = str;
|
||||||
|
|
||||||
|
if (base < 2 || base > 36)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// deal with negatives
|
||||||
|
if (i < 0) {
|
||||||
|
neg = 1;
|
||||||
|
i = -i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// deal with zero separatly
|
||||||
|
if (i == 0) {
|
||||||
|
*str++ = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute digits... in reverse order
|
||||||
|
while (i > 0) {
|
||||||
|
*str++ = digits[i % base];
|
||||||
|
i /= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neg) *str++ = '-';
|
||||||
|
*str = '\0';
|
||||||
|
|
||||||
|
return reverse(orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: mem*() functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "common/memory.h"
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: sprintf()-related functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "common/string.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Format str according to fmt using ellipsed arguments
|
||||||
|
//
|
||||||
|
int sprintf(char *str, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap);
|
||||||
|
ret = vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsprintf(char *str, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// (v)sprintf() but with a size limit: no more than n bytes are written in str
|
||||||
|
// XXX null termination behavior?
|
||||||
|
//
|
||||||
|
int snprintf(char *str, size_t n, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap);
|
||||||
|
ret = vsnprintf(str, n, fmt, ap)
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
while (*fmt && ret < n) {
|
||||||
|
if (*fmt != '%') {
|
||||||
|
*str++ = *fmt++;
|
||||||
|
ret++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'd':
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Implementation of describe_status() //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
static const char *descriptions[] = {
|
||||||
|
[-SUCCESS] = "Success",
|
||||||
|
[-FAILED] = "Failed (no precision)",
|
||||||
|
[-NOT_PERMITTED] = "Operation not permitted",
|
||||||
|
[-ACCESS_DENIED] = "Access denied",
|
||||||
|
|
||||||
|
[-BAD_ARGUMENT] = "Bad argument",
|
||||||
|
[-BAD_ARG_RANGE] = "Bad argument (not in range)",
|
||||||
|
[-BAD_ARG_NULL] = "Bad argument (null pointer)",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *describe_status(status_t status)
|
||||||
|
{
|
||||||
|
(void)descriptions;
|
||||||
|
(void)status;
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
|
@ -4,28 +4,64 @@
|
||||||
// Authors: spectral` //
|
// Authors: spectral` //
|
||||||
// NeoX //
|
// NeoX //
|
||||||
// //
|
// //
|
||||||
// Desc: strlen() function //
|
// Desc: String-related functions //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include "common/string.h"
|
#include "common/string.h"
|
||||||
|
|
||||||
// XXX several of these should be re-wrote in assembly
|
// TODO multibyte, assembly
|
||||||
|
|
||||||
size_t strlen(const char *s)
|
//
|
||||||
|
// Returns str's length
|
||||||
|
//
|
||||||
|
size_t strlen(const char *str)
|
||||||
|
{
|
||||||
|
const char *base = str;
|
||||||
|
|
||||||
|
while (*str++);
|
||||||
|
|
||||||
|
return (str - base - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the string src into dest
|
||||||
|
//
|
||||||
|
char *strcpy(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
char *base = dest;
|
||||||
|
while ((*dest++ = *src++));
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// strcpy() but safer
|
||||||
|
//
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; s; s++, i++);
|
for (i = 0; i < n && src[i]; i++) {
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
while (i < n) dest[i++] = 0;
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*size_t wcslen(const wchar_t *s);
|
//
|
||||||
|
// Reverses a string
|
||||||
|
//
|
||||||
|
char *reverse(char *str)
|
||||||
{
|
{
|
||||||
int i;
|
char ch, *orig = str;
|
||||||
|
size_t n = strlen(str);
|
||||||
|
char *temp = str + n - 1;
|
||||||
|
|
||||||
for (i = 0; s; s++, i++);
|
while (temp > str) {
|
||||||
|
ch = *temp;
|
||||||
return s;
|
*temp-- = *str;
|
||||||
}*/
|
*str++ = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: mem*() functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_MEMORY_H
|
||||||
|
#define _KALCOMM_MEMORY_H
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
|
#include "common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -7,9 +7,19 @@
|
||||||
// Desc: Values for status_t //
|
// Desc: Values for status_t //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_STATUS_H
|
||||||
|
#define _KALCOMM_STATUS_H
|
||||||
|
|
||||||
#ifndef __kaleid_status_h
|
#ifndef _KALCOMM_COMMON_H
|
||||||
#define __kaleid_status_h
|
#error "don't include common/types.h without common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _OSK_SOURCE
|
||||||
|
# define describe_status _osk_describe_status
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// see in common/lib/status.c for status messages
|
||||||
|
const char *describe_status(status_t);
|
||||||
|
|
||||||
#define STATUS_FAILED(x) ((x) < 0))
|
#define STATUS_FAILED(x) ((x) < 0))
|
||||||
#define STATUS_SUCCESS(x) (!STATUS_FAILED(x))
|
#define STATUS_SUCCESS(x) (!STATUS_FAILED(x))
|
||||||
|
@ -23,8 +33,9 @@
|
||||||
|
|
||||||
#define BAD_ARGUMENT (-4) // invalid arguments, can't be more precise
|
#define BAD_ARGUMENT (-4) // invalid arguments, can't be more precise
|
||||||
#define BAD_ARG_RANGE (-5) // arguments out of range
|
#define BAD_ARG_RANGE (-5) // arguments out of range
|
||||||
|
#define BAD_ARG_NULL (-6) // unexpected NULL argument
|
||||||
|
|
||||||
#define TRY_AGAIN (-6) // EAGAIN
|
#define TRY_AGAIN (-7) // EAGAIN
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,36 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|
||||||
#ifndef __kaleid_string_h
|
#ifndef _KALCOMM_STRING_H
|
||||||
#define __kaleid_string_h
|
#define _KALCOMM_STRING_H
|
||||||
|
|
||||||
|
#ifndef _KALCOMM_COMMON_H
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t strlen(const char *s);
|
#ifndef _OSK_SOURCE
|
||||||
|
|
||||||
|
# define strlen _osk_strlen
|
||||||
|
# define strcpy _osk_strcpy
|
||||||
|
# define strncpy _osk_strncpy
|
||||||
|
# define reverse _osk_reverse
|
||||||
|
|
||||||
|
# define sprintf _osk_sprintf
|
||||||
|
# define snprintf _osk_snprintf
|
||||||
|
# define vsprintf _osk_vsprintf
|
||||||
|
# define vsnprintf _osk_vsnprintf
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t strlen(const char *);
|
||||||
|
char *strcpy(char *, const char *);
|
||||||
|
char *strncpy(char *, const char *, size_t);
|
||||||
|
char *reverse(char *);
|
||||||
|
|
||||||
|
int sprintf(char *, const char *, ...);
|
||||||
|
int snprintf(char *, size_t, const char *, ...);
|
||||||
|
int vsprintf(char *, const char *, va_list);
|
||||||
|
int vsnprintf(char *, size_t, const char *, va_list);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,25 +8,34 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|
||||||
#ifndef __kaleid_types_h
|
#ifndef _KALCOMM_TYPES_H
|
||||||
#define __kaleid_types_h
|
#define _KALCOMM_TYPES_H
|
||||||
|
|
||||||
typedef _Bool bool;
|
#ifndef _KALCOMM_COMMON_H
|
||||||
typedef unsigned char uchar;
|
#error "don't include common/types.h without common/common.h"
|
||||||
typedef unsigned short ushort;
|
#endif
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef unsigned long ulong;
|
|
||||||
typedef long double ldouble;
|
|
||||||
typedef short status_t;
|
|
||||||
typedef short port_t;
|
|
||||||
typedef uint wchar_t;
|
|
||||||
typedef ulong size_t;
|
|
||||||
typedef long ssize_t;
|
|
||||||
|
|
||||||
|
#ifndef KEEP_KALCOMM_TYPES_MINIMAL
|
||||||
|
typedef _Bool bool;
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
typedef long long llong;
|
||||||
|
typedef unsigned long long ullong;
|
||||||
|
typedef long double ldouble;
|
||||||
|
typedef uint wchar_t;
|
||||||
|
typedef ullong size_t;
|
||||||
|
typedef llong ssize_t;
|
||||||
|
typedef size_t off_t;
|
||||||
|
typedef int atomic_t;
|
||||||
|
typedef ulong pid_t;
|
||||||
|
typedef void *va_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
// XXX
|
typedef short port_t;
|
||||||
typedef int atomic_t;
|
typedef short status_t;
|
||||||
typedef ulong pid_t; // etc...
|
// XXX limits
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,15 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include "kernel/init.h"
|
#include "kernel/init.h"
|
||||||
|
#include "kernel/ke/panic.h"
|
||||||
#include "kernel/io/terminal.h"
|
#include "kernel/io/terminal.h"
|
||||||
|
|
||||||
void _start(void)
|
//
|
||||||
|
// Entry point of kaleid-kernel.elf
|
||||||
|
//
|
||||||
|
void kstart(void)
|
||||||
{
|
{
|
||||||
assert(strlen("test") == 4);
|
|
||||||
|
|
||||||
kterm_init();
|
kterm_init();
|
||||||
kterm_print("Hello World!");
|
panic("Goodbye World :(");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,10 @@
|
||||||
// Desc: Include file for init.c //
|
// Desc: Include file for init.c //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef __kaleid_kernel_init_h
|
#ifndef _KALKERN_INIT_H
|
||||||
#define __kaleid_kernel_init_h
|
#define _KALKERN_INIT_H
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/string.h"
|
|
||||||
|
|
||||||
// kernel entry point
|
// kernel entry point
|
||||||
void kstart(void);
|
void kstart(void);
|
||||||
|
|
|
@ -7,15 +7,15 @@
|
||||||
// Desc: Ports I/O //
|
// Desc: Ports I/O //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef __kaleid_kernel_io_ports_h
|
#ifndef _KALKERN_IO_PORTS_H
|
||||||
#define __kaleid_kernel_io_ports_h
|
#define _KALKERN_IO_PORTS_H
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
#define outb(port,val) asm volatile ("outb %1, %0" : : "dN" (port), "a" (value))
|
#define outb(port,val) asm volatile ("outb %1, %0" : : "dN" (port), "a" (value))
|
||||||
|
|
||||||
uchar inb(port_t port);
|
uchar inb(port_t);
|
||||||
ushort inw(port_t port);
|
ushort inw(port_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,139 +9,178 @@
|
||||||
|
|
||||||
#include "kernel/io/terminal.h"
|
#include "kernel/io/terminal.h"
|
||||||
|
|
||||||
// VGA buffer size
|
//
|
||||||
static const size_t kterm_width = 80;
|
// VGA-related macros
|
||||||
static const size_t kterm_height = 25;
|
//
|
||||||
|
|
||||||
// position in the buffer
|
|
||||||
static size_t current_row;
|
|
||||||
static size_t current_col;
|
|
||||||
|
|
||||||
static uchar current_color;
|
|
||||||
|
|
||||||
// each buffer entry is composed of two bytes
|
|
||||||
// one is the color code, the other the character
|
|
||||||
static ushort *const buffer = (ushort *)0xB8000;
|
|
||||||
|
|
||||||
#define ComputeColorCode(fg, bg) ((fg) | (bg) << 4)
|
#define ComputeColorCode(fg, bg) ((fg) | (bg) << 4)
|
||||||
#define ComputeEntryOffset(x, y) ((y) * kterm_width + (x))
|
#define ComputeEntryOffset(kt, x, y) ((y) * kt->kt_width + (x))
|
||||||
#define ComputeEntry(ch, cl) (((ushort)(ch)) | (ushort)(cl) << 8)
|
#define ComputeEntry(ch, cl) (((ushort)(ch)) | (ushort)(cl) << 8)
|
||||||
|
|
||||||
|
//
|
||||||
|
// VGA output
|
||||||
|
//
|
||||||
|
static struct kterm _kt_vga = {
|
||||||
|
.kt_buffer = (ushort *)0xB8000,
|
||||||
|
.kt_width = 80,
|
||||||
|
.kt_height = 25,
|
||||||
|
.kt_curr_x = 0,
|
||||||
|
.kt_curr_y = 0,
|
||||||
|
.kt_color = ComputeColorCode(KTERM_COLOR_LGREY, KTERM_COLOR_BLACK),
|
||||||
|
.kt_lock = NULL,
|
||||||
|
#ifndef _NO_DEBUG
|
||||||
|
.kt_init = FALSE,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Standard output terminal
|
||||||
|
//
|
||||||
|
struct kterm *kt_stdout;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize standard output
|
||||||
|
//
|
||||||
void kterm_init(void)
|
void kterm_init(void)
|
||||||
{
|
{
|
||||||
assert_never_used(kterm_init);
|
assert(!kt_stdout && !_kt_vga.kt_init && "kterm_init() called twice");
|
||||||
|
|
||||||
kterm_change_color(ComputeColorCode(KTERM_COLOR_LIGHT_GREY, KTERM_COLOR_BLACK));
|
#ifndef _NO_DEBUG
|
||||||
kterm_clear();
|
_kt_vga.kt_init = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// to be switched to VESA
|
||||||
|
kt_stdout = &_kt_vga;
|
||||||
|
ktclear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void kterm_clear(void)
|
//
|
||||||
|
// Fills terminal with spaces
|
||||||
|
// XXX would '\0' work too?
|
||||||
|
//
|
||||||
|
status_t kterm_clear(struct kterm *kt)
|
||||||
{
|
{
|
||||||
size_t x, y;
|
size_t i;
|
||||||
|
|
||||||
assert_used_once(kterm_init);
|
if (kt == NULL)
|
||||||
|
return BAD_ARG_NULL;
|
||||||
|
|
||||||
for (x = 0; x < kterm_width; x++) {
|
assert(kt->kt_init && "kterm_clear called before initialization");
|
||||||
for (y = 0; y < kterm_height; y++) {
|
|
||||||
const size_t offset = ComputeEntryOffset(x,y);
|
kterm_lock(kt);
|
||||||
buffer[offset] = ComputeEntry(' ', current_color);
|
|
||||||
}
|
const ushort filler = ComputeEntry(' ', kt->kt_color);
|
||||||
|
const size_t bufsize = kt->kt_width * kt->kt_height;
|
||||||
|
|
||||||
|
for (i = 0; i < bufsize; i++) {
|
||||||
|
// XXX implement memset()
|
||||||
|
kt->kt_buffer[i] = filler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// go back to beginning
|
kt->kt_curr_x = kt->kt_curr_y = 0;
|
||||||
current_row = current_col = 0;
|
|
||||||
|
|
||||||
// XXX cursor update
|
kterm_unlock(kt);
|
||||||
}
|
|
||||||
|
|
||||||
status_t kterm_change_color(uchar color)
|
|
||||||
{
|
|
||||||
if (color > KTERM_COLOR_WHITE)
|
|
||||||
return BAD_ARG_RANGE;
|
|
||||||
|
|
||||||
current_color = color;
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kterm_putchar(char ch)
|
//
|
||||||
|
// Change the color code
|
||||||
|
//
|
||||||
|
status_t kterm_change_color(struct kterm *kt, uchar color)
|
||||||
|
{
|
||||||
|
if (color > KTERM_COLOR_WHITE)
|
||||||
|
return BAD_ARG_RANGE;
|
||||||
|
|
||||||
|
if (kt == NULL)
|
||||||
|
return BAD_ARG_NULL;
|
||||||
|
|
||||||
|
kterm_lock(kt);
|
||||||
|
kt->kt_color = color;
|
||||||
|
kterm_unlock(kt);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Writes a single character on the terminal (UNLOCKED version)
|
||||||
|
//
|
||||||
|
// DEPRECATED:
|
||||||
|
// - always use kterm_putch (LOCKED version)
|
||||||
|
// - doesn't check for NULL input
|
||||||
|
//
|
||||||
|
void kterm_putch_unlocked(struct kterm *kt, char ch)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
size_t prev;
|
size_t prev_row;
|
||||||
|
|
||||||
assert_used_once(kterm_init);
|
|
||||||
|
|
||||||
// carriage return takes us back to the beginning of the line
|
// carriage return takes us back to the beginning of the line
|
||||||
// no further test should be necessary
|
// no further test should be necessary
|
||||||
if (ch == '\r') { current_col = 0; return; }
|
if (ch == '\r') { kt->kt_curr_x = 0; return; }
|
||||||
|
|
||||||
// line feed first takes us to the very end of the line
|
// line feed first takes us to the very end of the line
|
||||||
// later in this function we actually do the line feed
|
// later in this function we actually do the line feed
|
||||||
else if (ch == '\n') { current_col = kterm_width - 1; }
|
else if (ch == '\n') { kt->kt_curr_y = kt->kt_width - 1; }
|
||||||
|
|
||||||
// tabulations account for 4 spaces
|
// tabulations account for 4 spaces
|
||||||
else if (ch == '\t') {
|
else if (ch == '\t') {
|
||||||
prev = current_row;
|
prev_row = kt->kt_curr_y;
|
||||||
// compiler will optimize this away
|
// compiler will optimize this away
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < TABSIZE; i++) {
|
||||||
// tabulations can't spread over two lines
|
// tabulations can't spread over two lines
|
||||||
if (current_row != prev) return;
|
if (kt->kt_curr_y == prev_row) {
|
||||||
|
kterm_putch_unlocked(kt, ' ');
|
||||||
kterm_putchar(' ');
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX check whether we were given a writable character
|
// XXX check whether we were given a writable character
|
||||||
else {
|
else {
|
||||||
const size_t offset = ComputeEntryOffset(current_col, current_row);
|
const size_t offset = ComputeEntryOffset(kt, kt->kt_curr_x, kt->kt_curr_y);
|
||||||
buffer[offset] = ComputeEntry(ch, current_color);
|
kt->kt_buffer[offset] = ComputeEntry(ch, kt->kt_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of line?
|
// end of line?
|
||||||
if (++current_col == kterm_width) {
|
if (++kt->kt_curr_x == kt->kt_width) {
|
||||||
current_col = 0;
|
kt->kt_curr_x = 0;
|
||||||
|
|
||||||
// end of buffer?
|
// line feed + end of buffer?
|
||||||
if (++current_row == kterm_height) {
|
if (++kt->kt_curr_y == kt->kt_height) {
|
||||||
current_row = 0;
|
kt->kt_curr_y = 0;
|
||||||
// XXX save previous buffer(?) and clear
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kterm_print(const char *s)
|
//
|
||||||
|
// Writes a single character on the terminal (LOCKED version)
|
||||||
|
//
|
||||||
|
status_t kterm_putch(struct kterm *kt, char ch)
|
||||||
{
|
{
|
||||||
while (*s) {
|
if (kt == NULL)
|
||||||
kterm_putchar(*s);
|
return BAD_ARG_NULL;
|
||||||
s++;
|
|
||||||
|
kterm_lock(kt);
|
||||||
|
kterm_putch_unlocked(kt, ch);
|
||||||
|
kterm_unlock(kt);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Print string on kterminal
|
||||||
|
//
|
||||||
|
status_t kterm_print(struct kterm *kt, const char *str)
|
||||||
|
{
|
||||||
|
if (kt == NULL)
|
||||||
|
return BAD_ARG_NULL;
|
||||||
|
|
||||||
|
kterm_lock(kt);
|
||||||
|
while (*str) {
|
||||||
|
kterm_putch_unlocked(kt, *str++);
|
||||||
}
|
}
|
||||||
}
|
kterm_unlock(kt);
|
||||||
|
|
||||||
void panic(const char *s)
|
return SUCCESS;
|
||||||
{
|
|
||||||
cli();
|
|
||||||
|
|
||||||
panicstr = s;
|
|
||||||
|
|
||||||
kterm_clear();
|
|
||||||
|
|
||||||
kterm_print("panic! - ");
|
|
||||||
kterm_print(s);
|
|
||||||
|
|
||||||
while (1) hlt();
|
|
||||||
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,37 +7,58 @@
|
||||||
// Desc: Early terminal functions //
|
// Desc: Early terminal functions //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef __kaleid_kernel_io_terminal_h
|
#ifndef _KALKERN_IO_KTERM_H
|
||||||
#define __kaleid_kernel_io_terminal_h
|
#define _KALKERN_IO_KTERM_H
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
// all available colors
|
// all available colors
|
||||||
enum {
|
enum kterm_color {
|
||||||
KTERM_COLOR_BLACK,
|
KTERM_COLOR_BLACK, KTERM_COLOR_BLUE,
|
||||||
KTERM_COLOR_BLUE,
|
KTERM_COLOR_GREEN, KTERM_COLOR_CYAN,
|
||||||
KTERM_COLOR_GREEN,
|
KTERM_COLOR_RED, KTERM_COLOR_MAGENTA,
|
||||||
KTERM_COLOR_CYAN,
|
KTERM_COLOR_BROWN, KTERM_COLOR_LGREY,
|
||||||
KTERM_COLOR_RED,
|
KTERM_COLOR_DARK_GREY, KTERM_COLOR_LBLUE,
|
||||||
KTERM_COLOR_MAGENTA,
|
KTERM_COLOR_LGREEN, KTERM_COLOR_LCYAN,
|
||||||
KTERM_COLOR_BROWN,
|
KTERM_COLOR_LRED, KTERM_COLOR_LMAGENTA,
|
||||||
KTERM_COLOR_LIGHT_GREY,
|
KTERM_COLOR_LBROWN, KTERM_COLOR_WHITE
|
||||||
KTERM_COLOR_DARK_GREY,
|
|
||||||
KTERM_COLOR_LIGHT_BLUE,
|
|
||||||
KTERM_COLOR_LIGHT_GREEN,
|
|
||||||
KTERM_COLOR_LIGHT_CYAN,
|
|
||||||
KTERM_COLOR_LIGHT_RED,
|
|
||||||
KTERM_COLOR_LIGHT_MAGENTA,
|
|
||||||
KTERM_COLOR_LIGHT_BROWN,
|
|
||||||
KTERM_COLOR_WHITE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void kterm_init(void);
|
struct kterm {
|
||||||
void kterm_clear(void);
|
void *kt_lock;
|
||||||
void kterm_putchar(char ch);
|
ushort *kt_buffer;
|
||||||
void kterm_print(const char *s);
|
uchar kt_color;
|
||||||
|
size_t kt_width;
|
||||||
|
size_t kt_height;
|
||||||
|
off_t kt_curr_x;
|
||||||
|
off_t kt_curr_y;
|
||||||
|
#ifndef _NO_DEBUG
|
||||||
|
bool kt_init;
|
||||||
|
#endif
|
||||||
|
|
||||||
status_t kterm_change_color(uchar color) ERRS(BAD_ARG_RANGE);
|
};
|
||||||
|
|
||||||
|
// current "standard" terminal
|
||||||
|
extern struct kterm *kt_stdout;
|
||||||
|
|
||||||
|
void kterm_init(void);
|
||||||
|
status_t kterm_clear(struct kterm *);
|
||||||
|
status_t kterm_putch(struct kterm *, char);
|
||||||
|
status_t kterm_print(struct kterm *, const char *);
|
||||||
|
status_t kterm_change_color(struct kterm *, uchar);
|
||||||
|
|
||||||
|
#ifdef _UNLOCKED_IO
|
||||||
|
void kterm_putch_unlocked(struct kterm *, char);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ktclear() kterm_clear(kt_stdout)
|
||||||
|
#define ktputch(c) kterm_putch(kt_stdout, (c))
|
||||||
|
#define ktprint(s) kterm_print(kt_stdout, (s))
|
||||||
|
#define ktchcol(c) kterm_change_color(kt_stdout, (c))
|
||||||
|
|
||||||
|
#define kterm_lock(kt)
|
||||||
|
#define kterm_trylock(kt)
|
||||||
|
#define kterm_unlock(kt)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: How NOT to panic 101 //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "kernel/ke/panic.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Panic message
|
||||||
|
//
|
||||||
|
const char *panicstr = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Failed assert() handler
|
||||||
|
//
|
||||||
|
noreturn void ___assert_handler(const char *msg, const char *file, int line, const char *func)
|
||||||
|
{
|
||||||
|
// not getting out of here
|
||||||
|
cli();
|
||||||
|
|
||||||
|
(void)file; (void)line; (void)func;
|
||||||
|
|
||||||
|
// XXX sprintf() to create a proper panicstr
|
||||||
|
panic(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Your best boy panic()
|
||||||
|
//
|
||||||
|
void panic(const char *str)
|
||||||
|
{
|
||||||
|
cli();
|
||||||
|
|
||||||
|
ktclear();
|
||||||
|
|
||||||
|
if (str == NULL) {
|
||||||
|
str = "(no message given)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panicstr) {
|
||||||
|
// shouldn't be possible
|
||||||
|
ktprint("double panic!\n");
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
|
|
||||||
|
panicstr = str;
|
||||||
|
|
||||||
|
ktprint("panic! - ");
|
||||||
|
ktprint(str);
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Looking to create some panic? Look no further! //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_KE_PANIC_H
|
||||||
|
#define _KALKERN_KE_PANIC_H
|
||||||
|
|
||||||
|
#include "kernel/io/terminal.h"
|
||||||
|
|
||||||
|
extern const char *panicstr;
|
||||||
|
noreturn void panic(const char *);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,12 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Memory allocation routines //
|
||||||
|
// Only exists to trigger Neox //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include "kernel/mm/malloc.h"
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Memory allocation routines //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_MM_MALLOC_H
|
||||||
|
#define _KALKERN_MM_MALLOC_H
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Test file for common/ //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define KEEP_KALCOMM_TYPES_MINIMAL
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "common/string.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
const char *test1 = "test string\n";
|
||||||
|
char *test2 = malloc(strlen(test1));
|
||||||
|
char *test3 = malloc(strlen(test1));
|
||||||
|
|
||||||
|
printf("1\n");
|
||||||
|
|
||||||
|
#undef strlen
|
||||||
|
assert(strlen("test string") == _osk_strlen("test string"));
|
||||||
|
|
||||||
|
#undef strcpy
|
||||||
|
assert(strcmp(strcpy(test2, test1), _osk_strcpy(test3, test1)) == 0);
|
||||||
|
|
||||||
|
// tests done
|
||||||
|
printf("2\n");
|
||||||
|
|
||||||
|
free(test2);
|
||||||
|
free(test3);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
ENTRY(kstart)
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x4000; /* XXX 0x4000 is temporary */
|
||||||
|
|
||||||
|
.text : AT(ADDR(.text) - 0x4000)
|
||||||
|
{
|
||||||
|
_code = .;
|
||||||
|
*(.text)
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : AT(ADDR(.data) - 0x4000)
|
||||||
|
{
|
||||||
|
_data = .;
|
||||||
|
*(.data)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eh_frame : AT(ADDR(.eh_frame) - 0x4000)
|
||||||
|
{
|
||||||
|
_ehframe = .;
|
||||||
|
*(.eh_frame)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : AT(ADDR(.bss) - 0x4000)
|
||||||
|
{
|
||||||
|
_bss = .;
|
||||||
|
*(.bss)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* You usually need to include generated COMMON symbols
|
||||||
|
* under kernel BSS section or use gcc's -fno-common
|
||||||
|
*/
|
||||||
|
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.comment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
// Desc: Project Tree //
|
// Desc: Project Tree //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// XXX *not* up to date
|
||||||
|
|
||||||
src/
|
src/
|
||||||
|
|
|
|
||||||
+ boot/
|
+ boot/
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
make
|
|
||||||
cp ../bin/bootloader.bin "~/Documents/GNU OSK/bin/bootloader.bin"
|
|
||||||
qemu-system-x86_64 -hda "~/Documents/GNU OSK/bin/bootloader.bin"
|
|
||||||
qemu-system-i386 -hda "~/Documents/GNU OSK/bin/bootloader.bin"
|
|
Loading…
Reference in New Issue