Compare commits
186 Commits
e314ff97f7
...
main
Author | SHA1 | Date | |
---|---|---|---|
44f5d687b0 | |||
1f5a358b19 | |||
e15f0af292 | |||
8e2017bd29 | |||
11125325ca | |||
81c54647d2 | |||
fc79a47957 | |||
6c8c158a1f | |||
65f08e3887 | |||
a14cc5df28 | |||
2e09db2dd1 | |||
5e561bfa15 | |||
8dd5373e7f | |||
3b798e5daa | |||
70739744ac | |||
1e981755de | |||
3766464c47 | |||
a9ed5947a8 | |||
db4ed04dd6 | |||
7b7cc86999 | |||
18486a6705 | |||
c9a92819b4 | |||
f75e121251 | |||
9c89433db5 | |||
69686a2c91 | |||
1ca8c68cf5 | |||
e60969b37a | |||
dbdf851dd2 | |||
d7626df19c | |||
95fec015f2 | |||
dc84d5856b | |||
19eea56a7e | |||
8c63eac00e | |||
d4db6acf61 | |||
540226fb0f | |||
2d6b24842e | |||
494a0f425c | |||
2ba4037af2 | |||
7ba3eead14 | |||
35b73e8004 | |||
4ec1a4962d | |||
24c7ea8b19 | |||
d2f7a3ce26 | |||
57ce3c792d | |||
d889a251ef | |||
b3be29246e | |||
2fe4ac5ad5 | |||
fa3ef311ad | |||
02c3d72a4b | |||
b9691b1948 | |||
916e8b6f19 | |||
bab3069152 | |||
61debdcb85 | |||
4028372475 | |||
6bdba0cb4f | |||
4a99b82e15 | |||
77928aca4b | |||
dda9c8a1ef | |||
3b0b090430 | |||
917ccf0465 | |||
2edc92bbcc | |||
5383c4eced | |||
903b303322 | |||
db596a9212 | |||
99e2d7053b | |||
33cb3dfa30 | |||
e5bdd1b5ee | |||
bd080a0f9e | |||
570b848625 | |||
c6e2d52831 | |||
0348e04436 | |||
d6a59da6d1 | |||
d39f708a51 | |||
bedbca1154 | |||
738b285e62 | |||
daf510687a | |||
2a281522cf | |||
30d22b3334 | |||
88bf5e7960 | |||
fb1a1bc213 | |||
4bd4198293 | |||
f626edd0f0 | |||
1352201800 | |||
dc12949329 | |||
295c513f2d | |||
9944f79b2e | |||
773f55466e | |||
8203b36092 | |||
da804296c6 | |||
0c280d971b | |||
94b2fa340c | |||
ec3a038a36 | |||
3bc05604db | |||
b7dd7761d5 | |||
3315d85e0c | |||
e8fd6c55eb | |||
d8d31d959f | |||
20ba985b34 | |||
09ea386b21 | |||
1e35f3b710 | |||
11ef629a3a | |||
719c615c92 | |||
3c87632b0c | |||
5fccbf3708 | |||
a72c3ca195 | |||
6533334824 | |||
ae3cfa7647 | |||
04211e2773 | |||
5fba376e2f | |||
ff058d0ae1 | |||
659ba24f12 | |||
cbcff77a4a | |||
a9bfb49bb8 | |||
f5147e78f9 | |||
4337bc11c8 | |||
8c936f6323 | |||
73b8ffb3b8 | |||
579b9ed349 | |||
55037b75fa | |||
7128f2640a | |||
9e85807a09 | |||
049c31193f | |||
457244222b | |||
577d6c97ec | |||
fd1086b408 | |||
5f075a9090 | |||
9dc9002f00 | |||
3372e386f5 | |||
886f912f36 | |||
5fc90ea240 | |||
9855669662 | |||
5969dcca54 | |||
41786ea523 | |||
29b59c474d | |||
06ade25a46 | |||
fc8bc6a495 | |||
50b1487708 | |||
e5d7b80ed5 | |||
4fb51d4356 | |||
0812a06350 | |||
1640b2e125 | |||
f3db3060af | |||
a4411b0581 | |||
599de25eec | |||
339224f705 | |||
d348ac109e | |||
14758ff4ea | |||
83e513c32f | |||
d6b35a2786 | |||
9479515685 | |||
8b2d35594d | |||
a3bbffcfd9 | |||
64a3f6ee0d | |||
5fe4d12c12 | |||
8b73e8850a | |||
0c540a11da | |||
ab702aabe7 | |||
ed11ec794a | |||
f65d5ce418 | |||
0bcc99997a | |||
a66f9174f4 | |||
9ade568a64 | |||
a64262ee13 | |||
484e013ceb | |||
02059bff33 | |||
3a916908ef | |||
b84d4dbcb8 | |||
854248303f | |||
2728346711 | |||
283f073124 | |||
deca2b9bfc | |||
943f2beab9 | |||
0467c45bf0 | |||
2e41858c77 | |||
96179d996d | |||
4cc1dba5f9 | |||
5ebf8ac6ab | |||
f559e71433 | |||
8fd17276b2 | |||
9b3a6cb5a4 | |||
083468240d | |||
ef75ad874d | |||
c7545d5fc6 | |||
ddf3cfff68 | |||
65a59534b4 | |||
e316910581 |
9
.clang-format
Normal file
9
.clang-format
Normal file
@ -0,0 +1,9 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 8
|
||||
UseTab: AlignWithSpaces
|
||||
BreakBeforeBraces: Linux
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
IndentCaseLabels: false
|
||||
ColumnLimit: 80
|
||||
AlignConsecutiveMacros: true
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,3 +3,5 @@ obj
|
||||
.*
|
||||
compile_commands.json
|
||||
tags
|
||||
base_fonts
|
||||
*.log
|
||||
|
0
.gitmodules
vendored
0
.gitmodules
vendored
30
Makefile
30
Makefile
@ -1,9 +1,9 @@
|
||||
NAME := bozOS
|
||||
|
||||
AS := i386-elf-as
|
||||
ASFLAGS :=
|
||||
ASFLAGS := -g
|
||||
CC := i386-elf-gcc
|
||||
CFLAGS := -std=gnu99 -ffreestanding -Wall -Wextra -iquotelibbozo/headers -iquoteheaders -MMD -fno-omit-frame-pointer -g
|
||||
CFLAGS := -std=gnu99 -ffreestanding -Wall -Wextra -iquotelibbozo/headers -iquoteheaders -MMD -fno-omit-frame-pointer -fstack-protector-all -g3
|
||||
LD := $(CC)
|
||||
LDFLAGS := -T boot/linker.ld -ffreestanding -nostdlib
|
||||
LIBS := -L libbozo/build/ -lbozo -lgcc
|
||||
@ -31,20 +31,30 @@ $(NAME): $(OBJ)
|
||||
$(LD) $(LDFLAGS) -o build/$(NAME).bin $(OBJ) $(LIBS)
|
||||
|
||||
run: $(NAME)
|
||||
qemu-system-i386 -kernel build/$(NAME).bin
|
||||
qemu-system-i386 -kernel build/$(NAME).bin -vga std
|
||||
|
||||
iso: $(NAME)
|
||||
mkdir -p isodir/boot/grub
|
||||
cp build/$(NAME).bin isodir/boot/$(NAME).bin
|
||||
cp config/grub.cfg isodir/boot/grub/grub.cfg
|
||||
grub-mkrescue -o build/$(NAME).iso isodir
|
||||
grub-mkrescue -o build/$(NAME).iso --compress=xz --locales=en@quot --themes= isodir
|
||||
rm -rf isodir
|
||||
|
||||
fast-iso: $(NAME)
|
||||
mkdir -p isodir/boot/grub
|
||||
cp build/$(NAME).bin isodir/boot/$(NAME).bin
|
||||
cp config/grub.cfg isodir/boot/grub/grub.cfg
|
||||
grub-mkrescue -o build/$(NAME).iso --themes= isodir
|
||||
rm -rf isodir
|
||||
|
||||
run-iso: iso
|
||||
qemu-system-i386 -cdrom build/$(NAME).iso
|
||||
qemu-system-i386 -cdrom build/$(NAME).iso -vga std
|
||||
|
||||
debug: iso
|
||||
qemu-system-i386 -s -S build/$(NAME).iso
|
||||
fast-run-iso: fast-iso
|
||||
qemu-system-i386 -cdrom build/$(NAME).iso -vga std
|
||||
|
||||
debug: fast-iso
|
||||
qemu-system-i386 -s -S -cdrom build/$(NAME).iso -vga std -D qemu.log -d in_asm,int -M smm=off
|
||||
|
||||
clean:
|
||||
make -C libbozo clean
|
||||
@ -55,7 +65,9 @@ fclean: clean
|
||||
make -C libbozo fclean
|
||||
rm -rf build
|
||||
|
||||
re: fclean all
|
||||
re:
|
||||
$(MAKE) fclean
|
||||
$(MAKE) all
|
||||
|
||||
.PHONY: all clean fclean re run iso run-iso
|
||||
.PHONY: all clean fclean re run iso run-iso fast-iso fast-run-iso
|
||||
-include $(DEP)
|
||||
|
72
README.md
72
README.md
@ -2,68 +2,10 @@
|
||||
|
||||
This project aims to explore how a kernel works by building our own, gaining hands-on experience with core concepts like memory management, interrupt, keyboard driver, etc
|
||||
|
||||
## INSTALLATION
|
||||
|
||||
### Cross compile the compile
|
||||
[THE DOCUMENTATION](https://wiki.osdev.org/GCC_Cross-Compiler)
|
||||
- install requirement follow [THE DOCUMENTATION](https://wiki.osdev.org/GCC_Cross-Compiler)
|
||||
- Setup the shell
|
||||
``` sh
|
||||
export PREFIX="$HOME/opt/cross"
|
||||
export TARGET=i386-elf
|
||||
export PATH="$PREFIX/bin:$PATH"
|
||||
mkdir $HOME/src
|
||||
cd $HOME/src
|
||||
```
|
||||
- Download [binutils](https://ftp.gnu.org/gnu/binutils/?C=M;O=D)
|
||||
- Download [gcc](https://ftp.gnu.org/gnu/gcc/?C=M;O=D)
|
||||
- Download [gdb](https://ftp.gnu.org/gnu/gdb/?C=M;O=D)
|
||||
- extract archives
|
||||
``` sh
|
||||
tar xf [your binutils archive]
|
||||
tar xf [your gcc archive]
|
||||
tar xf [your gdb archive]
|
||||
```
|
||||
- (protips use -j [nb core])
|
||||
- Compile binutils
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
mkdir build-binutils
|
||||
|
||||
cd build-binutils
|
||||
../binutils-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
|
||||
make
|
||||
make install
|
||||
```
|
||||
- Compile gdb
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
mkdir build-gdb
|
||||
|
||||
cd build-gdb
|
||||
../gdb.x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-werror
|
||||
make all-gdb
|
||||
make install-gdb
|
||||
make
|
||||
make install
|
||||
```
|
||||
- Compile gcc
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
|
||||
# The $PREFIX/bin dir _must_ be in the PATH. We did that above.
|
||||
which -- $TARGET-as || echo $TARGET-as is not in the PATH
|
||||
|
||||
mkdir build-gcc
|
||||
cd build-gcc
|
||||
../gcc-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
|
||||
make all-gcc
|
||||
make all-target-libgcc
|
||||
make install-gcc
|
||||
make install-target-libgcc
|
||||
```
|
||||
|
||||
### Compile and the start the kernel
|
||||
``` sh
|
||||
make run
|
||||
```
|
||||
## Currently supported
|
||||
- screen driver
|
||||
- keyboard driver
|
||||
- [memory pagination](./documentation/memory.md)
|
||||
- interruption
|
||||
- power management (reboot, halt, shutdown)
|
||||
- simple shell
|
@ -1,28 +1,41 @@
|
||||
ENTRY(_start)
|
||||
ENTRY (_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 2M;
|
||||
. = 0x00100000;
|
||||
/* The kernel will live at 3GB + 1MB in the virtual address space, */
|
||||
/* which will be mapped to 1MB in the physical address space. */
|
||||
/* Note that we page-align the sections. */
|
||||
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
_kernel_start = .;
|
||||
.multiboot.data : {
|
||||
*(.multiboot.data)
|
||||
}
|
||||
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
.multiboot.text : {
|
||||
*(.multiboot.text)
|
||||
}
|
||||
|
||||
. += 0xC0000000;
|
||||
/* Add a symbol that indicates the start address of the kernel. */
|
||||
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.bootstrap_stack)
|
||||
}
|
||||
/* Add a symbol that indicates the end address of the kernel. */
|
||||
_kernel_end = .;
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
menuentry "bozos" {
|
||||
set gfxmode=1024x768x32
|
||||
set gfxpayload=keep
|
||||
menuentry "bozOS" {
|
||||
multiboot /boot/bozOS.bin
|
||||
boot
|
||||
}
|
BIN
documentation/assets/memory/heap_map.webp
Normal file
BIN
documentation/assets/memory/heap_map.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
73
documentation/installation.md
Normal file
73
documentation/installation.md
Normal file
@ -0,0 +1,73 @@
|
||||
# INSTALLATION
|
||||
|
||||
## Cross compile the compile
|
||||
|
||||
### WHY ??
|
||||
Why cross compile the gcc ?
|
||||
|
||||
We must cross compile gcc cause our kernel is developped for i386 cpu but your current cpu is probally not an i386 so we need to create an i386 compiler
|
||||
|
||||
### HOW ?
|
||||
|
||||
[THE DOCUMENTATION](https://wiki.osdev.org/GCC_Cross-Compiler)
|
||||
- install requirement follow [THE DOCUMENTATION](https://wiki.osdev.org/GCC_Cross-Compiler)
|
||||
- Setup the shell
|
||||
``` sh
|
||||
export PREFIX="$HOME/opt/cross"
|
||||
export TARGET=i386-elf
|
||||
export PATH="$PREFIX/bin:$PATH"
|
||||
mkdir $HOME/src
|
||||
cd $HOME/src
|
||||
```
|
||||
- Download [binutils](https://ftp.gnu.org/gnu/binutils/?C=M;O=D)
|
||||
- Download [gcc](https://ftp.gnu.org/gnu/gcc/?C=M;O=D)
|
||||
- Download [gdb](https://ftp.gnu.org/gnu/gdb/?C=M;O=D)
|
||||
- extract archives
|
||||
``` sh
|
||||
tar xf [your binutils archive]
|
||||
tar xf [your gcc archive]
|
||||
tar xf [your gdb archive]
|
||||
```
|
||||
- (protips use -j [nb core])
|
||||
- Compile binutils
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
mkdir build-binutils
|
||||
|
||||
cd build-binutils
|
||||
../binutils-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
|
||||
make
|
||||
make install
|
||||
```
|
||||
- Compile gdb
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
mkdir build-gdb
|
||||
|
||||
cd build-gdb
|
||||
../gdb.x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-werror
|
||||
make all-gdb
|
||||
make install-gdb
|
||||
make
|
||||
make install
|
||||
```
|
||||
- Compile gcc
|
||||
``` sh
|
||||
cd $HOME/src
|
||||
|
||||
# The $PREFIX/bin dir _must_ be in the PATH. We did that above.
|
||||
which -- $TARGET-as || echo $TARGET-as is not in the PATH
|
||||
|
||||
mkdir build-gcc
|
||||
cd build-gcc
|
||||
../gcc-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
|
||||
make all-gcc
|
||||
make all-target-libgcc
|
||||
make install-gcc
|
||||
make install-target-libgcc
|
||||
```
|
||||
|
||||
## Compile and the start the kernel
|
||||
``` sh
|
||||
make run
|
||||
```
|
10
documentation/memory.md
Normal file
10
documentation/memory.md
Normal file
@ -0,0 +1,10 @@
|
||||
# MEMOMY
|
||||
|
||||
## Pagination
|
||||
|
||||
To activate pagination you must put the physic [pd](./memory/page_directory.md) address in the cr3 register and 0x80000000 in the cr0 register. Now the [MMU](./memory/mmu.md) will translate your address
|
||||
|
||||
### Our setup
|
||||
|
||||
Cause create all [pt](./memory/page_table.md) will cost 3MB (768 * 1024 * 4, 768: cause is our heap limite, 1024: cause each pt contains 1024 entry and 4: cause size of pte is 4byte) we decided to create it on the heap and dynamically. So the first pt of the pd (pd[0]) will contain a default_page_table (or heap_pt). Each page create by each the heap_pt will be a pt added to the pd.
|
||||

|
3
documentation/memory/frame.md
Normal file
3
documentation/memory/frame.md
Normal file
@ -0,0 +1,3 @@
|
||||
# FRAME
|
||||
|
||||
Like [page](./page.md) but in physical memory space
|
19
documentation/memory/mmu.md
Normal file
19
documentation/memory/mmu.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Memory Management Unit (MMU)
|
||||
The MMU is a chip which translate virtual memory to physical memory. When you try to access to an address (/!\ only when you try to access) the MMU will get the physical address from the [pd](./page_directory.md).
|
||||
|
||||
## How translate an address ?
|
||||
The address will be divid in 3 parts:
|
||||
- Page Directory index (10bit (cause 1024))
|
||||
- Page Table index (10bit (cause 1024 too))
|
||||
- offset (12bit cause page size = 4096)
|
||||
|
||||
### Example
|
||||
|
||||
**address**: 0b000100000011101011111011101101
|
||||
|
||||
| Base | PD index | PT index | offset |
|
||||
|--------|----------|------------|--------------|
|
||||
| Binary | 00010000 | 0011101011 | 111011101101 |
|
||||
| Decimal| 16 | 235 | 3821 |
|
||||
|
||||
So to translate this address the MMU will get the 20 first bit of the value store at the 235th PTE of the 16th PDE and will replace the 20 first bit of the virtually address.
|
3
documentation/memory/page.md
Normal file
3
documentation/memory/page.md
Normal file
@ -0,0 +1,3 @@
|
||||
# PAGE
|
||||
|
||||
A page is a memory space with with a specific size (default 4096byte).
|
7
documentation/memory/page_directory.md
Normal file
7
documentation/memory/page_directory.md
Normal file
@ -0,0 +1,7 @@
|
||||
# PAGE DIRECTORY
|
||||
|
||||
The page directory (or pd) is
|
||||
|
||||
|
||||
## Indexed Size
|
||||
A PD can store 1024 PT, each PT index 1024 * 4096Byte = 4MB of address, so a PD can index 1024 * 4MB = 4GB.
|
12
documentation/memory/page_table.md
Normal file
12
documentation/memory/page_table.md
Normal file
@ -0,0 +1,12 @@
|
||||
# PAGE TABLE
|
||||
|
||||
A page table (or PT) is an 1024 array of 32bit value(Page Table Entry (or PTE)). The address of the PT is store in the [PD](./page_directory.md).
|
||||
|
||||
## Page Table Entry (PTE)
|
||||
The value is a 20 first bits of the [frame](./frame.md) address and the 12 last bit is for the flag.
|
||||
|
||||
### Not used PTE value
|
||||
To say to the [MMU](./mmu.md) the page is currently not attribued to a frame you should put the (PTE index << 12)
|
||||
|
||||
## Indexed Size
|
||||
Cause our kernel use 4096byte page and a PT can store 1024 value, each PT index 1024 * 4096Byte = 4MB of address.
|
87
headers/alloc.h
Normal file
87
headers/alloc.h
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Remove this and replace it with <assert.h> header
|
||||
// for debugging purposes
|
||||
|
||||
// BPZ = Blocks Per Zone, which is the max
|
||||
// number of blocks for a new zone
|
||||
enum { BPZ = 128, PAGES_TINY = 16, PAGES_SMALL = 64, MEM_ALIGN = 8 };
|
||||
|
||||
typedef enum { TINY, SMALL, LARGE } block_type_t;
|
||||
|
||||
/* METADATA:
|
||||
* ptr: the ptr to return with kmalloc (aligned)
|
||||
* size: the actual size
|
||||
* sub_size: the size asked by the user (different
|
||||
* from size only if krealloc and krealloc size < size)
|
||||
* in_use: bool to track block state
|
||||
* zone: the zone containing the block
|
||||
*
|
||||
* LINKED LIST:
|
||||
* next and prev will never change, it's the original block's
|
||||
* position (initialized when creating the blocks)
|
||||
* next/prev_used: linked list for the
|
||||
* in_use blocks (Block *used in struct Zone)
|
||||
* next/prev_free: linked list for the
|
||||
* available blocks (Block *free in struct Zone)
|
||||
*/
|
||||
typedef struct Block {
|
||||
void *ptr;
|
||||
size_t size;
|
||||
size_t sub_size;
|
||||
bool in_use;
|
||||
struct Zone *zone;
|
||||
|
||||
struct Block *prev;
|
||||
struct Block *next;
|
||||
struct Block *prev_used;
|
||||
struct Block *next_used;
|
||||
struct Block *prev_free;
|
||||
struct Block *next_free;
|
||||
} Block;
|
||||
|
||||
/* free is the first list, when creating the blocks
|
||||
* used is a list at the end of the free list, which contains all the blocks
|
||||
* in_use
|
||||
*/
|
||||
typedef struct Zone {
|
||||
Block *free;
|
||||
Block *used;
|
||||
size_t size;
|
||||
struct Zone *prev;
|
||||
struct Zone *next;
|
||||
block_type_t type;
|
||||
} Zone;
|
||||
|
||||
/* Linked list to store all the zones (pages) mapped.
|
||||
* The attribute type is either TINY, SMALL or LARGE.
|
||||
* For TINY and SMALL, the zone will be divided in blocks.
|
||||
* For LARGE, it will be entire page(s).
|
||||
*/
|
||||
extern Zone *vzones[3];
|
||||
extern Zone *kzones[3];
|
||||
|
||||
/*----------- UTILS ----------*/
|
||||
block_type_t get_type(size_t size);
|
||||
size_t get_zone_size(block_type_t type);
|
||||
size_t align_mem(size_t addr);
|
||||
/*----------------------------*/
|
||||
|
||||
/*-------- ALLOCATOR ---------*/
|
||||
int new_vzone(block_type_t type, size_t size);
|
||||
int new_kzone(block_type_t type, size_t size);
|
||||
/*----------------------------*/
|
||||
|
||||
void *vmalloc(size_t size);
|
||||
void vfree(void *ptr);
|
||||
void *vrealloc(void *ptr, size_t size);
|
||||
void show_valloc_mem(void);
|
||||
size_t vsize(void *virt_addr);
|
||||
void *kmalloc(size_t size);
|
||||
void kfree(void *ptr);
|
||||
void *krealloc(void *ptr, size_t size);
|
||||
void show_kalloc_mem(void);
|
||||
size_t ksize(void *phys_addr);
|
16
headers/apic.h
Normal file
16
headers/apic.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// MSR
|
||||
bool cpu_has_msr();
|
||||
void cpu_set_msr(uint32_t msr, uint32_t lo, uint32_t hi);
|
||||
void cpu_get_msr(uint32_t msr, uint32_t *lo, uint32_t *hi);
|
||||
|
||||
// 8259 PIC
|
||||
void pic_disable(void);
|
||||
void pic_remap(int offset_master, int offset_slave);
|
||||
|
||||
// APIC
|
||||
void enable_apic(void);
|
6
headers/base.h
Normal file
6
headers/base.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define BASE_BIN "01"
|
||||
#define BASE_OCTA BASE_BIN "234567"
|
||||
#define BASE_DECA BASE_OCTA "89"
|
||||
#define BASE_HEXA BASE_DECA "abcdef"
|
13
headers/commands.h
Normal file
13
headers/commands.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
void halt_cmd(char *arg);
|
||||
void color_cmd(char *arg);
|
||||
void date_cmd(char *arg);
|
||||
void poweroff_cmd(char *arg);
|
||||
void stack_cmd(char *arg);
|
||||
void help_cmd(char *arg);
|
||||
void reboot_cmd(char *arg);
|
||||
void heap_cmd(char *arg);
|
||||
void clear_cmd(char *arg);
|
||||
void merdella_cmd(char *arg);
|
||||
void layout_cmd(char *arg);
|
66
headers/cpuid.h
Normal file
66
headers/cpuid.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
enum {
|
||||
CPUID_FEAT_ECX_SSE3 = 1 << 0,
|
||||
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
|
||||
CPUID_FEAT_ECX_DTES64 = 1 << 2,
|
||||
CPUID_FEAT_ECX_MONITOR = 1 << 3,
|
||||
CPUID_FEAT_ECX_DS_CPL = 1 << 4,
|
||||
CPUID_FEAT_ECX_VMX = 1 << 5,
|
||||
CPUID_FEAT_ECX_SMX = 1 << 6,
|
||||
CPUID_FEAT_ECX_EST = 1 << 7,
|
||||
CPUID_FEAT_ECX_TM2 = 1 << 8,
|
||||
CPUID_FEAT_ECX_SSSE3 = 1 << 9,
|
||||
CPUID_FEAT_ECX_CID = 1 << 10,
|
||||
CPUID_FEAT_ECX_SDBG = 1 << 11,
|
||||
CPUID_FEAT_ECX_FMA = 1 << 12,
|
||||
CPUID_FEAT_ECX_CX16 = 1 << 13,
|
||||
CPUID_FEAT_ECX_XTPR = 1 << 14,
|
||||
CPUID_FEAT_ECX_PDCM = 1 << 15,
|
||||
CPUID_FEAT_ECX_PCID = 1 << 17,
|
||||
CPUID_FEAT_ECX_DCA = 1 << 18,
|
||||
CPUID_FEAT_ECX_SSE4_1 = 1 << 19,
|
||||
CPUID_FEAT_ECX_SSE4_2 = 1 << 20,
|
||||
CPUID_FEAT_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEAT_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEAT_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEAT_ECX_TSC = 1 << 24,
|
||||
CPUID_FEAT_ECX_AES = 1 << 25,
|
||||
CPUID_FEAT_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEAT_ECX_OSXSAVE = 1 << 27,
|
||||
CPUID_FEAT_ECX_AVX = 1 << 28,
|
||||
CPUID_FEAT_ECX_F16C = 1 << 29,
|
||||
CPUID_FEAT_ECX_RDRAND = 1 << 30,
|
||||
CPUID_FEAT_ECX_HYPERVISOR = 1 << 31,
|
||||
|
||||
CPUID_FEAT_EDX_FPU = 1 << 0,
|
||||
CPUID_FEAT_EDX_VME = 1 << 1,
|
||||
CPUID_FEAT_EDX_DE = 1 << 2,
|
||||
CPUID_FEAT_EDX_PSE = 1 << 3,
|
||||
CPUID_FEAT_EDX_TSC = 1 << 4,
|
||||
CPUID_FEAT_EDX_MSR = 1 << 5,
|
||||
CPUID_FEAT_EDX_PAE = 1 << 6,
|
||||
CPUID_FEAT_EDX_MCE = 1 << 7,
|
||||
CPUID_FEAT_EDX_CX8 = 1 << 8,
|
||||
CPUID_FEAT_EDX_APIC = 1 << 9,
|
||||
CPUID_FEAT_EDX_SEP = 1 << 11,
|
||||
CPUID_FEAT_EDX_MTRR = 1 << 12,
|
||||
CPUID_FEAT_EDX_PGE = 1 << 13,
|
||||
CPUID_FEAT_EDX_MCA = 1 << 14,
|
||||
CPUID_FEAT_EDX_CMOV = 1 << 15,
|
||||
CPUID_FEAT_EDX_PAT = 1 << 16,
|
||||
CPUID_FEAT_EDX_PSE36 = 1 << 17,
|
||||
CPUID_FEAT_EDX_PSN = 1 << 18,
|
||||
CPUID_FEAT_EDX_CLFLUSH = 1 << 19,
|
||||
CPUID_FEAT_EDX_DS = 1 << 21,
|
||||
CPUID_FEAT_EDX_ACPI = 1 << 22,
|
||||
CPUID_FEAT_EDX_MMX = 1 << 23,
|
||||
CPUID_FEAT_EDX_FXSR = 1 << 24,
|
||||
CPUID_FEAT_EDX_SSE = 1 << 25,
|
||||
CPUID_FEAT_EDX_SSE2 = 1 << 26,
|
||||
CPUID_FEAT_EDX_SS = 1 << 27,
|
||||
CPUID_FEAT_EDX_HTT = 1 << 28,
|
||||
CPUID_FEAT_EDX_TM = 1 << 29,
|
||||
CPUID_FEAT_EDX_IA64 = 1 << 30,
|
||||
CPUID_FEAT_EDX_PBE = 1 << 31
|
||||
};
|
@ -1,8 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRINT_PTR(X) kprintf("%s:%u %s: %p\n", __FILE__, __LINE__, #X, X)
|
||||
#define PRINT_STR(X) kprintf("%s:%u %s: %s\n", __FILE__, __LINE__, #X, X)
|
||||
#define PRINT_UINT(X) kprintf("%s:%u %s: %u\n", __FILE__, __LINE__, #X, X)
|
||||
#define PRINT_INT(X) kprintf("%s:%u %s: %d\n", __FILE__, __LINE__, #X, X)
|
||||
#define assert(X) \
|
||||
do { \
|
||||
if (!(X)) { \
|
||||
kpanic("ASSERT_FAIL %s:%u %s\n", __FILE__, __LINE__, \
|
||||
#X); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct function_entry {
|
||||
uint32_t addr;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct stackframe {
|
||||
struct stackframe *ebp;
|
||||
uint32_t eip;
|
||||
};
|
||||
|
||||
void print_stack(void);
|
||||
|
9
headers/drivers.h
Normal file
9
headers/drivers.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "interrupts.h"
|
||||
#define NEWLINE 0
|
||||
#define READING 1
|
||||
|
||||
void load_drivers(void);
|
||||
void keyboard_handler(struct registers *regs);
|
||||
void clock_init(struct registers *regs);
|
10
headers/font.h
Normal file
10
headers/font.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct font {
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
uint32_t yoffset;
|
||||
char *bitmap;
|
||||
};
|
878
headers/fonts/consolas_regular_13.h
Normal file
878
headers/fonts/consolas_regular_13.h
Normal file
@ -0,0 +1,878 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
struct font consolas_regular_13_font[] = {
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.yoffset = 12,
|
||||
.bitmap = " ",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "## ## ## ## ## ## ## ## ## ## #########",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 5,
|
||||
.yoffset = 0,
|
||||
.bitmap = "##############################",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
" ## ## ## ## ## ## #################### ## ## ## "
|
||||
"## #################### ## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 15,
|
||||
.yoffset = 0,
|
||||
.bitmap =
|
||||
" ### ## ##### ###### ## ## ## ## ##### ###### "
|
||||
" ##### ### ## ### ######### ###### ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ### ## ##### ### ## ## ## ## ## ## ######## ### "
|
||||
"## ## ###### ####### ## ## ## ### ## "
|
||||
"## ## ##### ## ### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = " #### ###### ## ## ## ## ###### "
|
||||
"#### #### ## ###### ## ## ##### ## #### ## "
|
||||
"#### ######## #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 5,
|
||||
.yoffset = 0,
|
||||
.bitmap = "###############",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = " # ### ## ## ## ## ## ## ## ## ## ## "
|
||||
" ## ## ### # ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = " # ### ## ## ## ## ## ## ## ## ## ## "
|
||||
" ## ## ### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 8,
|
||||
.yoffset = 0,
|
||||
.bitmap =
|
||||
" ## # ## # ######## ###### ###### ######## # ## # ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 8,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
" ## ## ## ################ ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 6,
|
||||
.yoffset = 10,
|
||||
.bitmap = " ### #### ### ####### ### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 2,
|
||||
.yoffset = 7,
|
||||
.bitmap = "############",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 3,
|
||||
.yoffset = 10,
|
||||
.bitmap = " ## ########",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 15,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ## ## ### ## ### ## "
|
||||
"### ## ## ### ## ### ## "
|
||||
"### ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### ## ## ## ##### ###### ########## "
|
||||
"###### ##### ## ## ## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " ## #### ##### ## ## ## ## ## "
|
||||
"## ## ## ################",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### # ## ## ## ### ## "
|
||||
"### ### ### ################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "##### ####### ## ## ## ##### ##### ## "
|
||||
" ## ######## ##### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
" ### ### #### ##### ## ## ### ## ### "
|
||||
"## ## ## #################### ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "###### ###### ## ## ##### ###### ## ## "
|
||||
" ## ######### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ##### ## ## ###### ####### ## #### "
|
||||
" #### ##### ### ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ### ## ### ## ### "
|
||||
"## ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ######### #### ##### ### ###### ###### ### "
|
||||
" ##### #### ######### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### ### ##### #### #### ## ####### "
|
||||
"###### ## ## ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = "######### #########",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 12,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
" ### ### ### ### #### ### ####### ### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 10,
|
||||
.yoffset = 3,
|
||||
.bitmap = " # ### ### #### #### #### #### ### "
|
||||
"### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 5,
|
||||
.yoffset = 6,
|
||||
.bitmap = "################ ################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 10,
|
||||
.yoffset = 3,
|
||||
.bitmap = " # ### ### #### #### #### #### ### ### "
|
||||
" # ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "### ##### ### ## ## ##### #### ## ## ## "
|
||||
" ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap =
|
||||
" #### ####### ## ## ## ## ## ##################### "
|
||||
"######## ######## ######## ############## ## ###### ## "
|
||||
"## ## ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " ### #### #### ###### ## ## "
|
||||
" ## ## ### ### ######## ######## ### ### "
|
||||
" ## ## ### ###",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "###### ########## #### #### ########## ####### ## "
|
||||
" #### #### ######### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### ## ### ## ## ## ## "
|
||||
" ## ## # ####### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "##### ####### ## ## ## #### #### #### #### "
|
||||
" #### ##### ## ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ## ## ################ ## "
|
||||
" ## ##############",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ## ## ################ ## "
|
||||
" ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### ## #### ## ## ###### ###### "
|
||||
" #### ## ## ## ####### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "## #### #### #### #### #################### "
|
||||
" #### #### #### #### ##",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ## ## ## ## ## "
|
||||
"## ## ## ################",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "############ ## ## ## ## ## ## ### "
|
||||
"####### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
"## ### ## ### ## ### ## ### ##### #### #### "
|
||||
" ##### ## ### ## ### ## ### ## ### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "## ## ## ## ## ## ## ## ## "
|
||||
" ## ##############",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "### ####### ######## ######## "
|
||||
"############################## ###### ## ###### ###### "
|
||||
" ###### ###### ###",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "### ##### ###### ###### ###### #### ## #### ## #### "
|
||||
"###### ###### ###### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
" #### ######## ## ## ### #### #### #### "
|
||||
" #### #### ### ## ## ######## #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "###### ####### ## ##### #### #### ########## "
|
||||
"###### ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 15,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ####### ## ## ## #### #### #### "
|
||||
" #### #### ## ## ## ####### ##### ## # "
|
||||
" ##### ### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "##### ####### ## ## ## ## ## ## ###### ##### ## "
|
||||
"### ## ### ## ### ## ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " #### ###### ## # ## ### ##### ##### "
|
||||
" ### #### ######### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ## ## ## ## ## "
|
||||
"## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "## #### #### #### #### #### #### #### "
|
||||
" #### #### ### ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "### ### ### ## ### ### ## ## ### ### "
|
||||
" ### ### ## ## ###### ###### #### "
|
||||
" #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
" ## # ## ## ## ## ## ## ## ## ## ## ## ## "
|
||||
"######## ######## ######## ######## ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
"### ### ## ## ### ### ###### #### #### "
|
||||
"#### #### ###### ### ### ### ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
"## ##### ### ## ## ## ## ###### #### "
|
||||
"#### ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = "################ ## ### ## ### ### "
|
||||
"### ### ## ################",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = "############ ## ## ## ## ## ## ## ## ## "
|
||||
"## ## ##########",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 15,
|
||||
.yoffset = 0,
|
||||
.bitmap = "## ### ## ### ## ### ## "
|
||||
" ## ### ## ### ## ### "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = "########## ## ## ## ## ## ## ## ## ## "
|
||||
"## ## ############",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 6,
|
||||
.yoffset = 1,
|
||||
.bitmap =
|
||||
" ## #### ###### ## ## ## ## ### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 2,
|
||||
.yoffset = 14,
|
||||
.bitmap = "####################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 5,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ### ### ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
" #### ###### # ## ############## #### ########## ######",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "## ## ## ## ###### ####### ### #### "
|
||||
" #### #### #### ########## ##### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
" #### ######### ### ## ## ### # ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ## ## ## ## ###### ########## #### "
|
||||
" #### #### #### ### ####### ### ##",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = " #### ###### ### #################### ### "
|
||||
"####### ######",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap =
|
||||
" #### ##### ## ## ## ####### ####### "
|
||||
"## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 4,
|
||||
.bitmap = " ################ ## ## ## ####### ###### ## "
|
||||
"####### ########## ########## ##### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "## ## ## ## ###### ########## #### #### "
|
||||
" #### #### #### #### ##",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ### ### ### ##### ##### ## "
|
||||
"## ## ## ## ################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ### ### ### ############## ## ## "
|
||||
" ## ## ## ## ### ######## #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "## ## ## ## ## ### ## ### ##### "
|
||||
" #### #### ##### ## ### ## ### ## ### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.yoffset = 0,
|
||||
.bitmap = "##### ##### ## ## ## ## ## "
|
||||
"## ## ## ## ################",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = "#### ## ################## ## #### ## #### ## #### ## #### "
|
||||
"## #### ## ##",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
"###### ########## #### #### #### #### #### #### ##",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = " #### ###### ### ##### #### #### ##### ### "
|
||||
"###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 4,
|
||||
.bitmap = "###### ####### ### #### #### #### #### "
|
||||
"########## ###### ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.yoffset = 4,
|
||||
.bitmap = " ###### ########## #### #### #### #### ### "
|
||||
"####### ###### ## ## ##",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
"###### ########## #### #### ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
" ##### ###### ## #### ##### #### ############### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 12,
|
||||
.yoffset = 1,
|
||||
.bitmap = " # ## ## ################## ## ## "
|
||||
" ## ## ## ###### #####",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
"## #### #### #### #### #### #### ########## ######",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = "### ### ## ## ### ### ## ## ## ## ###### "
|
||||
" #### #### ## ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = "### ### ## ## ## ## ## ## ## ## ######## ######## "
|
||||
" ######## ### #### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap = " ### ### ### ### ### ### ##### #### "
|
||||
"#### ###### ###### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
"### ### ### ## ### ### ## ## ###### ##### "
|
||||
"#### ### ## ### ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.yoffset = 4,
|
||||
.bitmap =
|
||||
"############## ## ## ### ## ### ##############",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = " ### #### ## ## ## ## ## ### "
|
||||
"#### ## ## ## ## ## ##### ####",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 18,
|
||||
.yoffset = -2,
|
||||
.bitmap = "####################################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 16,
|
||||
.yoffset = 0,
|
||||
.bitmap = "### #### ## ## ## ## ## ### "
|
||||
"#### ## ## ## ## ## ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 4,
|
||||
.yoffset = 6,
|
||||
.bitmap = " ### ######## #### ######## #### ",
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.yoffset = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
};
|
770
headers/fonts/eating_pasta_regular_13.h
Normal file
770
headers/fonts/eating_pasta_regular_13.h
Normal file
@ -0,0 +1,770 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
struct font eating_pasta_regular_13_font[] = {
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.bitmap = " ",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 13,
|
||||
.bitmap = "####### ### ### ### ### ### ### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 5,
|
||||
.bitmap = " ## ##### ##### ## ## ## # ",
|
||||
},
|
||||
{
|
||||
.width = 13,
|
||||
.height = 12,
|
||||
.bitmap = " ### ### #### #### #### #### "
|
||||
"############ ############ #### #### ############ "
|
||||
"############ ### ### ### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 15,
|
||||
.bitmap = " # #### ###### ####### #### #### #### "
|
||||
" ####### ###### # ### # ### ######## ####### "
|
||||
"####### # ",
|
||||
},
|
||||
{
|
||||
.width = 16,
|
||||
.height = 13,
|
||||
.bitmap = " #### ### ##### #### ### ## ### ### ## #### "
|
||||
" ##### ### ### #### #### ### ###### "
|
||||
"### ## ## #### ## ## ### ## ### #### ##### "
|
||||
" #### #### ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### ### ## ### ### ###### "
|
||||
"##### ### #### ### ######## ######## ### #### "
|
||||
"######### ##### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 5,
|
||||
.bitmap = " ######## ## # ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 15,
|
||||
.bitmap = " # ### #### ### #### ### ### ### ### ### ### ### "
|
||||
"#### #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 16,
|
||||
.bitmap = " ## #### ### #### ### ### #### #### #### "
|
||||
"#### ### ### #### #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 6,
|
||||
.bitmap = " # # # # ##### ##### ##### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 9,
|
||||
.bitmap = " ### ### ### ######################## ### "
|
||||
"### ## ",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 5,
|
||||
.bitmap = " ## ### ### ### ## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 3,
|
||||
.bitmap = "########################",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 4,
|
||||
.bitmap = " ## ####### ###",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 14,
|
||||
.bitmap = " ### ### ### ### ### ### ### ### "
|
||||
"#### ### ### #### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### ######## ### ### ### ### ## ### ## "
|
||||
"## ### ## ### ### ### ### ######## ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 13,
|
||||
.bitmap = " ### #### ################# ### ### ### ### "
|
||||
"### ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ###### ######## ### #### ### #### "
|
||||
"### #### #### #### ####### ##################",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " #### ####### ######## # ### ## #### "
|
||||
" #### # ### ### ## ### ######## ######## "
|
||||
" ##### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" #### ##### ##### ###### ### ### ####### ### "
|
||||
"#### ############################# # #### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 14,
|
||||
.bitmap = " ##### ####### ####### ### ### ###### ####### "
|
||||
"######## #### #### ########### ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ### #### ###### ######## ### "
|
||||
"####### ### ### ### ### ### ######## ###### ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 13,
|
||||
.bitmap = "############## ###### ### #### ### ### #### "
|
||||
"### ### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " ##### ####### ######## ### ### ### ## ####### "
|
||||
" ###### ######## ### ## ### #### ######## ######## "
|
||||
" ###### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" #### ####### ######## ## ###### ###### ### ######## "
|
||||
"######## ###### ### #### #### ## ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 10,
|
||||
.bitmap = " ### #### #### ### ## ### #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 12,
|
||||
.bitmap =
|
||||
" # ### #### ### ## ## ### ### ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.bitmap =
|
||||
" # ### #### ##### ### ###### ##### ### ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 7,
|
||||
.bitmap = " #### ###### ###### ###### ###### ######",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 9,
|
||||
.bitmap =
|
||||
" # ### #### ##### ### ###### ##### ### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### ###### ### ###### ## ### ##### "
|
||||
"#### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 14,
|
||||
.height = 14,
|
||||
.bitmap = " ###### ######## ########## #### ### "
|
||||
"### ######### ######### ### ## ### # #### ## ### ##### "
|
||||
"############ ### ### ### #### ######### "
|
||||
"######## ####### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 12,
|
||||
.bitmap = " ##### ##### ###### ## ### ### ### "
|
||||
"### ### ### ## ######### ######### ### ### ### "
|
||||
"####### ####",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 12,
|
||||
.bitmap = "####### ######## ### ####### ############ ####### "
|
||||
"######## ### ### ### #################### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### #### ### ### ### ### #### #### "
|
||||
" #### ### ## ### ### ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 12,
|
||||
.bitmap = "##### ####### ####### ### #### ## ### ### ## ### "
|
||||
"###### ####### #### ####### ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"######## ######## ######## ### ### #### ####### "
|
||||
"###### ### ### ######## ######## ######## ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.bitmap = "########################### ### ####### ####### "
|
||||
"####### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ###### ######## ### ### ### #### #### "
|
||||
" #### #### ### #### ### ## ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "### ###### ###### ###### ###### "
|
||||
"##################################### ####### ####### "
|
||||
"####### ####### ####",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 12,
|
||||
.bitmap = "####################################",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ### ### ### "
|
||||
"###### ###### ######## ### ######## ####### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "### ### ### ### ### ### ### ### #### ####### "
|
||||
"###### ###### ####### ### #### ### #### ### ### "
|
||||
"### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ### ### ### ### "
|
||||
"### ### ### ####### ####### #######",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## #### #### ##### #### ##### ##### ##### "
|
||||
"##### ########### ########### ### ### ### ### ### ### ### "
|
||||
"# ### ### ### ### ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "#### ####### ######## ######## ######## ######### "
|
||||
"###### ## ###### ######### ######### ######## ######## "
|
||||
"####### ####",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ##### ####### ######### ### #### ### ###### ###### "
|
||||
" ###### ### ### ### ### #### ######## ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = "### ###### ####### ### ###### ###### ###### "
|
||||
"########### ###### #### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 15,
|
||||
.bitmap = " ##### ####### ######### ### #### ### ###### "
|
||||
"###### ###### ####### ##### ### ##### ######## "
|
||||
"####### ####### ## # ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = "### ###### ####### ### ### ### ### ### ### ### "
|
||||
"#### ####### ###### ###### ### ### ### ####### # ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ##### ###### ####### #### #### #### ####### "
|
||||
" ##### #### ### ######## ####### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.bitmap = "################ ### ### ### ### ### "
|
||||
"### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ### ### ### ### ### ### ## ### ## ### ## ### ### "
|
||||
" ### ### ### ### ### ### ### ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"### ###### ### ### #### ### ### ### ### ### ### ### "
|
||||
"### ###### ###### ###### ###### ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 14,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"### #### ###### #### ####### #### ### ### #### ### ### "
|
||||
"##### ### ############ ############ ###### ##### ##### ##### "
|
||||
"##### ##### #### #### #### #### #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " ### ## #### #### ######## ###### ###### #### "
|
||||
" #### ##### ###### ####### ### #### #### ### "
|
||||
"### ####",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "#### ####### ### #### #### #### ### ####### "
|
||||
"##### #### ### ### ### ### "
|
||||
" ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = " ####### ####### ## #### ### ### ### ### "
|
||||
"### ### ### ###### ################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 16,
|
||||
.bitmap = " ####################### ### ### ### ### ### "
|
||||
" ### ### ### #### ############## ######",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 14,
|
||||
.bitmap = "### ### #### ### ### #### ### ### "
|
||||
"#### ### ### ### #### ###",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 16,
|
||||
.bitmap = "###### ############## #### ### ### ### ### "
|
||||
"### ### ### ### ################# ###### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 7,
|
||||
.bitmap = " ### #### #### ##### ###### ## ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 3,
|
||||
.bitmap = "###########################",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 3,
|
||||
.bitmap = " ## ### # ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 12,
|
||||
.bitmap = " #### ##### ###### ## ### ### ### "
|
||||
"### ### ### ### ######### ######### ### ### #### "
|
||||
"####### ###",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 12,
|
||||
.bitmap = "###### ######## ### ####### ############ ####### "
|
||||
"######## ### ### ### #################### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### #### ### ### ### ### #### #### "
|
||||
" #### #### ## ### ### ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 12,
|
||||
.bitmap =
|
||||
" ##### ###### ####### ## #### ## ### ## ## ## "
|
||||
" ### ### ### ### #### ####### ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ######## ######## ######## ### ### #### ###### "
|
||||
"###### ### ### ######## ######## ########",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.bitmap = "####################### ### ### ####### ####### "
|
||||
"####### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ###### ######## ### ### ### #### #### "
|
||||
" #### ######## #### ### ### ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "### ###### ###### ####### ####### "
|
||||
"##################################### ####### ####### "
|
||||
"####### ####### ####",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 12,
|
||||
.bitmap = "####################################",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ### ### ### "
|
||||
"###### ###### ######## ############ ####### #### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ### ### ### ### ### #### "
|
||||
"####### ###### ###### ####### ### #### ### "
|
||||
"#### ### #### ### # ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ### ### ### ### "
|
||||
"### ### ### ####### ####### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## #### #### ##### #### ##### ##### ##### "
|
||||
"##### ########### ########### ### ### ### ### ### ### ### "
|
||||
"# ### ### ### ### ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "#### ####### ####### ######## ######## ######### "
|
||||
"###### ## ## ### ##### ### ##### ### #### ### #### ### "
|
||||
"### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ##### ####### ######### ### #### ### ###### ###### "
|
||||
" ###### ####### ### ### #### ######## ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ###### ####### ### ### ### ### ### ### ### "
|
||||
"#### ####### ###### #### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 15,
|
||||
.bitmap = " ##### ####### ######### ### #### ### ###### "
|
||||
"###### ###### ####### ##### ### ##### ######## "
|
||||
"####### ####### ### # ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ### ###### ####### ### ### ### ### ### ### ### "
|
||||
"#### ####### ###### ###### ### ### ### #### ### # ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ##### ###### ####### #### #### #### ####### "
|
||||
" ##### #### ### ######## ####### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 12,
|
||||
.bitmap = "################ ### ### ### ### ### "
|
||||
"### ### ### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ### ### ### ### ## ###### ###### ###### ### ## "
|
||||
" ### ### ### ### ### ### ### ######## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"### ####### ### ### #### ### ### ### ### ### ### ### "
|
||||
"### ###### ###### ###### ###### ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 14,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"### #### ###### #### ###### #### ### ### #### ### ### "
|
||||
"######### ############ ############ ##### ##### ##### ##### "
|
||||
"##### ##### #### #### #### #### #### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " ### ## #### #### ######## ###### ###### #### "
|
||||
" #### ##### ###### ####### ### #### #### ### "
|
||||
"### ####",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "#### ####### ### #### #### ### ### ####### "
|
||||
"##### ##### ### ### ### ### "
|
||||
" ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 8,
|
||||
.height = 13,
|
||||
.bitmap = " ####### ####### ## #### ### ### ### ### "
|
||||
"### ### ### ###### ################",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 17,
|
||||
.bitmap = " # ### #### #### ### ### ### ### #### ### "
|
||||
" #### #### #### #### #### #### # ",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 17,
|
||||
.bitmap = " ###########################################################"
|
||||
"########",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 17,
|
||||
.bitmap = " ## ### ##### #### ### ### ### #### ### "
|
||||
"#### ### ### ### #### ##### ### ## ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 5,
|
||||
.bitmap = " ## #### # ########## ######### #### ",
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
};
|
1731
headers/fonts/eating_pasta_regular_32.h
Normal file
1731
headers/fonts/eating_pasta_regular_32.h
Normal file
File diff suppressed because it is too large
Load Diff
765
headers/fonts/minecraft_medium_13.h
Normal file
765
headers/fonts/minecraft_medium_13.h
Normal file
@ -0,0 +1,765 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
struct font minecraft_medium_13_font[] = {
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
{
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.bitmap = " ",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 13,
|
||||
.bitmap = "#################### ####",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 7,
|
||||
.bitmap =
|
||||
" ## ### ## ### ## ### ## ############## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = " ## ### ## ### ## ### "
|
||||
"################################# ## ### ## ### "
|
||||
"###################### ## ### ## ### ## ### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 15,
|
||||
.bitmap = " ## ## ####### ################## ## "
|
||||
" ## ## ## ## ################## "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 13,
|
||||
.height = 13,
|
||||
.bitmap = " ## # # # # # # # # # ## # # "
|
||||
"## # # ## ## ## # ## # # # "
|
||||
" # # # # # # # # # # ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## ## ### ## ### ######### "
|
||||
"#### ### #### ##### ### ## ### ## ### ## "
|
||||
"### #### ### #### ###",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 5,
|
||||
.bitmap = "##########",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 13,
|
||||
.bitmap = " #### ###### ## ## ## ## ## ## ## "
|
||||
"## #### ####",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 13,
|
||||
.bitmap = "#### #### ## ## ## ## ## ## ## "
|
||||
"## ###### #### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 7,
|
||||
.bitmap = "## #### ## #### #### ######## #### ##",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 9,
|
||||
.bitmap = " ## ## ## ## ################## ## "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 4,
|
||||
.bitmap = "#### ## ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 2,
|
||||
.bitmap = "##########",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 2,
|
||||
.bitmap = "####",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## # # # # # "
|
||||
" # # # # # # ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ## ##### ###### ###### ###### ## "
|
||||
"##### ## ###### ###### ##### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## #### #### #### ## ## ## ## ## "
|
||||
" ## ############",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ## ##### ##### ##### ## "
|
||||
"## ## ## ## ## ##################",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ## ##### ##### ### ### "
|
||||
"## ## ##### ##### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ### ### ##### ##### ####### ## ### ## "
|
||||
"### ## ### ## ### #################### ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "######### ######### ## ## ## ## "
|
||||
" ## ####### ####### # #### "
|
||||
"### ######## ######## ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" ##### ##### ## ## #### ## ## "
|
||||
" ####### ####### ## ##### ### ##### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = "#################### ##### ##### ##### ## "
|
||||
"## ## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
" #### #### ## ##### ##### ##### ### #### "
|
||||
"#### ## ##### ##### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ## ##### ##### ##### ##### "
|
||||
"### ####### ####### ### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 10,
|
||||
.bitmap = "###### ####",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 12,
|
||||
.bitmap = "###### #### ## ",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 9,
|
||||
.bitmap = " ## ## #### ## ## ## ## ## ##",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 7,
|
||||
.bitmap =
|
||||
"########################### ##################",
|
||||
},
|
||||
{
|
||||
.width = 6,
|
||||
.height = 9,
|
||||
.bitmap = "## ## #### ## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " #### #### ## ##### ##### ### ### "
|
||||
"## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 15,
|
||||
.height = 16,
|
||||
.bitmap =
|
||||
" ########### ############# ## #### #### "
|
||||
"###### #### ###### #### ###### #### ## ## #### ## "
|
||||
"## #### ## ## #### ## ## #### ############# ######### "
|
||||
"## ## ############# ########### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " ##### ##### ## ##### "
|
||||
"################################### ##### ##### "
|
||||
"##### ##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "######### ######### ## ##### ##### ##### "
|
||||
" ############ ######### ## ##### ##### "
|
||||
"############ ######### ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 13,
|
||||
.bitmap = " ######### ######### ## #### #### "
|
||||
"#### ## ## ## ## "
|
||||
"#### ## ######### ######### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "######### ######### ## ##### ##### ##### "
|
||||
" ##### ##### ##### ##### ##### "
|
||||
"############ ######### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "######################## ## ##### "
|
||||
"##### ##### ## ## ## ## "
|
||||
" ######################",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = "###################### ## ###### ###### "
|
||||
"###### ## ## ## ## ## "
|
||||
"## ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 13,
|
||||
.bitmap = " ########## ############ ## ## "
|
||||
"####### ####### ####### #### #### "
|
||||
" #### ## ######## ######## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ##### ##### ##### ##### "
|
||||
" ########################### ##### ##### "
|
||||
"##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 13,
|
||||
.bitmap = "######## ## ## ## ## ## ## ## ## ## ########",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## ## ## ## ## ## ## "
|
||||
" #### #### ## ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"## ## ##### ##### ## ## ## ## ## ##### "
|
||||
" ##### ## ## ## ## ## ##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"## ## ## ## ## ## ## "
|
||||
" ## ## ## ## ####################",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ####### ######### ################## "
|
||||
"## ##### ## ##### ##### ##### ##### "
|
||||
"##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ####### ####### ##### ## ##### ## ##### "
|
||||
"## ##### ####### ####### ##### ##### "
|
||||
"##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 13,
|
||||
.height = 13,
|
||||
.bitmap = " ######### ######### ## #### #### "
|
||||
" #### #### #### #### #### "
|
||||
" #### ## ######### ######### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "######### ######### ## ##### "
|
||||
"####################### ######### ## ## "
|
||||
"## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 13,
|
||||
.height = 13,
|
||||
.bitmap = " ######### ######### ## #### #### "
|
||||
" #### #### #### #### #### "
|
||||
" #### ### ## ######### ###########",
|
||||
},
|
||||
{
|
||||
.width = 13,
|
||||
.height = 13,
|
||||
.bitmap = "########## ########## ## ## ## ## "
|
||||
"############ ########## ########## ## ### ## "
|
||||
"### ## ### ## ### ## #### ##",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap = " ######## ########## ## ####### ##### "
|
||||
" ##### ### ### ### ########## "
|
||||
"####### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "###################### ## ## ## "
|
||||
"## ## ## ## ## ## "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"## ##### ##### ##### ##### ##### ##### "
|
||||
" ##### ##### ##### ##### ### ###### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ##### ##### ##### ##### "
|
||||
" ### ## ### ## ### ## ### ## ## "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ##### ##### ##### ##### "
|
||||
" ##### ##### ## ##### ## ####### ######### "
|
||||
"####### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ### ## ### ## ### ####### "
|
||||
"## ## ## ### ## ### ## ##### "
|
||||
"##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ##### ### ## ### ## ### ####### "
|
||||
"## ## ## ## ## ## "
|
||||
" ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "###################### ### ### ##### "
|
||||
" ### ### ## ## ## ## "
|
||||
" ######################",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 16,
|
||||
.bitmap =
|
||||
"########## ## ## ## ## ## ## ## ## ## ## ## ########",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = "# # # # # # # "
|
||||
" # # # # # ##",
|
||||
},
|
||||
{
|
||||
.width = 4,
|
||||
.height = 16,
|
||||
.bitmap =
|
||||
"######## ## ## ## ## ## ## ## ## ## ## ## ##########",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 7,
|
||||
.bitmap =
|
||||
" ## ## ## ## ## ## ### ##### ### ##",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 1,
|
||||
.bitmap = "##########",
|
||||
},
|
||||
{
|
||||
.width = 3,
|
||||
.height = 3,
|
||||
.bitmap = "# # #",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 10,
|
||||
.bitmap = "####### ####### ####### ### ######## "
|
||||
"########## ##### ### ######## ########",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 13,
|
||||
.bitmap = "## ## ## ## ## ##### ## "
|
||||
"##### ## ##### #### ####### ##### ##### "
|
||||
"############ ######### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 10,
|
||||
.bitmap = " ##### ##### ##### ## ##### ##### "
|
||||
"## ##### ### ##### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ### ####### ####### ######### "
|
||||
"##### ##### ##### ##### #####################",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 10,
|
||||
.bitmap = " ####### ####### ######### ################## ## "
|
||||
" ## ### ####### #######",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ##### ##### ## ########################### ## "
|
||||
" ## ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 14,
|
||||
.bitmap =
|
||||
" ####### ####### ######### ##### ### ####### ####### "
|
||||
" ### ### ##### ##### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = "## ## ## ## ## ## ## ## ## "
|
||||
"## #### ####### ##### ##### ##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 13,
|
||||
.bitmap = "#### ####################",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 13,
|
||||
.bitmap = " ## ## ## ## ## ## ## "
|
||||
" #### #### ## ### ### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = "## ## ## ##### ##### ####### ## ## "
|
||||
"## #### #### ## ## ## ## ## ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 13,
|
||||
.bitmap = "##########################",
|
||||
},
|
||||
{
|
||||
.width = 15,
|
||||
.height = 10,
|
||||
.bitmap = "###### ##### ###### ##### ###### ##### ## ### "
|
||||
"#### ### #### ### #### ### #### ### "
|
||||
"#### ### #### ### ##",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 10,
|
||||
.bitmap = "####### ####### ####### ## ##### ##### "
|
||||
"##### ##### ##### ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 10,
|
||||
.bitmap = " #### #### #### ## ##### ##### ##### "
|
||||
"##### ### #### #### ",
|
||||
},
|
||||
{
|
||||
.width = 10,
|
||||
.height = 13,
|
||||
.bitmap =
|
||||
"## ### ## ### ## ### #### ####### ##### ##### "
|
||||
" ########## ####### ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 13,
|
||||
.bitmap = " ### ### ####### ######### ###### ##### ##### "
|
||||
"##### ### ####### ####### ### ### ###",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 10,
|
||||
.bitmap = "## ### ################# ### ## ## ## ## "
|
||||
" ## ",
|
||||
},
|
||||
{
|
||||
.width = 7,
|
||||
.height = 11,
|
||||
.bitmap = " ##### ############## ## ### ### ## "
|
||||
" ####### ##### ",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 12,
|
||||
.bitmap =
|
||||
" ## ## #### #### #### ## ## ## ## ## ## ##",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 10,
|
||||
.bitmap = "## ##### ##### ##### ##### ##### ##### "
|
||||
"##### ### ####### #######",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 7,
|
||||
.bitmap = "## ##### ##### ### ## ### ## ### "
|
||||
"## ## ",
|
||||
},
|
||||
{
|
||||
.width = 12,
|
||||
.height = 9,
|
||||
.bitmap = "## #### #### #### #### ## "
|
||||
"#### ## #### ## ## ########## ##########",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 11,
|
||||
.bitmap =
|
||||
"## ##### ####### ##### ## ### ## ### ## "
|
||||
" ## ## ### ## ### ## ##### ###",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 12,
|
||||
.bitmap = "## ##### ##### ##### ##### ##### ### "
|
||||
"####### ####### ### ######### ###### ",
|
||||
},
|
||||
{
|
||||
.width = 9,
|
||||
.height = 11,
|
||||
.bitmap = "########################### ## ## ## ## "
|
||||
" ## ## ##################",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 17,
|
||||
.bitmap = " ## ## ## ## ## ## ## ## ## ## ## ## "
|
||||
" ## ## ## ## ##",
|
||||
},
|
||||
{
|
||||
.width = 2,
|
||||
.height = 17,
|
||||
.bitmap = "##################################",
|
||||
},
|
||||
{
|
||||
.width = 5,
|
||||
.height = 17,
|
||||
.bitmap = "## ## ## ## ## ## ## ## ## ## ## ## "
|
||||
" ## ## ## ## ## ",
|
||||
},
|
||||
{
|
||||
.width = 11,
|
||||
.height = 2,
|
||||
.bitmap = " ### ##### #### ",
|
||||
},
|
||||
{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.bitmap = NULL,
|
||||
},
|
||||
};
|
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "tss.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GDT_ADDRESS 0x00000800
|
||||
#define GDT_SIZE 7
|
||||
#define GDT_SIZE 8
|
||||
|
||||
// https://wiki.osdev.org/Global_Descriptor_Table#GDTR
|
||||
struct gdt_descriptor {
|
||||
@ -11,6 +12,8 @@ struct gdt_descriptor {
|
||||
uint32_t base;
|
||||
} __attribute__((packed));
|
||||
|
||||
extern struct tss TSS;
|
||||
|
||||
void init_gdt();
|
||||
|
||||
#define GDT_FLAG_64BIT_MODE 0b0010
|
||||
@ -30,3 +33,13 @@ void init_gdt();
|
||||
#define GDT_ACCESS_RW_READABLE_FOR_CODE_WRITABLE_FOR_DATA 0b00000010
|
||||
#define GDT_ACCESS_A_ACCESSED 0b00000001
|
||||
#define GDT_ACCESS_A_NOT_ACCESSED 0b00000000
|
||||
|
||||
extern uint8_t gdt_entries[GDT_SIZE * 8];
|
||||
|
||||
#define GDT_OFFSET_KERNEL_CODE 0x08
|
||||
#define GDT_OFFSET_KERNEL_DATA 0x10
|
||||
#define GDT_OFFSET_KERNEL_STACK 0x18
|
||||
#define GDT_OFFSET_USER_CODE 0x20
|
||||
#define GDT_OFFSET_USER_DATA 0x28
|
||||
#define GDT_OFFSET_USER_STACK 0x30
|
||||
#define GDT_OFFSET_TSS 0x38
|
||||
|
9
headers/icon.h
Normal file
9
headers/icon.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct icon {
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
uint32_t *pixels;
|
||||
};
|
57864
headers/icons/image.h
Normal file
57864
headers/icons/image.h
Normal file
File diff suppressed because it is too large
Load Diff
22
headers/idt.h
Normal file
22
headers/idt.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// doc : https://wiki.osdev.org/Interrupt_Descriptor_Table#IDTR
|
||||
struct idt_descriptor {
|
||||
uint16_t size;
|
||||
uint32_t offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_entry {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load
|
||||
// into CS before calling the ISR
|
||||
uint8_t reserved; // Set to zero
|
||||
uint8_t attributes; // Type and attributes; see the IDT page
|
||||
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
||||
} __attribute__((packed));
|
||||
|
||||
#define IDT_SIZE 256
|
||||
|
||||
void init_idt(void);
|
31
headers/interrupts.h
Normal file
31
headers/interrupts.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct registers {
|
||||
// data segment selector
|
||||
uint32_t ds;
|
||||
// general purpose registers pushed by pusha
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
// pushed by isr procedure
|
||||
uint32_t int_no, err_code;
|
||||
// pushed by CPU automatically
|
||||
uint32_t eip, cs, eflags, useresp, ss;
|
||||
};
|
||||
|
||||
typedef void (*isr_t)(struct registers *);
|
||||
|
||||
void isr_handler(struct registers *regs);
|
||||
void pic_send_eoi(uint8_t irq);
|
||||
void register_interrupt_handler(int index, isr_t handler);
|
||||
|
||||
static inline void cli(void)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
|
||||
// aka sti
|
||||
static inline void toris(void)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
}
|
@ -1,18 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static const char *keymap[128] = {
|
||||
[[__maybe_unused__]] static const char *azerty_keymap[128] = {
|
||||
[2] = "&1", [3] = "é2", [4] = "\"3", [5] = "'4", [6] = "(5",
|
||||
[7] = "-6", [8] = "è7", [9] = "_8", [10] = "ç9", [11] = "à0",
|
||||
[12] = ")°", [13] = "=+", [14] = NULL, [15] = NULL, [16] = "aA",
|
||||
[17] = "zZ", [18] = "eE", [19] = "rR", [20] = "tT", [21] = "yY",
|
||||
[22] = "uU", [23] = "iI", [24] = "oO", [25] = "pP", [26] = "^¨",
|
||||
[27] = "$£", [28] = "\n\n", [30] = "qQ", [31] = "sS", [32] = "dD",
|
||||
[33] = "fF", [34] = "gG", [35] = "hH", [36] = "jJ", [37] = "kK",
|
||||
[38] = "lL", [39] = "mM", [40] = "ù%", [41] = NULL, [42] = NULL,
|
||||
[43] = "*µ", [44] = "wW", [45] = "xX", [46] = "cC", [47] = "vV",
|
||||
[48] = "bB", [49] = "nN", [50] = ",?", [51] = ";.", [52] = ":/",
|
||||
[53] = "!§", [54] = NULL, [55] = NULL, [56] = NULL, [57] = " ",
|
||||
[58] = NULL, [59] = NULL, [60] = NULL, [61] = NULL, [62] = NULL,
|
||||
[63] = NULL, [64] = NULL, [65] = NULL, [66] = NULL, [67] = NULL,
|
||||
[68] = NULL, [69] = NULL, [70] = NULL, [71] = NULL, [72] = NULL,
|
||||
[73] = NULL, [74] = NULL, [75] = NULL, [76] = NULL, [77] = NULL,
|
||||
[78] = NULL, [79] = NULL, [80] = NULL, [81] = NULL, [82] = NULL,
|
||||
[83] = NULL, [84] = NULL, [85] = NULL, [86] = NULL, [87] = NULL,
|
||||
[88] = NULL, [89] = NULL, [90] = NULL, [91] = NULL, [92] = NULL,
|
||||
[93] = NULL, [94] = NULL, [95] = NULL, [96] = NULL, [97] = NULL,
|
||||
[98] = NULL, [99] = NULL, [100] = NULL, [101] = NULL, [102] = NULL,
|
||||
[103] = NULL, [104] = NULL, [105] = NULL, [106] = NULL, [107] = NULL,
|
||||
[108] = NULL, [109] = NULL, [110] = NULL, [111] = NULL, [112] = NULL,
|
||||
[113] = NULL, [114] = NULL, [115] = NULL, [116] = NULL, [117] = NULL,
|
||||
[118] = NULL, [119] = NULL, [120] = NULL, [121] = NULL, [122] = NULL,
|
||||
[123] = NULL, [124] = NULL, [125] = NULL, [126] = NULL, [127] = NULL,
|
||||
};
|
||||
|
||||
[[__maybe_unused__]] static const char *qwerty_keymap[128] = {
|
||||
[2] = "1!", [3] = "2@", [4] = "3#", [5] = "4$", [6] = "5%",
|
||||
[7] = "6^", [8] = "7&", [9] = "8*", [10] = "9(", [11] = "0)",
|
||||
[12] = "-_", [13] = "=+", [16] = "qQ", [17] = "wW", [18] = "eE",
|
||||
[19] = "rR", [20] = "tT", [21] = "yY", [22] = "uU", [23] = "iI",
|
||||
[24] = "oO", [25] = "pP", [26] = "[{", [27] = "]}", [28] = "\n\n",
|
||||
[30] = "aA", [31] = "sS", [32] = "dD", [33] = "fF", [34] = "gG",
|
||||
[35] = "hH", [36] = "jJ", [37] = "kK", [38] = "lL", [39] = ";:",
|
||||
[40] = "'\"", [43] = "\\|", [44] = "zZ", [45] = "xX", [46] = "cC",
|
||||
[47] = "vV", [48] = "bB", [49] = "nN", [50] = "mM", [51] = ",<",
|
||||
[52] = ".>", [53] = "/?", [57] = " ",
|
||||
[12] = "-_", [13] = "=+", [14] = NULL, [15] = NULL, [16] = "qQ",
|
||||
[17] = "wW", [18] = "eE", [19] = "rR", [20] = "tT", [21] = "yY",
|
||||
[22] = "uU", [23] = "iI", [24] = "oO", [25] = "pP", [26] = "[{",
|
||||
[27] = "]}", [28] = "\n\n", [30] = "aA", [31] = "sS", [32] = "dD",
|
||||
[33] = "fF", [34] = "gG", [35] = "hH", [36] = "jJ", [37] = "kK",
|
||||
[38] = "lL", [39] = ";:", [40] = "'\"", [41] = NULL, [42] = NULL,
|
||||
[43] = "\\|", [44] = "zZ", [45] = "xX", [46] = "cC", [47] = "vV",
|
||||
[48] = "bB", [49] = "nN", [50] = "mM", [51] = ",<", [52] = ".>",
|
||||
[53] = "/?", [54] = NULL, [55] = NULL, [56] = NULL, [57] = " ",
|
||||
[58] = NULL, [59] = NULL, [60] = NULL, [61] = NULL, [62] = NULL,
|
||||
[63] = NULL, [64] = NULL, [65] = NULL, [66] = NULL, [67] = NULL,
|
||||
[68] = NULL, [69] = NULL, [70] = NULL, [71] = NULL, [72] = NULL,
|
||||
[73] = NULL, [74] = NULL, [75] = NULL, [76] = NULL, [77] = NULL,
|
||||
[78] = NULL, [79] = NULL, [80] = NULL, [81] = NULL, [82] = NULL,
|
||||
[83] = NULL, [84] = NULL, [85] = NULL, [86] = NULL, [87] = NULL,
|
||||
[88] = NULL, [89] = NULL, [90] = NULL, [91] = NULL, [92] = NULL,
|
||||
[93] = NULL, [94] = NULL, [95] = NULL, [96] = NULL, [97] = NULL,
|
||||
[98] = NULL, [99] = NULL, [100] = NULL, [101] = NULL, [102] = NULL,
|
||||
[103] = NULL, [104] = NULL, [105] = NULL, [106] = NULL, [107] = NULL,
|
||||
[108] = NULL, [109] = NULL, [110] = NULL, [111] = NULL, [112] = NULL,
|
||||
[113] = NULL, [114] = NULL, [115] = NULL, [116] = NULL, [117] = NULL,
|
||||
[118] = NULL, [119] = NULL, [120] = NULL, [121] = NULL, [122] = NULL,
|
||||
[123] = NULL, [124] = NULL, [125] = NULL, [126] = NULL, [127] = NULL,
|
||||
};
|
||||
|
||||
#define KEYBOARD_PORT 0x60
|
||||
@ -103,3 +147,5 @@ struct key_event {
|
||||
uint8_t c;
|
||||
uint8_t scan_code;
|
||||
};
|
||||
|
||||
struct key_event get_key(void);
|
||||
|
3
headers/kpanic.h
Normal file
3
headers/kpanic.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
__attribute__((noreturn)) void kpanic(const char *format, ...);
|
@ -2,18 +2,15 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
enum print_level {
|
||||
KERN_EMERG,
|
||||
KERN_ALERT,
|
||||
KERN_CRIT,
|
||||
KERN_ERR,
|
||||
KERN_WARNING,
|
||||
KERN_NOTICE,
|
||||
KERN_INFO,
|
||||
KERN_DEBUG,
|
||||
KERN_DEFAULT,
|
||||
KERN_CONT
|
||||
};
|
||||
#define KERN_DEFAULT "0"
|
||||
#define KERN_EMERG "1"
|
||||
#define KERN_ALERT "2"
|
||||
#define KERN_CRIT "3"
|
||||
#define KERN_ERR "4"
|
||||
#define KERN_WARNING "5"
|
||||
#define KERN_NOTICE "6"
|
||||
#define KERN_INFO "7"
|
||||
#define KERN_DEBUG "8"
|
||||
|
||||
int kprintf(int level, const char *restrict format, ...);
|
||||
int kvprintf(int level, const char *restrict format, va_list ap);
|
||||
int kprintf(const char *restrict format, ...);
|
||||
int kvprintf(const char *restrict format, va_list *ap);
|
||||
|
66
headers/memory.h
Normal file
66
headers/memory.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "multiboot.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRESENT (1 << 0)
|
||||
#define RW (1 << 1)
|
||||
#define SUPERVISOR (0 << 2)
|
||||
#define ACCESSED (1 << 4)
|
||||
#define INIT_FLAGS (PRESENT | RW | SUPERVISOR)
|
||||
#define PAGE_SIZE 4096
|
||||
#define PT_SIZE 1024
|
||||
#define PD_SIZE 1024
|
||||
#define PAGE_MASK 0xFFFFF000
|
||||
#define HEAP_END 0xC0000000
|
||||
#define HEAP_START ((uint32_t)&_kernel_end - HEAP_END)
|
||||
#define KERNEL_START ((uint32_t)&_kernel_start)
|
||||
#define KERNEL_END ((uint32_t)&_kernel_end - HEAP_END)
|
||||
#define PT_START 256
|
||||
|
||||
#define GET_PAGE_ADDR(pd_index, pt_index) \
|
||||
((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * 4096)
|
||||
|
||||
#define GET_FRAME(frame_table, i) (frame_table[i / 8] & (1 << (i % 8)))
|
||||
#define SET_FRAME(frame_table, i, used) \
|
||||
do { \
|
||||
if (used) \
|
||||
frame_table[i / 8] |= (1 << (i % 8)); \
|
||||
else \
|
||||
frame_table[i / 8] &= ~(1 << (i % 8)); \
|
||||
} while (0)
|
||||
|
||||
struct frame_zone {
|
||||
void *addr;
|
||||
uint32_t first_free_frame;
|
||||
uint8_t *frame_table;
|
||||
uint32_t total_frames;
|
||||
uint32_t remaining_frames;
|
||||
struct frame_zone *next;
|
||||
};
|
||||
|
||||
extern uint32_t _kernel_end;
|
||||
extern uint32_t _kernel_start;
|
||||
extern uint32_t boot_page_directory;
|
||||
extern uint32_t boot_page_table1;
|
||||
extern uint32_t *kernel_pd;
|
||||
extern uint32_t *current_pd;
|
||||
extern uint32_t page_table_default[1024];
|
||||
extern uint32_t mem_size;
|
||||
extern multiboot_memory_map_t *mmap_addr;
|
||||
extern multiboot_uint32_t mmap_length;
|
||||
extern struct frame_zone *head;
|
||||
|
||||
uint32_t *virt_to_phys(uint32_t *virt_addr);
|
||||
void init_memory(multiboot_info_t *mbd, uint32_t magic);
|
||||
void *alloc_frame(void);
|
||||
int free_frame(void *frame_ptr);
|
||||
int8_t add_single_page(void *frame);
|
||||
void *alloc_pages(size_t size, void **phys_addr);
|
||||
int free_pages(void *page_ptr, size_t size);
|
||||
void init_page_table(uint32_t page_table[1024], uint16_t start);
|
||||
int16_t add_page_table(uint16_t pd_index);
|
||||
void switch_pd(uint32_t *pd, uint32_t *cr3);
|
268
headers/multiboot.h
Normal file
268
headers/multiboot.h
Normal file
@ -0,0 +1,268 @@
|
||||
/* multiboot.h - Multiboot header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
// https://imgflip.com/i/9cflls
|
||||
|
||||
#pragma once
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||
|
||||
/* Flags set in the ’flags’ member of the multiboot header. */
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
/* Flags to be set in the ’flags’ member of the multiboot info structure. */
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header {
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
multiboot_uint32_t entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
multiboot_uint32_t mode_type;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
struct multiboot_aout_symbol_table {
|
||||
multiboot_uint32_t tabsize;
|
||||
multiboot_uint32_t strsize;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t reserved;
|
||||
};
|
||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
struct multiboot_elf_section_header_table {
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t shndx;
|
||||
};
|
||||
typedef struct multiboot_elf_section_header_table
|
||||
multiboot_elf_section_header_table_t;
|
||||
|
||||
struct multiboot_info {
|
||||
/* Multiboot info version number */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
multiboot_uint32_t boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
multiboot_uint32_t mods_count;
|
||||
multiboot_uint32_t mods_addr;
|
||||
|
||||
union {
|
||||
multiboot_aout_symbol_table_t aout_sym;
|
||||
multiboot_elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
multiboot_uint32_t mmap_length;
|
||||
multiboot_uint32_t mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
multiboot_uint32_t drives_length;
|
||||
multiboot_uint32_t drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
multiboot_uint32_t config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
multiboot_uint32_t boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
multiboot_uint32_t apm_table;
|
||||
|
||||
/* Video */
|
||||
multiboot_uint32_t vbe_control_info;
|
||||
multiboot_uint32_t vbe_mode_info;
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
union {
|
||||
struct {
|
||||
multiboot_uint32_t framebuffer_palette_addr;
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
};
|
||||
struct {
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_color {
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry {
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
} __attribute__((packed));
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_mod_list {
|
||||
/* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive
|
||||
*/
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
|
||||
/* Module command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
multiboot_uint32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info {
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void init_multiboot(multiboot_info_t *mbd, uint32_t magic);
|
4
headers/power.h
Normal file
4
headers/power.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void reboot(void);
|
||||
void halt(void);
|
30
headers/rtc.h
Normal file
30
headers/rtc.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SECOND_REGISTER 0x00
|
||||
#define MINUTE_REGISTER 0x02
|
||||
#define HOUR_REGISTER 0x04
|
||||
#define DAY_OF_THE_WEEK_REGISTER 0x06
|
||||
#define DAY_OF_THE_MONTH_REGISTER 0x07
|
||||
#define MONTH_REGISTER 0x08
|
||||
#define YEAR_REGISTER 0x09
|
||||
#define CENTURY_REGISTER 0x32
|
||||
|
||||
#define REGISTER_A 0x0A
|
||||
#define REGISTER_B 0x0B
|
||||
|
||||
enum { CMOS_ADDRESS = 0x70, CMOS_DATA = 0x71 };
|
||||
|
||||
struct rtc_date {
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
|
||||
uint8_t index_of_the_day;
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint32_t year;
|
||||
};
|
||||
|
||||
struct rtc_date get_date(void);
|
@ -2,60 +2,4 @@
|
||||
|
||||
#define PROMPT "> "
|
||||
|
||||
static const char *POOP =
|
||||
" / ____/ / _ \\\n"
|
||||
" _/ ___/_ / / \\___ \\_\n"
|
||||
" / _/'-, `---._ / / \\_ \\\n"
|
||||
" / ______/(0} `, , ` , ) / / \\_ \\\n"
|
||||
" / V ; ` , ` ( / / ,'~~~~~~`, \\\n"
|
||||
" | `.____,- ' (, ` , ) / / :`,-'\"\"`. \"; "
|
||||
"|\n"
|
||||
" | `-------._); , ` `, / / \\;: )``: |\n"
|
||||
" / / ) ) ; ` ,, : / / `` : '; "
|
||||
"\\\n"
|
||||
"/ / ( (`;: ; ` ;:\\ / / ;;;, "
|
||||
"\\\n"
|
||||
"| / (: )``;:;;)`'`'`--./ / ____ _,-';;` "
|
||||
"|\n"
|
||||
"| | :` )`;)`)`' : / / ~~~~~ ~~~`--',.;;;| "
|
||||
"|\n"
|
||||
"| | `--;~~~~~ ` / /, \" \" \"` \",, \\ ;`` | "
|
||||
" |\n"
|
||||
"| | ( ; , / / ; `; ; | "
|
||||
"|\n"
|
||||
"| | (; ; ; ` / / ,` ` : | "
|
||||
"><\n"
|
||||
"| | (; / / / ` ; ; : |\n"
|
||||
"| \\ ;(_; ; : / /` ; ; ,,,\"\"\";} `; / "
|
||||
"><\n"
|
||||
"\\ \\ : `; `; ` / /,;,'''' );;`); ; / >< "
|
||||
" ><\n"
|
||||
" \\ | ;' :; ;/ / (;` :( ; , ; | "
|
||||
"><\n"
|
||||
" | | |, `;; ,/ / `)`; `(; ` `; | "
|
||||
"(`\\\n"
|
||||
" | \\ ; ;; ``: / `).:` \\;, `. / _> "
|
||||
")_\n"
|
||||
" \\ \\_ ,-' ;`;;:;` / ;;'`;; `) )/ ,-' "
|
||||
",-. `;\n"
|
||||
" \\ \\_ ~~~,-`;`;,\" / ~~~~~ ,-' ; "
|
||||
"`\"\"/ /\"\"\n"
|
||||
" \\_ \\___\"\"\"/\"\" / `\"\"/\"\" "
|
||||
"\n";
|
||||
|
||||
typedef enum {
|
||||
HELP,
|
||||
REBOOT,
|
||||
POWEROFF,
|
||||
HALT,
|
||||
STACK,
|
||||
ECHO,
|
||||
COLOR,
|
||||
MERDELLA,
|
||||
ERROR
|
||||
} CMD_TOK;
|
||||
|
||||
void reboot(void);
|
||||
void halt(void);
|
||||
void shell_init(void);
|
||||
void print_stack(void);
|
||||
|
62
headers/signal.h
Normal file
62
headers/signal.h
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SIG_DFL 0
|
||||
#define SIG_IGN -1
|
||||
|
||||
typedef enum {
|
||||
SIGABRT, // Abort signal from abort(3)
|
||||
SIGALRM, // Timer signal from alarm(2)
|
||||
SIGBUS, // Bus error (bad memory access)
|
||||
SIGCHLD, // Child stopped or terminated
|
||||
SIGCLD, // A synonym for SIGCHLD
|
||||
SIGCONT, // Continue if stopped
|
||||
SIGEMT, // Emulator trap
|
||||
SIGFPE, // Floating-point exception
|
||||
SIGHUP, // Hangup detected on controlling terminal or death of
|
||||
// controlling process
|
||||
SIGILL, // Illegal Instruction
|
||||
SIGINFO, // A synonym for SIGPWR
|
||||
SIGINT, // Interrupt from keyboard
|
||||
SIGIO, // I/O now possible (4.2BSD)
|
||||
SIGIOT, // IOT trap. A synonym for SIGABRT
|
||||
SIGKILL, // Kill signal
|
||||
SIGLOST, // File lock lost (unused)
|
||||
SIGPIPE, // Broken pipe: write to pipe with no readers; see pipe(7)
|
||||
SIGPOLL, // Pollable event (Sys V); synonym for SIGIO
|
||||
SIGPROF, // Profiling timer expired
|
||||
SIGPWR, // Power failure (System V)
|
||||
SIGQUIT, // Quit from keyboard
|
||||
SIGSEGV, // Invalid memory reference
|
||||
SIGSTKFLT, // Stack fault on coprocessor (unused)
|
||||
SIGSTOP, // Stop process
|
||||
SIGTSTP, // Stop typed at terminal
|
||||
SIGSYS, // Bad system call (SVr4); see also seccomp(2)
|
||||
SIGTERM, // Termination signal
|
||||
SIGTRAP, // Trace/breakpoint trap
|
||||
SIGTTIN, // Terminal input for background process
|
||||
SIGTTOU, // Terminal output for background process
|
||||
SIGUNUSED, // Synonymous with SIGSYS
|
||||
SIGURG, // Urgent condition on socket (4.2BSD)
|
||||
SIGUSR1, // User-defined signal 1
|
||||
SIGUSR2, // User-defined signal 2
|
||||
SIGVTALRM, // Virtual alarm clock (4.2BSD)
|
||||
SIGXCPU, // CPU time limit exceeded (4.2BSD); see setrlimit(2)
|
||||
SIGXFSZ, // File size limit exceeded (4.2BSD); see setrlimit(2)
|
||||
SIGWINCH, // Window resize signal (4.3BSD, Sun)
|
||||
SIG_INT, // Interrupt from keyboard
|
||||
LAST
|
||||
} SIGNAL_CODE;
|
||||
|
||||
typedef void (*signal_handler_t)(int);
|
||||
|
||||
void signal(SIGNAL_CODE sig_num, void *handler);
|
||||
void kill(int pid, SIGNAL_CODE sig_num);
|
||||
void exec_signal_pending(void);
|
||||
|
||||
struct signal_data {
|
||||
void *handlers[LAST];
|
||||
uint32_t pending;
|
||||
};
|
44
headers/task.h
Normal file
44
headers/task.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "list.h"
|
||||
#include "memory.h"
|
||||
#include "signal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern struct task *current_task;
|
||||
|
||||
enum status { ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED, FORKED };
|
||||
enum owner { OWNER_KERNEL, OWNER_USER };
|
||||
|
||||
#define STACK_SIZE PAGE_SIZE * 4
|
||||
|
||||
struct task {
|
||||
uint8_t *esp;
|
||||
uint8_t *esp0;
|
||||
uint32_t *cr3; // physical
|
||||
uint32_t *heap; // virtual
|
||||
uint32_t *eip;
|
||||
uint16_t pid;
|
||||
uint8_t status;
|
||||
uint8_t uid;
|
||||
struct task *daddy;
|
||||
struct task *child;
|
||||
struct signal_data signals;
|
||||
struct task *next;
|
||||
struct task *prev;
|
||||
};
|
||||
|
||||
void scheduler(void);
|
||||
void switch_to_task(struct task *next_task);
|
||||
struct task *create_task(uint8_t uid);
|
||||
int8_t create_kernel_task(void);
|
||||
void remove_task(struct task *task);
|
||||
struct task *copy_task(const struct task *task);
|
||||
void kfork(struct task *daddy);
|
||||
void zombify_task(struct task *task);
|
||||
|
||||
// utils
|
||||
void exec_fn(void (*fn)(void));
|
||||
uint16_t fork(void);
|
||||
uint16_t wait(void);
|
@ -1,24 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "font.h"
|
||||
#include "icon.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define VGA_WIDTH 80
|
||||
#define VGA_HEIGHT 25
|
||||
#define TERM_BUF ((uint16_t *)0xB8000)
|
||||
#define SCREEN_WIDTH 1024
|
||||
#define SCREEN_HEIGHT 768
|
||||
#define FONT_WIDTH 13
|
||||
#define FONT_HEIGHT 17
|
||||
#define VGA_WIDTH (SCREEN_WIDTH / FONT_WIDTH)
|
||||
#define VGA_HEIGHT (SCREEN_HEIGHT / FONT_HEIGHT)
|
||||
#define TERM_COUNT 10
|
||||
|
||||
struct screen {
|
||||
size_t row;
|
||||
size_t column;
|
||||
uint8_t color;
|
||||
uint16_t buffer[VGA_WIDTH * VGA_HEIGHT];
|
||||
uint32_t fg_color;
|
||||
uint32_t bg_color;
|
||||
uint8_t buffer[VGA_WIDTH * VGA_HEIGHT];
|
||||
uint32_t default_color;
|
||||
struct icon *background;
|
||||
struct font *font;
|
||||
char line[256];
|
||||
};
|
||||
|
||||
enum vga_color {
|
||||
typedef enum {
|
||||
VGA_COLOR_BLACK = 0,
|
||||
VGA_COLOR_BLUE = 1,
|
||||
VGA_COLOR_GREEN = 2,
|
||||
@ -33,20 +43,29 @@ enum vga_color {
|
||||
VGA_COLOR_LIGHT_CYAN = 11,
|
||||
VGA_COLOR_LIGHT_RED = 12,
|
||||
VGA_COLOR_LIGHT_MAGENTA = 13,
|
||||
VGA_COLOR_LIGHT_BROWN = 14,
|
||||
VGA_COLOR_LIGHT_YELLOW = 14,
|
||||
VGA_COLOR_WHITE = 15,
|
||||
};
|
||||
} vga_color;
|
||||
|
||||
enum cursor_direction { LEFT, RIGHT, UP, DOWN };
|
||||
|
||||
void terminal_initialize(void);
|
||||
void terminal_setcolor(uint8_t color);
|
||||
void terminal_set_bg_color(uint32_t color);
|
||||
void terminal_set_fg_color(uint32_t color);
|
||||
int terminal_putchar(char c);
|
||||
int terminal_write(const char *data, size_t size);
|
||||
int terminal_writestring(const char *data);
|
||||
int terminal_writelong(long number);
|
||||
void terminal_set_screen(int pos);
|
||||
void terminal_clear(void);
|
||||
void terminal_refresh(void);
|
||||
struct key_event terminal_getkey(void);
|
||||
void update_cursor(void);
|
||||
void move_cursor(int direction);
|
||||
struct screen *get_screen(void);
|
||||
void set_color_level(int level);
|
||||
void terminal_set_default_fg_color(uint32_t fg_color);
|
||||
void terminal_set_default_bg_color(uint32_t fg_color);
|
||||
void terminal_change_default_fg_color(uint32_t color);
|
||||
uint32_t terminal_get_default_color(void);
|
||||
uint8_t terminal_get_char(int column, int row);
|
||||
void terminal_remove_last_char(void);
|
||||
|
5
headers/time.h
Normal file
5
headers/time.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void sleep(uint64_t delay);
|
60
headers/tss.h
Normal file
60
headers/tss.h
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// _h fields are for the offset
|
||||
struct tss {
|
||||
uint16_t link;
|
||||
uint16_t link_h;
|
||||
|
||||
uint32_t esp0;
|
||||
uint16_t ss0;
|
||||
uint16_t ss0_h;
|
||||
|
||||
uint32_t esp1;
|
||||
uint16_t ss1;
|
||||
uint16_t ss1_h;
|
||||
|
||||
uint32_t esp2;
|
||||
uint16_t ss2;
|
||||
uint16_t ss2_h;
|
||||
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
|
||||
uint16_t es;
|
||||
uint16_t es_h;
|
||||
|
||||
uint16_t cs;
|
||||
uint16_t cs_h;
|
||||
|
||||
uint16_t ss;
|
||||
uint16_t ss_h;
|
||||
|
||||
uint16_t ds;
|
||||
uint16_t ds_h;
|
||||
|
||||
uint16_t fs;
|
||||
uint16_t fs_h;
|
||||
|
||||
uint16_t gs;
|
||||
uint16_t gs_h;
|
||||
|
||||
uint16_t ldt;
|
||||
uint16_t ldt_h;
|
||||
|
||||
uint16_t trap;
|
||||
uint16_t iomap;
|
||||
};
|
18
headers/vbe.h
Normal file
18
headers/vbe.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "icon.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct vbe_interface {
|
||||
uint32_t *buff;
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
uint32_t pitch;
|
||||
uint8_t bpp;
|
||||
};
|
||||
|
||||
extern struct vbe_interface display;
|
||||
|
||||
void draw_icon(uint32_t pos_x, uint32_t pos_y, struct icon *img);
|
||||
void put_pixel(uint32_t color, uint32_t x, uint32_t y);
|
@ -1,34 +1,38 @@
|
||||
SRCDIR = src
|
||||
OBJDIR = obj
|
||||
BUILDDIR = build
|
||||
SSRC := $(shell find src -name '*.s')
|
||||
CSRC := $(shell find src -name '*.c')
|
||||
OBJ := $(patsubst src/%.c,obj/%.o,$(CSRC))\
|
||||
$(patsubst src/%.s,obj/%.o,$(SSRC))
|
||||
|
||||
SRC := $(shell find $(SRCDIR) -name '*.c')
|
||||
OBJ := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRC))
|
||||
CC := i386-elf-gcc
|
||||
CFLAGS := -std=gnu99 -ffreestanding -O2 -Wall -Wextra -iquoteheaders -c
|
||||
|
||||
CC = i386-elf-gcc
|
||||
CFLAGS = -std=gnu99 -ffreestanding -O2 -Wall -Wextra -iquoteheaders -c
|
||||
|
||||
AR = ar
|
||||
ARFLAGS =
|
||||
AS := i386-elf-as
|
||||
ASFLAGS :=
|
||||
AR := ar
|
||||
ARFLAGS :=
|
||||
|
||||
NAME = libbozo.a
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||
obj/%.o: src/%.s
|
||||
mkdir -p $(dir $@)
|
||||
$(AS) $(ASFLAGS) $< -o $@
|
||||
|
||||
obj/%.o: src/%.c
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
all : $(NAME)
|
||||
|
||||
clean :
|
||||
rm -rf $(OBJDIR)
|
||||
rm -rf obj
|
||||
|
||||
fclean : clean
|
||||
rm -rf $(BUILDDIR)
|
||||
rm -rf build
|
||||
|
||||
$(NAME) : $(OBJ)
|
||||
mkdir -p $(BUILDDIR)
|
||||
$(AR) -rc $(BUILDDIR)/$(NAME) $(OBJ)
|
||||
mkdir -p build
|
||||
$(AR) -rc build/$(NAME) $(OBJ)
|
||||
|
||||
re: fclean all
|
||||
|
||||
.PHONY: clean fclean test all re
|
||||
.PHONY: clean fclean all re
|
||||
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
int isalnum(int c);
|
||||
int isalpha(int c);
|
||||
int iscntrl(int c);
|
||||
*/
|
||||
int isdigit(int c);
|
||||
int isalpha(int c);
|
||||
int isalnum(int c);
|
||||
/*
|
||||
int isgraph(int c);
|
||||
int islower(int c);
|
||||
|
6
libbozo/headers/list.h
Normal file
6
libbozo/headers/list.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct list {
|
||||
void *content;
|
||||
struct list *next;
|
||||
};
|
@ -7,6 +7,9 @@ int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
size_t strlen(const char *str);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *memset(void *str, int c, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void bzero(void *s, size_t n);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void outb(uint16_t port, uint8_t val)
|
||||
@ -25,3 +26,8 @@ static inline uint16_t inw(uint16_t port)
|
||||
__asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void io_wait(void)
|
||||
{
|
||||
outb(0x80, 0);
|
||||
}
|
||||
|
6
libbozo/headers/utils.h
Normal file
6
libbozo/headers/utils.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define CEIL(x, y) (((x) + (y) - 1) / (y))
|
||||
#define ARRAY_SIZE(ptr) (sizeof(ptr) / sizeof(ptr[0]))
|
||||
#define ROUND_CEIL(x, y) (CEIL(x, y) * y)
|
||||
#define ROUND_FLOOR(x, y) ((x / y) * y)
|
6
libbozo/src/ctype/isalnum.c
Normal file
6
libbozo/src/ctype/isalnum.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "ctype.h"
|
||||
|
||||
int isalnum(int c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c);
|
||||
}
|
4
libbozo/src/ctype/isalpha.c
Normal file
4
libbozo/src/ctype/isalpha.c
Normal file
@ -0,0 +1,4 @@
|
||||
int isalpha(int c)
|
||||
{
|
||||
return ('Z' >= c && c >= 'A') || ('z' >= c && c >= 'a');
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
int isprint(int c)
|
||||
{
|
||||
return (32 <= c && c < 127);
|
||||
return (c >= 32 && c < 127);
|
||||
}
|
6
libbozo/src/string/bzero.c
Normal file
6
libbozo/src/string/bzero.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "string.h"
|
||||
|
||||
void bzero(void *s, size_t n)
|
||||
{
|
||||
memset(s, 0, n);
|
||||
}
|
@ -8,6 +8,7 @@ int memcmp(const void *s1, const void *s2, size_t n)
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
for (i = 0; str1[i] == str2[i] && i < n - 1; i++);
|
||||
for (i = 0; str1[i] == str2[i] && i < n - 1; i++)
|
||||
;
|
||||
return str1[i] - str2[i];
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
21
libbozo/src/string/memmove.c
Normal file
21
libbozo/src/string/memmove.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stddef.h>
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
const char *cast1 = (const char *)src;
|
||||
char *cast2 = (char *)dest;
|
||||
|
||||
if (!cast1 && !cast2 && n > 0)
|
||||
return (0);
|
||||
if (&cast1[0] > &cast2[0]) {
|
||||
while (i < n) {
|
||||
cast2[i] = cast1[i];
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
while (n--)
|
||||
cast2[n] = cast1[n];
|
||||
}
|
||||
return cast2;
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
char *strchr(const char *str, int c)
|
||||
{
|
||||
char *start = (char *) str;
|
||||
char *start = (char *)str;
|
||||
|
||||
while (*start)
|
||||
{
|
||||
while (*start) {
|
||||
if (*start == c)
|
||||
return start;
|
||||
start++;
|
||||
|
12
libbozo/src/string/strcpy.c
Normal file
12
libbozo/src/string/strcpy.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stddef.h>
|
||||
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (!src)
|
||||
return NULL;
|
||||
for (; src[i]; i++)
|
||||
dest[i] = src[i];
|
||||
dest[i] = '\0';
|
||||
return dest;
|
||||
}
|
@ -4,12 +4,11 @@
|
||||
|
||||
char *strstr(const char *haystack, const char *needle)
|
||||
{
|
||||
char *start = (char *) haystack;
|
||||
char *start = (char *)haystack;
|
||||
size_t len;
|
||||
|
||||
len = strlen(needle);
|
||||
while (*start != '\0')
|
||||
{
|
||||
while (*start != '\0') {
|
||||
if (strncmp(start, needle, len) == 0)
|
||||
return start;
|
||||
start++;
|
||||
|
9
libbozo/src/types.sh
Executable file
9
libbozo/src/types.sh
Executable file
@ -0,0 +1,9 @@
|
||||
# !/bin/bash
|
||||
sed -i 's/u8/uint8_t/g' **/*.c
|
||||
sed -i 's/i8/int8_t/g' **/*.c
|
||||
sed -i 's/u16/uint16_t/g' **/*.c
|
||||
sed -i 's/i16/int16_t/g' **/*.c
|
||||
sed -i 's/u32/uint32_t/g' **/*.c
|
||||
sed -i 's/i32/int32_t/g' **/*.c
|
||||
sed -i 's/u64/uint64_t/g' **/*.c
|
||||
sed -i 's/i64/int64_t/g' **/*.c
|
199
src/boot.s
199
src/boot.s
@ -1,110 +1,133 @@
|
||||
/* Declare constants for the multiboot header. */
|
||||
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
|
||||
.set MEMINFO, 1<<1 /* provide memory map */
|
||||
.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */
|
||||
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
|
||||
# Declare constants for the multiboot header.
|
||||
.set ALIGN, 1<<0 # align loaded modules on page boundaries
|
||||
.set MEMINFO, 1<<1 # provide memory map
|
||||
.set VIDEOMODE, 1<<2 # provide memory map
|
||||
.set FLAGS, ALIGN | MEMINFO | VIDEOMODE # this is the Multiboot 'flag' field
|
||||
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
|
||||
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
|
||||
|
||||
/*
|
||||
Declare a multiboot header that marks the program as a kernel. These are magic
|
||||
values that are documented in the multiboot standard. The bootloader will
|
||||
search for this signature in the first 8 KiB of the kernel file, aligned at a
|
||||
32-bit boundary. The signature is in its own section so the header can be
|
||||
forced to be within the first 8 KiB of the kernel file.
|
||||
*/
|
||||
.section .multiboot
|
||||
# Declare a multiboot header that marks the program as a kernel.
|
||||
.section .multiboot.data, "aw"
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
.skip 20
|
||||
|
||||
/*
|
||||
The multiboot standard does not define the value of the stack pointer register
|
||||
(esp) and it is up to the kernel to provide a stack. This allocates room for a
|
||||
small stack by creating a symbol at the bottom of it, then allocating 16384
|
||||
bytes for it, and finally creating a symbol at the top. The stack grows
|
||||
downwards on x86. The stack is in its own section so it can be marked nobits,
|
||||
which means the kernel file is smaller because it does not contain an
|
||||
uninitialized stack. The stack on x86 must be 16-byte aligned according to the
|
||||
System V ABI standard and de-facto extensions. The compiler will assume the
|
||||
stack is properly aligned and failure to align the stack will result in
|
||||
undefined behavior.
|
||||
*/
|
||||
.section .bss
|
||||
.align 16
|
||||
# Video mode
|
||||
.long 0
|
||||
.long 1024
|
||||
.long 768
|
||||
.long 32
|
||||
|
||||
# Allocate the initial stack.
|
||||
.section .bootstrap_stack, "aw", @nobits
|
||||
stack_bottom:
|
||||
.skip 16384 # 16 KiB
|
||||
stack_top:
|
||||
|
||||
/*
|
||||
The linker script specifies _start as the entry point to the kernel and the
|
||||
bootloader will jump to this position once the kernel has been loaded. It
|
||||
doesn't make sense to return from this function as the bootloader is gone.
|
||||
*/
|
||||
.section .text
|
||||
# Preallocate pages used for paging. Don't hard-code addresses and assume they
|
||||
# are available, as the bootloader might have loaded its multiboot structures or
|
||||
# modules there. This lets the bootloader know it must avoid the addresses.
|
||||
.global boot_page_directory
|
||||
.global boot_page_table1
|
||||
.section .bss, "aw", @nobits
|
||||
.align 4096
|
||||
boot_page_directory:
|
||||
.skip 4096
|
||||
boot_page_table1:
|
||||
.skip 4096
|
||||
# Further page tables may be required if the kernel grows beyond 3 MiB.
|
||||
|
||||
# The kernel entry point.
|
||||
.section .multiboot.text, "a"
|
||||
.global _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
/*
|
||||
The bootloader has loaded us into 32-bit protected mode on a x86
|
||||
machine. Interrupts are disabled. Paging is disabled. The processor
|
||||
state is as defined in the multiboot standard. The kernel has full
|
||||
control of the CPU. The kernel can only make use of hardware features
|
||||
and any code it provides as part of itself. There's no printf
|
||||
function, unless the kernel provides its own <stdio.h> header and a
|
||||
printf implementation. There are no security restrictions, no
|
||||
safeguards, no debugging mechanisms, only what the kernel provides
|
||||
itself. It has absolute and complete power over the
|
||||
machine.
|
||||
*/
|
||||
# Physical address of boot_page_table1.
|
||||
# TODO: I recall seeing some assembly that used a macro to do the
|
||||
# conversions to and from physical. Maybe this should be done in this
|
||||
# code as well?
|
||||
movl $(boot_page_table1 - 0xC0000000), %edi
|
||||
# First address to map is address 0.
|
||||
# TODO: Start at the first kernel page instead. Alternatively map the first
|
||||
# 1 MiB as it can be generally useful, and there's no need to
|
||||
# specially map the VGA buffer.
|
||||
movl $0, %esi
|
||||
# Map 1023 pages. The 1024th will be the VGA text buffer.
|
||||
movl $1023, %ecx
|
||||
|
||||
/*
|
||||
To set up a stack, we set the esp register to point to the top of the
|
||||
stack (as it grows downwards on x86 systems). This is necessarily done
|
||||
in assembly as languages such as C cannot function without a stack.
|
||||
*/
|
||||
1:
|
||||
# Only map the kernel.
|
||||
cmpl $_kernel_start, %esi
|
||||
jl 2f
|
||||
cmpl $(_kernel_end - 0xC0000000), %esi
|
||||
jge 3f
|
||||
|
||||
# Map physical address as "present, writable". Note that this maps
|
||||
# .text and .rodata as writable. Mind security and map them as non-writable.
|
||||
movl %esi, %edx
|
||||
orl $0x003, %edx
|
||||
movl %edx, (%edi)
|
||||
|
||||
2:
|
||||
# Size of page is 4096 bytes.
|
||||
addl $4096, %esi
|
||||
# Size of entries in boot_page_table1 is 4 bytes.
|
||||
addl $4, %edi
|
||||
# Loop to the next entry if we haven't finished.
|
||||
loop 1b
|
||||
|
||||
3:
|
||||
# Map VGA video memory to 0xC03FF000 as "present, writable".
|
||||
movl $(0x000B8000 | 0x003), boot_page_table1 - 0xC0000000 + 1023 * 4
|
||||
|
||||
# The page table is used at both page directory entry 0 (virtually from 0x0
|
||||
# to 0x3FFFFF) (thus identity mapping the kernel) and page directory entry
|
||||
# 768 (virtually from 0xC0000000 to 0xC03FFFFF) (thus mapping it in the
|
||||
# higher half). The kernel is identity mapped because enabling paging does
|
||||
# not change the next instruction, which continues to be physical. The CPU
|
||||
# would instead page fault if there was no identity mapping.
|
||||
|
||||
# Map the page table to both virtual addresses 0x00000000 and 0xC0000000.
|
||||
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
|
||||
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
|
||||
|
||||
# Set cr3 to the address of the boot_page_directory.
|
||||
movl $(boot_page_directory - 0xC0000000), %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# Enable paging and the write-protect bit.
|
||||
movl %cr0, %ecx
|
||||
orl $0x80000000, %ecx
|
||||
movl %ecx, %cr0
|
||||
|
||||
# Jump to higher half with an absolute jump.
|
||||
lea 4f, %ecx
|
||||
jmp *%ecx
|
||||
|
||||
.section .text
|
||||
|
||||
4:
|
||||
# At this point, paging is fully set up and enabled.
|
||||
|
||||
# Unmap the identity mapping as it is now unnecessary.
|
||||
movl $0, boot_page_directory + 0
|
||||
|
||||
# Reload crc3 to force a TLB flush so the changes to take effect.
|
||||
movl %cr3, %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# Set up the stack.
|
||||
mov $stack_top, %esp
|
||||
|
||||
/*
|
||||
This is a good place to initialize crucial processor state before the
|
||||
high-level kernel is entered. It's best to minimize the early
|
||||
environment where crucial features are offline. Note that the
|
||||
processor is not fully initialized yet: Features such as floating
|
||||
point instructions and instruction set extensions are not initialized
|
||||
yet. The GDT should be loaded here. Paging should be enabled here.
|
||||
C++ features such as global constructors and exceptions will require
|
||||
runtime support to work as well.
|
||||
*/
|
||||
push %eax
|
||||
push %ebx
|
||||
|
||||
/*
|
||||
Enter the high-level kernel. The ABI requires the stack is 16-byte
|
||||
aligned at the time of the call instruction (which afterwards pushes
|
||||
the return pointer of size 4 bytes). The stack was originally 16-byte
|
||||
aligned above and we've pushed a multiple of 16 bytes to the
|
||||
stack since (pushed 0 bytes so far), so the alignment has thus been
|
||||
preserved and the call is well defined.
|
||||
*/
|
||||
# Enter the high-level kernel.
|
||||
call kernel_main
|
||||
|
||||
/*
|
||||
If the system has nothing more to do, put the computer into an
|
||||
infinite loop. To do that:
|
||||
1) Disable interrupts with cli (clear interrupt enable in eflags).
|
||||
They are already disabled by the bootloader, so this is not needed.
|
||||
Mind that you might later enable interrupts and return from
|
||||
kernel_main (which is sort of nonsensical to do).
|
||||
2) Wait for the next interrupt to arrive with hlt (halt instruction).
|
||||
Since they are disabled, this will lock up the computer.
|
||||
3) Jump to the hlt instruction if it ever wakes up due to a
|
||||
non-maskable interrupt occurring or due to system management mode.
|
||||
*/
|
||||
# Infinite loop if the system has nothing more to do.
|
||||
cli
|
||||
1: hlt
|
||||
jmp 1b
|
||||
|
||||
/*
|
||||
Set the size of the _start symbol to the current location '.' minus its start.
|
||||
This is useful when debugging or when you implement call tracing.
|
||||
*/
|
||||
.size _start, . - _start
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "debug.h"
|
||||
#include "kprintf.h"
|
||||
#include <stddef.h>
|
||||
|
||||
void print_stack(void)
|
||||
{
|
||||
@ -7,7 +8,7 @@ void print_stack(void)
|
||||
(struct stackframe *)__builtin_frame_address(0);
|
||||
|
||||
while (stack) {
|
||||
kprintf(0, "fn: %d\n", stack->eip);
|
||||
kprintf(KERN_DEBUG "fn: %p\n", stack->eip);
|
||||
stack = stack->ebp;
|
||||
}
|
||||
}
|
||||
|
52
src/drivers/clock.c
Normal file
52
src/drivers/clock.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "drivers.h"
|
||||
#include "interrupts.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "sys/io.h"
|
||||
#include "task.h"
|
||||
|
||||
#define PIT_CHANNEL0 0x40
|
||||
#define PIT_FREQUENCY 1193182
|
||||
#define PIT_COUNT (65535 / 2)
|
||||
#define DELAY (1000 / (PIT_FREQUENCY / PIT_COUNT))
|
||||
|
||||
static uint32_t sleep_counter;
|
||||
static uint32_t scheduler_counter;
|
||||
|
||||
static void clock_handler(struct registers *regs);
|
||||
|
||||
static void set_pit_count(unsigned count)
|
||||
{
|
||||
cli();
|
||||
|
||||
outb(0x40, count & 0xFF); // Low byte
|
||||
outb(0x40, (count & 0xFF00) >> 8); // High byte
|
||||
|
||||
toris();
|
||||
}
|
||||
|
||||
void clock_init(struct registers *regs)
|
||||
{
|
||||
(void)regs;
|
||||
set_pit_count(PIT_COUNT);
|
||||
register_interrupt_handler(0, clock_handler);
|
||||
}
|
||||
|
||||
static void clock_handler(struct registers *regs)
|
||||
{
|
||||
(void)regs;
|
||||
if (scheduler_counter % 10 == 0)
|
||||
scheduler();
|
||||
scheduler_counter++;
|
||||
sleep_counter--;
|
||||
}
|
||||
|
||||
void sleep(uint64_t delay)
|
||||
{
|
||||
sleep_counter = delay / DELAY;
|
||||
while (sleep_counter)
|
||||
;
|
||||
}
|
8
src/drivers/drivers.c
Normal file
8
src/drivers/drivers.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include "drivers.h"
|
||||
#include "interrupts.h"
|
||||
|
||||
void load_drivers(void)
|
||||
{
|
||||
register_interrupt_handler(0, clock_init);
|
||||
register_interrupt_handler(1, keyboard_handler);
|
||||
}
|
24
src/drivers/keyboard.c
Normal file
24
src/drivers/keyboard.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "keyboard.h"
|
||||
#include "drivers.h"
|
||||
#include "interrupts.h"
|
||||
#include "terminal.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static bool new_input_indicator = false;
|
||||
static struct key_event new_input = {};
|
||||
|
||||
void keyboard_handler(struct registers *regs)
|
||||
{
|
||||
(void)regs;
|
||||
new_input_indicator = true;
|
||||
new_input = terminal_getkey();
|
||||
}
|
||||
|
||||
struct key_event get_key(void)
|
||||
{
|
||||
while (!new_input_indicator)
|
||||
;
|
||||
new_input_indicator = false;
|
||||
return new_input;
|
||||
}
|
21
src/drivers/vbe.c
Normal file
21
src/drivers/vbe.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "vbe.h"
|
||||
#include "icon.h"
|
||||
|
||||
struct vbe_interface display;
|
||||
|
||||
void put_pixel(uint32_t color, uint32_t x, uint32_t y)
|
||||
{
|
||||
// divide by 4 because display.buff is in 32bit instead of 8bit
|
||||
const uint32_t coords = x + y * display.pitch / 4;
|
||||
display.buff[coords] = color;
|
||||
}
|
||||
|
||||
void draw_icon(uint32_t pos_x, uint32_t pos_y, struct icon *img)
|
||||
{
|
||||
for (uint32_t y = 0; y < img->height; y++) {
|
||||
for (uint32_t x = 0; x < img->width; x++) {
|
||||
put_pixel(img->pixels[y * img->width + x], pos_x + x,
|
||||
pos_y + y);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,14 +5,15 @@
|
||||
|
||||
extern void set_gdt(uint32_t gdt_ptr);
|
||||
|
||||
struct tss TSS;
|
||||
uint8_t gdt_entries[GDT_SIZE * 8];
|
||||
struct gdt_descriptor *gdtr = (struct gdt_descriptor *)GDT_ADDRESS;
|
||||
struct gdt_descriptor gdtr;
|
||||
|
||||
static void set_gdt_entry_value(uint8_t *target, uint32_t base, uint32_t limit,
|
||||
uint8_t access, uint8_t granularity)
|
||||
{
|
||||
if (limit > 0xFFFFF) {
|
||||
kprintf(KERN_ERR,
|
||||
kprintf(KERN_ERR
|
||||
"GDT cannot encode limits larger than 0xFFFFF");
|
||||
}
|
||||
|
||||
@ -36,13 +37,13 @@ static void set_gdt_entry_value(uint8_t *target, uint32_t base, uint32_t limit,
|
||||
|
||||
void init_gdt(void)
|
||||
{
|
||||
gdtr->size = 8 * GDT_SIZE - 1;
|
||||
gdtr->base = (uint32_t)&gdt_entries[0];
|
||||
gdtr.size = 8 * GDT_SIZE - 1;
|
||||
gdtr.base = (uint32_t)&gdt_entries[0];
|
||||
|
||||
set_gdt_entry_value(gdt_entries + 0x00, 0, 0, 0, 0); // Null segment
|
||||
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x08, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_KERNEL_CODE, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_KERNEL_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_EXECUTABLE |
|
||||
GDT_ACCESS_DC_NOT_CONFORM |
|
||||
@ -50,7 +51,7 @@ void init_gdt(void)
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // Kernel code
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x10, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_KERNEL_DATA, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_KERNEL_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_NOT_EXECUTABLE |
|
||||
GDT_ACCESS_DC_NOT_CONFORM |
|
||||
@ -58,7 +59,7 @@ void init_gdt(void)
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // Kernel data
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x18, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_KERNEL_STACK, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_KERNEL_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_NOT_EXECUTABLE |
|
||||
GDT_ACCESS_DC_CONFORM |
|
||||
@ -67,7 +68,7 @@ void init_gdt(void)
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // Kernel stack
|
||||
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x20, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_USER_CODE, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_USER_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_EXECUTABLE |
|
||||
GDT_ACCESS_DC_CONFORM |
|
||||
@ -75,7 +76,7 @@ void init_gdt(void)
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // User code
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x28, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_USER_DATA, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_USER_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_NOT_EXECUTABLE |
|
||||
GDT_ACCESS_DC_NOT_CONFORM |
|
||||
@ -83,13 +84,16 @@ void init_gdt(void)
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // User data
|
||||
set_gdt_entry_value(
|
||||
gdt_entries + 0x30, 0, 0xFFFFF,
|
||||
gdt_entries + GDT_OFFSET_USER_STACK, 0, 0xFFFFF,
|
||||
GDT_ACCESS_P_VALID | GDT_ACCESS_DPL_USER_MODE |
|
||||
GDT_ACCESS_S_CODE_OR_DATA | GDT_ACCESS_E_NOT_EXECUTABLE |
|
||||
GDT_ACCESS_DC_CONFORM |
|
||||
GDT_ACCESS_RW_READABLE_FOR_CODE_WRITABLE_FOR_DATA |
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // User stack
|
||||
// TSS
|
||||
set_gdt_entry_value(gdt_entries + GDT_OFFSET_TSS, (uint32_t)&TSS,
|
||||
sizeof(struct tss) - 1, 0x89, 0);
|
||||
|
||||
set_gdt(((uint32_t)gdtr));
|
||||
set_gdt(((uint32_t)&gdtr));
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
.global set_gdt
|
||||
|
||||
set_gdt:
|
||||
cli // disable all interrupts
|
||||
mov eax, [esp+4] // 1st parameter : pointer to the IDT
|
||||
lgdt [eax]
|
||||
mov ax, 0x10 // 0x10 is the offset in the GDT to our data segment
|
||||
@ -15,4 +16,5 @@
|
||||
mov ss, ax
|
||||
jmp 0x08:.flush // 0x08 is the offset to our code segment: far jump on it
|
||||
.flush:
|
||||
ret
|
||||
ret
|
||||
|
||||
|
60
src/interrupt/handler.c
Normal file
60
src/interrupt/handler.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "interrupts.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "power.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
const char *faults[] = {
|
||||
"division by zero",
|
||||
"debugger",
|
||||
"NMI",
|
||||
"breakpoint",
|
||||
"overflow",
|
||||
"bounds",
|
||||
"invalid opcode",
|
||||
"coprocessor not available",
|
||||
"double fault",
|
||||
"coprocessor segement overrun",
|
||||
"invalid task state segment",
|
||||
"segment not present",
|
||||
"stack fault",
|
||||
"general protection fault",
|
||||
"page fault",
|
||||
"reserved",
|
||||
"math fault",
|
||||
"alignment check",
|
||||
"machine check",
|
||||
"SIMD floating point exception",
|
||||
};
|
||||
|
||||
static isr_t interrupt_handlers[16];
|
||||
|
||||
void isr_handler(struct registers *regs)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
while (i < ARRAY_SIZE(faults)) {
|
||||
if (i == 6)
|
||||
reboot();
|
||||
if (i == regs->int_no)
|
||||
kpanic("interrupt: %s\n", faults[i]);
|
||||
i++;
|
||||
}
|
||||
kprintf(KERN_ERR "interrupt triggered with no matching code\n");
|
||||
}
|
||||
|
||||
void register_interrupt_handler(int i, isr_t handler)
|
||||
{
|
||||
interrupt_handlers[i] = handler;
|
||||
}
|
||||
|
||||
void irq_handler(struct registers *regs)
|
||||
{
|
||||
if (regs->int_no != 0) {
|
||||
isr_t handler = interrupt_handlers[regs->int_no - 32];
|
||||
handler(regs);
|
||||
}
|
||||
pic_send_eoi(regs->int_no);
|
||||
}
|
48
src/interrupt/idt.c
Normal file
48
src/interrupt/idt.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "apic.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "kprintf.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)
|
||||
|
||||
extern void *isr_stub_table[];
|
||||
extern void *irq_stub_table[];
|
||||
|
||||
__attribute__((aligned(0x10))) static struct idt_entry idt_entries[IDT_SIZE];
|
||||
static struct idt_descriptor idtr;
|
||||
|
||||
void load_idt(struct idt_descriptor *idtr);
|
||||
|
||||
void idt_set_descriptor(uint8_t index, void *isr, uint8_t flags)
|
||||
{
|
||||
struct idt_entry *descriptor = &idt_entries[index];
|
||||
|
||||
descriptor->isr_low = (uint32_t)isr & 0xFFFF;
|
||||
descriptor->kernel_cs = GDT_OFFSET_KERNEL_CODE;
|
||||
descriptor->attributes = flags;
|
||||
descriptor->isr_high = (uint32_t)isr >> 16;
|
||||
descriptor->reserved = 0;
|
||||
}
|
||||
|
||||
void init_idt(void)
|
||||
{
|
||||
idtr.offset = (uintptr_t)&idt_entries[0];
|
||||
idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < 32; i++)
|
||||
idt_set_descriptor(i, isr_stub_table[i], 0x8E);
|
||||
pic_remap(0x20, 0x28);
|
||||
for (uint8_t j = 0; j < 16; j++)
|
||||
idt_set_descriptor(i + j, irq_stub_table[j], 0x8E);
|
||||
load_idt(&idtr);
|
||||
__asm__ volatile("sti");
|
||||
}
|
138
src/interrupt/irq.s
Normal file
138
src/interrupt/irq.s
Normal file
@ -0,0 +1,138 @@
|
||||
.intel_syntax noprefix
|
||||
.extern irq_handler
|
||||
|
||||
irq_common_stub:
|
||||
// push general purpose registers
|
||||
pusha
|
||||
|
||||
// push data segment selector
|
||||
mov ax, ds
|
||||
push eax
|
||||
|
||||
// use kernel data segment
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
// hand over stack to C function
|
||||
push esp
|
||||
// and call it
|
||||
call irq_handler
|
||||
// pop stack pointer again
|
||||
pop eax
|
||||
|
||||
// restore original segment pointers segment
|
||||
pop eax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
// restore registers
|
||||
popa
|
||||
|
||||
// remove int_no and err_code from stack
|
||||
add esp, 8
|
||||
|
||||
iret
|
||||
|
||||
irq0:
|
||||
mov [esp_backup], esp
|
||||
push 0
|
||||
push 32
|
||||
jmp irq_common_stub
|
||||
|
||||
irq1:
|
||||
push 1
|
||||
push 33
|
||||
jmp irq_common_stub
|
||||
|
||||
irq2:
|
||||
push 2
|
||||
push 34
|
||||
jmp irq_common_stub
|
||||
|
||||
irq3:
|
||||
push 3
|
||||
push 35
|
||||
jmp irq_common_stub
|
||||
|
||||
irq4:
|
||||
push 4
|
||||
push 36
|
||||
jmp irq_common_stub
|
||||
|
||||
irq5:
|
||||
push 5
|
||||
push 37
|
||||
jmp irq_common_stub
|
||||
|
||||
irq6:
|
||||
push 6
|
||||
push 38
|
||||
jmp irq_common_stub
|
||||
|
||||
irq7:
|
||||
push 7
|
||||
push 39
|
||||
jmp irq_common_stub
|
||||
|
||||
irq8:
|
||||
push 8
|
||||
push 40
|
||||
jmp irq_common_stub
|
||||
|
||||
irq9:
|
||||
push 9
|
||||
push 41
|
||||
jmp irq_common_stub
|
||||
|
||||
irq10:
|
||||
push 10
|
||||
push 42
|
||||
jmp irq_common_stub
|
||||
|
||||
irq11:
|
||||
push 11
|
||||
push 43
|
||||
jmp irq_common_stub
|
||||
|
||||
irq12:
|
||||
push 12
|
||||
push 44
|
||||
jmp irq_common_stub
|
||||
|
||||
irq13:
|
||||
push 13
|
||||
push 45
|
||||
jmp irq_common_stub
|
||||
|
||||
irq14:
|
||||
push 14
|
||||
push 46
|
||||
jmp irq_common_stub
|
||||
|
||||
irq15:
|
||||
push 15
|
||||
push 47
|
||||
jmp irq_common_stub
|
||||
|
||||
.global irq_stub_table
|
||||
irq_stub_table:
|
||||
.long irq0
|
||||
.long irq1
|
||||
.long irq2
|
||||
.long irq3
|
||||
.long irq4
|
||||
.long irq5
|
||||
.long irq6
|
||||
.long irq7
|
||||
.long irq8
|
||||
.long irq9
|
||||
.long irq10
|
||||
.long irq11
|
||||
.long irq12
|
||||
.long irq13
|
||||
.long irq14
|
||||
.long irq15
|
257
src/interrupt/isr.s
Normal file
257
src/interrupt/isr.s
Normal file
@ -0,0 +1,257 @@
|
||||
.intel_syntax noprefix
|
||||
.extern isr_handler
|
||||
|
||||
isr_common_stub:
|
||||
// push general purpose registers
|
||||
pusha
|
||||
|
||||
// push data segment selector
|
||||
mov ax, ds
|
||||
push eax
|
||||
|
||||
// use kernel data segment
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
// hand over stack to C function
|
||||
push esp
|
||||
// and call it
|
||||
call isr_handler
|
||||
// pop stack pointer again
|
||||
pop eax
|
||||
|
||||
// restore original segment pointers segment
|
||||
pop eax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
// restore registers
|
||||
popa
|
||||
|
||||
// remove int_no and err_code from stack
|
||||
add esp, 8
|
||||
|
||||
iret
|
||||
|
||||
// 0: Divide By Zero Exception
|
||||
isr0:
|
||||
push 0
|
||||
push 0
|
||||
jmp isr_common_stub
|
||||
|
||||
// 1: Debug Exception
|
||||
isr1:
|
||||
push 0
|
||||
push 1
|
||||
jmp isr_common_stub
|
||||
|
||||
// 2: Non Maskable Interrupt Exception
|
||||
isr2:
|
||||
push 0
|
||||
push 2
|
||||
jmp isr_common_stub
|
||||
|
||||
// 3: Int 3 Exception
|
||||
isr3:
|
||||
push 0
|
||||
push 3
|
||||
jmp isr_common_stub
|
||||
|
||||
// 4: INTO Exception
|
||||
isr4:
|
||||
push 0
|
||||
push 4
|
||||
jmp isr_common_stub
|
||||
|
||||
// 5: Out of Bounds Exception
|
||||
isr5:
|
||||
push 0
|
||||
push 5
|
||||
jmp isr_common_stub
|
||||
|
||||
// 6: Invalid Opcode Exception
|
||||
isr6:
|
||||
push 0
|
||||
push 6
|
||||
jmp isr_common_stub
|
||||
|
||||
// 7: Coprocessor Not Available Exception
|
||||
isr7:
|
||||
push 0
|
||||
push 7
|
||||
jmp isr_common_stub
|
||||
|
||||
// 8: Double Fault Exception (With Error Code!)
|
||||
isr8:
|
||||
push 8
|
||||
jmp isr_common_stub
|
||||
|
||||
// 9: Coprocessor Segment Overrun Exception
|
||||
isr9:
|
||||
push 0
|
||||
push 9
|
||||
jmp isr_common_stub
|
||||
|
||||
// 10: Bad TSS Exception (With Error Code!)
|
||||
isr10:
|
||||
push 10
|
||||
jmp isr_common_stub
|
||||
|
||||
// 11: Segment Not Present Exception (With Error Code!)
|
||||
isr11:
|
||||
push 11
|
||||
jmp isr_common_stub
|
||||
|
||||
// 12: Stack Fault Exception (With Error Code!)
|
||||
isr12:
|
||||
push 12
|
||||
jmp isr_common_stub
|
||||
|
||||
// 13: General Protection Fault Exception (With Error Code!)
|
||||
isr13:
|
||||
push 13
|
||||
jmp isr_common_stub
|
||||
|
||||
// 14: Page Fault Exception (With Error Code!)
|
||||
isr14:
|
||||
push 14
|
||||
jmp isr_common_stub
|
||||
|
||||
// 15: Reserved Exception
|
||||
isr15:
|
||||
push 0
|
||||
push 15
|
||||
jmp isr_common_stub
|
||||
|
||||
// 16: Floating Point Exception
|
||||
isr16:
|
||||
push 0
|
||||
push 16
|
||||
jmp isr_common_stub
|
||||
|
||||
// 17: Alignment Check Exception
|
||||
isr17:
|
||||
push 17
|
||||
jmp isr_common_stub
|
||||
|
||||
// 18: Machine Check Exception
|
||||
isr18:
|
||||
push 0
|
||||
push 18
|
||||
jmp isr_common_stub
|
||||
|
||||
// 19: Reserved
|
||||
isr19:
|
||||
push 0
|
||||
push 19
|
||||
jmp isr_common_stub
|
||||
|
||||
// 20: Reserved
|
||||
isr20:
|
||||
push 0
|
||||
push 20
|
||||
jmp isr_common_stub
|
||||
|
||||
// 21: Reserved
|
||||
isr21:
|
||||
push 21
|
||||
jmp isr_common_stub
|
||||
|
||||
// 22: Reserved
|
||||
isr22:
|
||||
push 0
|
||||
push 22
|
||||
jmp isr_common_stub
|
||||
|
||||
// 23: Reserved
|
||||
isr23:
|
||||
push 0
|
||||
push 23
|
||||
jmp isr_common_stub
|
||||
|
||||
// 24: Reserved
|
||||
isr24:
|
||||
push 0
|
||||
push 24
|
||||
jmp isr_common_stub
|
||||
|
||||
// 25: Reserved
|
||||
isr25:
|
||||
push 0
|
||||
push 25
|
||||
jmp isr_common_stub
|
||||
|
||||
// 26: Reserved
|
||||
isr26:
|
||||
push 0
|
||||
push 26
|
||||
jmp isr_common_stub
|
||||
|
||||
// 27: Reserved
|
||||
isr27:
|
||||
push 0
|
||||
push 27
|
||||
jmp isr_common_stub
|
||||
|
||||
// 28: Reserved
|
||||
isr28:
|
||||
push 0
|
||||
push 28
|
||||
jmp isr_common_stub
|
||||
|
||||
// 29: Reserved
|
||||
isr29:
|
||||
push 0
|
||||
push 29
|
||||
jmp isr_common_stub
|
||||
|
||||
// 30: Reserved
|
||||
isr30:
|
||||
push 0
|
||||
push 30
|
||||
jmp isr_common_stub
|
||||
|
||||
// 31: Reserved
|
||||
isr31:
|
||||
push 0
|
||||
push 31
|
||||
jmp isr_common_stub
|
||||
|
||||
.global isr_stub_table
|
||||
isr_stub_table:
|
||||
.long isr0
|
||||
.long isr1
|
||||
.long isr2
|
||||
.long isr3
|
||||
.long isr4
|
||||
.long isr5
|
||||
.long isr6
|
||||
.long isr7
|
||||
.long isr8
|
||||
.long isr9
|
||||
.long isr10
|
||||
.long isr11
|
||||
.long isr12
|
||||
.long isr13
|
||||
.long isr14
|
||||
.long isr15
|
||||
.long isr16
|
||||
.long isr17
|
||||
.long isr18
|
||||
.long isr19
|
||||
.long isr20
|
||||
.long isr21
|
||||
.long isr22
|
||||
.long isr23
|
||||
.long isr24
|
||||
.long isr25
|
||||
.long isr26
|
||||
.long isr27
|
||||
.long isr28
|
||||
.long isr29
|
||||
.long isr30
|
||||
.long isr31
|
11
src/interrupt/load_idt.s
Normal file
11
src/interrupt/load_idt.s
Normal file
@ -0,0 +1,11 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.global load_idt
|
||||
load_idt:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [ebp + 8]
|
||||
lidt [eax]
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
23
src/interrupt/msr.c
Normal file
23
src/interrupt/msr.c
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
const uint32_t CPUID_FLAG_MSR = 1 << 5;
|
||||
|
||||
bool cpu_has_msr()
|
||||
{
|
||||
static unsigned int eax, edx, unused;
|
||||
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
||||
return edx & CPUID_FLAG_MSR;
|
||||
}
|
||||
|
||||
void cpu_get_msr(uint32_t msr, uint32_t *lo, uint32_t *hi)
|
||||
{
|
||||
asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr));
|
||||
}
|
||||
|
||||
void cpu_set_msr(uint32_t msr, uint32_t lo, uint32_t hi)
|
||||
{
|
||||
asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr));
|
||||
}
|
64
src/interrupt/pic.c
Normal file
64
src/interrupt/pic.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include "sys/io.h"
|
||||
#include <stdint.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 /* Indicates that ICW4 will be present */
|
||||
#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 /* End-of-interrupt command code */
|
||||
|
||||
void pic_remap(int offset_master, int offset_slave)
|
||||
{
|
||||
uint8_t a1, a2;
|
||||
|
||||
a1 = inb(PIC1_DATA); // save masks
|
||||
a2 = inb(PIC2_DATA);
|
||||
|
||||
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization
|
||||
// sequence (in cascade mode)
|
||||
io_wait();
|
||||
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC1_DATA, offset_master); // ICW2: Master PIC vector offset
|
||||
io_wait();
|
||||
outb(PIC2_DATA, offset_slave); // ICW2: Slave PIC vector offset
|
||||
io_wait();
|
||||
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC
|
||||
// at IRQ2 (0000 0100)
|
||||
io_wait();
|
||||
outb(PIC2_DATA,
|
||||
2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
|
||||
io_wait();
|
||||
|
||||
outb(
|
||||
PIC1_DATA,
|
||||
ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
|
||||
io_wait();
|
||||
outb(PIC2_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outb(PIC1_DATA, a1); // restore saved masks.
|
||||
outb(PIC2_DATA, a2);
|
||||
}
|
||||
|
||||
void pic_send_eoi(uint8_t irq)
|
||||
{
|
||||
if (irq >= 8)
|
||||
outb(PIC2_COMMAND, PIC_EOI);
|
||||
outb(PIC1_COMMAND, PIC_EOI);
|
||||
}
|
33
src/kernel.c
33
src/kernel.c
@ -1,8 +1,19 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "drivers.h"
|
||||
#include "gdt.h"
|
||||
#include "icon.h"
|
||||
#include "idt.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "multiboot.h"
|
||||
#include "power.h"
|
||||
#include "shell.h"
|
||||
#include "string.h"
|
||||
#include "task.h"
|
||||
#include "terminal.h"
|
||||
/* #include "power.h" */
|
||||
#include "gdt.h"
|
||||
#include "time.h"
|
||||
#include "vbe.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -19,11 +30,23 @@
|
||||
#error "This tutorial needs to be compiled with a ix86-elf compiler"
|
||||
#endif
|
||||
|
||||
void kernel_main(void)
|
||||
static void bozo(int int_code)
|
||||
{
|
||||
/* Initialize terminal interface */
|
||||
terminal_initialize();
|
||||
kprintf("apagnan code\n");
|
||||
}
|
||||
|
||||
void kernel_main(multiboot_info_t *mbd, uint32_t magic)
|
||||
{
|
||||
terminal_initialize();
|
||||
init_gdt();
|
||||
init_idt();
|
||||
init_memory(mbd, magic);
|
||||
load_drivers();
|
||||
create_kernel_task();
|
||||
kill(0, 4);
|
||||
for (size_t i = 0; i < 10000; i++)
|
||||
free_pages(alloc_pages(1, NULL), 1);
|
||||
signal(4, bozo);
|
||||
kill(0, 4);
|
||||
shell_init();
|
||||
}
|
||||
|
36
src/kpanic.c
Normal file
36
src/kpanic.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "keyboard.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "power.h"
|
||||
#include "string.h"
|
||||
#include "terminal.h"
|
||||
|
||||
extern uint32_t page_table1[1024];
|
||||
extern const char *faults[];
|
||||
void clear_registers(void);
|
||||
|
||||
__attribute__((noreturn)) void kpanic(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
/* terminal_set_bg_color(VGA_COLOR_BLUE); */
|
||||
/* terminal_clear(); */
|
||||
kprintf("kpanic: ");
|
||||
va_start(va, format);
|
||||
kvprintf(format, &va);
|
||||
va_end(va);
|
||||
|
||||
uint32_t faulting_address;
|
||||
// __asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
|
||||
// kprintf("fault at address: %p\n", faulting_address);
|
||||
/* for (int i = 16; i < 32; i++) */
|
||||
/* kprintf("%p\n", page_table1[i]); */
|
||||
// show_valloc_mem();
|
||||
/* kprintf("\n\n"); */
|
||||
/* print_stack(); */
|
||||
/* kprintf("\n\n"); */
|
||||
/* kprintf("PRESS SPACE TO REBOOT"); */
|
||||
__asm__ __volatile__("jmp panic");
|
||||
}
|
@ -1,17 +1,14 @@
|
||||
#include "kprintf.h"
|
||||
#include "ctype.h"
|
||||
#include "string.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int kprintf(int level, const char *restrict format, ...)
|
||||
int kprintf(const char *restrict format, ...)
|
||||
{
|
||||
va_list va;
|
||||
int i;
|
||||
|
||||
va_start(va, format);
|
||||
i = kvprintf(level, format, va);
|
||||
i = kvprintf(format, &va);
|
||||
va_end(va);
|
||||
return i;
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
#include "base.h"
|
||||
#include "ctype.h"
|
||||
#include "kprintf.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int print_int_base(int64_t number, const char *prefix, const char *base);
|
||||
|
||||
static int get_level(const char *str)
|
||||
{
|
||||
if (!str || !isdigit(str[0]))
|
||||
return 0;
|
||||
return str[0] - '0';
|
||||
}
|
||||
|
||||
static int print_flag(char flag, va_list *ap)
|
||||
{
|
||||
@ -12,32 +20,42 @@ static int print_flag(char flag, va_list *ap)
|
||||
case '%':
|
||||
return terminal_putchar('%');
|
||||
case 'i':
|
||||
return terminal_writelong(va_arg(*ap, int));
|
||||
return print_int_base(va_arg(*ap, int32_t), NULL, BASE_DECA);
|
||||
case 'd':
|
||||
return terminal_writelong(va_arg(*ap, int));
|
||||
return print_int_base(va_arg(*ap, int32_t), NULL, BASE_DECA);
|
||||
case 'c':
|
||||
return terminal_putchar(va_arg(*ap, int));
|
||||
case 's':
|
||||
return terminal_writestring(va_arg(*ap, char *));
|
||||
case 'p':
|
||||
return print_int_base(va_arg(*ap, uint32_t), "0x", BASE_HEXA);
|
||||
case 'x':
|
||||
return print_int_base(va_arg(*ap, int32_t), "0x", BASE_HEXA);
|
||||
case 'u':
|
||||
return print_int_base(va_arg(*ap, uint32_t), NULL, BASE_DECA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvprintf(int level, const char *restrict format, va_list ap)
|
||||
int kvprintf(const char *restrict format, va_list *ap)
|
||||
{
|
||||
const char *start = format;
|
||||
int ret = 0;
|
||||
|
||||
(void)level;
|
||||
const int level = get_level(format);
|
||||
set_color_level(level);
|
||||
if (level)
|
||||
start++;
|
||||
while (*start != '\0') {
|
||||
if (*start == '%' && *(start + 1) != '\0') {
|
||||
ret += print_flag(*(start + 1), &ap);
|
||||
ret += print_flag(*(start + 1), ap);
|
||||
start++;
|
||||
} else {
|
||||
ret += terminal_putchar(*start);
|
||||
}
|
||||
start++;
|
||||
}
|
||||
set_color_level(0);
|
||||
update_cursor();
|
||||
return ret;
|
||||
}
|
||||
|
28
src/kprint/print_int_base.c
Normal file
28
src/kprint/print_int_base.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "string.h"
|
||||
#include "terminal.h"
|
||||
|
||||
int print_int_base(int64_t number, const char *prefix, const char *base)
|
||||
{
|
||||
const int base_size = strlen(base);
|
||||
uint64_t div = 1;
|
||||
uint32_t tmp;
|
||||
int rv = 0;
|
||||
|
||||
if (prefix)
|
||||
terminal_writestring(prefix);
|
||||
if (number < 0) {
|
||||
rv += terminal_putchar('-');
|
||||
tmp = -1 * number;
|
||||
} else {
|
||||
tmp = number;
|
||||
}
|
||||
while (div <= tmp / base_size)
|
||||
div *= base_size;
|
||||
while (div > 0) {
|
||||
rv += terminal_putchar(base[tmp / div % base_size]);
|
||||
div /= base_size;
|
||||
}
|
||||
return rv;
|
||||
}
|
43
src/memory/frame.c
Normal file
43
src/memory/frame.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
|
||||
void *alloc_frame(void)
|
||||
{
|
||||
struct frame_zone *it = head;
|
||||
while (it && !it->remaining_frames)
|
||||
it = it->next;
|
||||
if (!it || it->remaining_frames == 0) {
|
||||
kprintf(KERN_CRIT "No memory zone available (ratio)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t i = it->first_free_frame;
|
||||
for (; GET_FRAME(it->frame_table, i); i++)
|
||||
;
|
||||
it->first_free_frame++;
|
||||
it->remaining_frames--;
|
||||
SET_FRAME(it->frame_table, i, 1);
|
||||
return it->addr + i * PAGE_SIZE;
|
||||
}
|
||||
|
||||
int free_frame(void *frame_ptr)
|
||||
{
|
||||
struct frame_zone *it = head;
|
||||
while (it && (frame_ptr < it->addr ||
|
||||
frame_ptr >= it->addr + it->total_frames * PAGE_SIZE))
|
||||
it = it->next;
|
||||
|
||||
uint32_t index = ((frame_ptr - it->addr) / PAGE_SIZE);
|
||||
SET_FRAME(it->frame_table, index, 0);
|
||||
if (it->first_free_frame > index)
|
||||
it->first_free_frame = index;
|
||||
it->remaining_frames++;
|
||||
return 0;
|
||||
}
|
12
src/memory/load_pd.s
Normal file
12
src/memory/load_pd.s
Normal file
@ -0,0 +1,12 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.text
|
||||
.global load_page_directory
|
||||
load_page_directory:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [esp + 8]
|
||||
mov cr3, eax
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
123
src/memory/memory.c
Normal file
123
src/memory/memory.c
Normal file
@ -0,0 +1,123 @@
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t *kernel_pd = &boot_page_directory;
|
||||
uint32_t *current_pd;
|
||||
uint32_t page_table_default[1024] __attribute__((aligned(PAGE_SIZE)));
|
||||
uint32_t frame_zones_page_table[1024] __attribute__((aligned(PAGE_SIZE)));
|
||||
uint32_t mem_size;
|
||||
struct frame_zone *head;
|
||||
|
||||
void switch_pd(uint32_t *pd, uint32_t *cr3)
|
||||
{
|
||||
current_pd = pd;
|
||||
asm volatile("mov %0, %%cr3" ::"r"(cr3));
|
||||
}
|
||||
|
||||
static void lst_add_back(struct frame_zone **root, struct frame_zone *element)
|
||||
{
|
||||
if (!*root) {
|
||||
*root = element;
|
||||
return;
|
||||
}
|
||||
struct frame_zone *it = *root;
|
||||
while (it->next)
|
||||
it = it->next;
|
||||
it->next = element;
|
||||
}
|
||||
|
||||
static void add_frame_node(multiboot_memory_map_t *mmmt)
|
||||
{
|
||||
static uint32_t index;
|
||||
|
||||
/**
|
||||
* # = kernel code
|
||||
* - = blank
|
||||
*/
|
||||
|
||||
uint64_t start_addr = mmmt->addr;
|
||||
uint64_t end_addr = mmmt->addr + mmmt->len;
|
||||
uint64_t len = mmmt->len;
|
||||
|
||||
/** Kernel code cover all the block
|
||||
* this situation:
|
||||
* #######################
|
||||
*/
|
||||
if (KERNEL_START <= start_addr && KERNEL_END >= end_addr)
|
||||
return;
|
||||
|
||||
/** Kernel code start on the block
|
||||
* this situation:
|
||||
* --------###############
|
||||
*/
|
||||
if (KERNEL_START > start_addr && KERNEL_START <= end_addr)
|
||||
len = ROUND_FLOOR(KERNEL_START - start_addr, PAGE_SIZE);
|
||||
/** Kernel code end on the block
|
||||
* this situation:
|
||||
* ###############--------
|
||||
*/
|
||||
if (KERNEL_START <= start_addr && KERNEL_END > start_addr &&
|
||||
KERNEL_END <= end_addr) {
|
||||
len = ROUND_CEIL(len - (KERNEL_END - start_addr), PAGE_SIZE) -
|
||||
PAGE_SIZE; // cringe but ROUND_FLOOR is un poquito crampte
|
||||
start_addr = ROUND_CEIL(KERNEL_END, PAGE_SIZE);
|
||||
}
|
||||
end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE);
|
||||
|
||||
init_page_table(frame_zones_page_table, 0);
|
||||
kernel_pd[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03;
|
||||
frame_zones_page_table[index] =
|
||||
((uint32_t)start_addr & PAGE_MASK) | INIT_FLAGS;
|
||||
|
||||
struct frame_zone *current =
|
||||
(struct frame_zone *)GET_PAGE_ADDR(1022, index++);
|
||||
|
||||
current->frame_table = (uint8_t *)current + sizeof(struct frame_zone);
|
||||
|
||||
/** 8 is cause we are using uint8_t
|
||||
nb_frame = size / (PAGE_SIZE + 1 / 8)
|
||||
cause we are using non decimal number
|
||||
nb_frame = ((size * 8) / (PAGE_SIZE * 8 + 1))
|
||||
*/
|
||||
const uint32_t nb_frame = ((len * 8) / (PAGE_SIZE * 8 + 1));
|
||||
current->first_free_frame = 0;
|
||||
current->next = NULL;
|
||||
current->remaining_frames = nb_frame;
|
||||
current->total_frames = nb_frame;
|
||||
|
||||
memset(current->frame_table, 0,
|
||||
nb_frame * sizeof(*current->frame_table));
|
||||
|
||||
uint32_t i = 1;
|
||||
for (; i < CEIL(nb_frame, PAGE_SIZE); i++)
|
||||
frame_zones_page_table[index + i] =
|
||||
((uint32_t)(start_addr + i * PAGE_SIZE) & PAGE_MASK) |
|
||||
INIT_FLAGS;
|
||||
current->addr = (void *)start_addr + i * PAGE_SIZE;
|
||||
index += i - 1;
|
||||
lst_add_back(&head, current);
|
||||
}
|
||||
|
||||
static void init_frame_zones(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < mmap_length; i++) {
|
||||
multiboot_memory_map_t *mmmt =
|
||||
(multiboot_memory_map_t *)mmap_addr + i;
|
||||
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||
add_frame_node(mmmt);
|
||||
}
|
||||
}
|
||||
|
||||
void init_memory(multiboot_info_t *mbd, uint32_t magic)
|
||||
{
|
||||
for (uint16_t i = 0; i < 0x300; i++)
|
||||
kernel_pd[i] = 0x02;
|
||||
init_page_table(page_table_default, 0);
|
||||
kernel_pd[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03;
|
||||
current_pd = kernel_pd;
|
||||
init_multiboot(mbd, magic);
|
||||
init_frame_zones();
|
||||
}
|
107
src/memory/page.c
Normal file
107
src/memory/page.c
Normal file
@ -0,0 +1,107 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "task.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr,
|
||||
uint32_t **page_table_ptr)
|
||||
{
|
||||
for (*pd_index_ptr = 1; *pd_index_ptr < 768; (*pd_index_ptr)++) {
|
||||
if (current_pd[(*pd_index_ptr)] == 0x02) {
|
||||
if (add_page_table(*pd_index_ptr) < 0)
|
||||
return -2;
|
||||
}
|
||||
*page_table_ptr =
|
||||
(uint32_t *)GET_PAGE_ADDR(0, *pd_index_ptr + PT_START);
|
||||
for (uint16_t i = 0; i + nb_pages - 1 < PT_SIZE; i++) {
|
||||
uint16_t j;
|
||||
for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j &&
|
||||
j < nb_pages;
|
||||
j++)
|
||||
;
|
||||
if (j == nb_pages)
|
||||
return i;
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t add_single_page(void *frame)
|
||||
{
|
||||
uint16_t pd_index;
|
||||
uint32_t *page_table;
|
||||
const int16_t i = find_next_block(1, &pd_index, &page_table);
|
||||
|
||||
if (i < 0) {
|
||||
kprintf(KERN_CRIT "impossible to add page to page directory\n");
|
||||
return -1;
|
||||
}
|
||||
page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *alloc_pages(size_t size, void **phys_addr)
|
||||
{
|
||||
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
|
||||
uint16_t pd_index;
|
||||
uint32_t *page_table;
|
||||
const int16_t index = find_next_block(nb_pages, &pd_index, &page_table);
|
||||
|
||||
if (index < 0) {
|
||||
kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index,
|
||||
PT_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = index; i - (size_t)index < nb_pages; i++) {
|
||||
void *frame = alloc_frame();
|
||||
if (!frame) {
|
||||
for (size_t j = index; j < i; j++)
|
||||
free_frame((void *)(page_table[j] & PAGE_MASK));
|
||||
return NULL;
|
||||
}
|
||||
if (phys_addr)
|
||||
*phys_addr = frame;
|
||||
page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS;
|
||||
}
|
||||
memset((void *)GET_PAGE_ADDR(pd_index, index), 0, nb_pages * PAGE_SIZE);
|
||||
return (void *)GET_PAGE_ADDR(pd_index, index);
|
||||
}
|
||||
|
||||
int free_pages(void *page_ptr, size_t size)
|
||||
{
|
||||
const uint32_t page_addr = (uint32_t)page_ptr;
|
||||
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
|
||||
const uint32_t page_index = page_addr / PAGE_SIZE;
|
||||
const uint32_t pd_index = page_index / PD_SIZE;
|
||||
const uint32_t pt_index = page_index % PD_SIZE;
|
||||
|
||||
if ((uint32_t)pd_index > 0x300) {
|
||||
kprintf(KERN_WARNING "Address out of range\n");
|
||||
return -1;
|
||||
} else if (page_addr % PAGE_SIZE) {
|
||||
kprintf(KERN_WARNING "Invalid address\n");
|
||||
return -1;
|
||||
} else if (pt_index + nb_pages > PT_SIZE) {
|
||||
kprintf(KERN_WARNING "Invalid number of frames\n");
|
||||
return -1;
|
||||
}
|
||||
uint32_t *page_table =
|
||||
(uint32_t *)GET_PAGE_ADDR(0, PT_START + pd_index);
|
||||
for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) {
|
||||
if (page_table[i] >> 12 == i) {
|
||||
kprintf(KERN_WARNING "Page already free\n");
|
||||
return -2;
|
||||
}
|
||||
free_frame((void *)(page_table[i] & PAGE_MASK));
|
||||
page_table[i] = i << 12;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
22
src/memory/page_table.c
Normal file
22
src/memory/page_table.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "debug.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
void init_page_table(uint32_t page_table[1024], uint16_t start)
|
||||
{
|
||||
for (uint16_t i = start; i < 1024; i++)
|
||||
page_table[i] = (i << 12) | 0x03;
|
||||
}
|
||||
|
||||
int16_t add_page_table(uint16_t pd_index)
|
||||
{
|
||||
void *frame = alloc_frame();
|
||||
if (!frame)
|
||||
return -1;
|
||||
page_table_default[PT_START + pd_index] =
|
||||
((uint32_t)frame & PAGE_MASK) | 0x03;
|
||||
uint32_t *page_table =
|
||||
(uint32_t *)GET_PAGE_ADDR(0, PT_START + pd_index);
|
||||
init_page_table(page_table, 0);
|
||||
kernel_pd[pd_index] = ((uint32_t)frame & PAGE_MASK) | 0x03;
|
||||
return 0;
|
||||
}
|
13
src/memory/paging.s
Normal file
13
src/memory/paging.s
Normal file
@ -0,0 +1,13 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.text
|
||||
.global enable_paging
|
||||
enable_paging:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, cr0
|
||||
or eax, 0x80000000
|
||||
mov cr0, eax
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
70
src/memory/phys/allocator.c
Normal file
70
src/memory/phys/allocator.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "task.h"
|
||||
|
||||
Zone *kzones[3];
|
||||
|
||||
static void add_zone(Zone *zone, block_type_t type)
|
||||
{
|
||||
// We put the zone at the beginning of the list
|
||||
if (kzones[type]) {
|
||||
assert(kzones[type] != zone);
|
||||
zone->next = kzones[type];
|
||||
kzones[type]->prev = zone;
|
||||
}
|
||||
kzones[type] = zone;
|
||||
}
|
||||
|
||||
static void new_block(Zone *zone, uint32_t zone_size)
|
||||
{
|
||||
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
|
||||
|
||||
// Metadata
|
||||
new_block->in_use = false;
|
||||
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
||||
new_block->sub_size = new_block->size;
|
||||
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
|
||||
new_block->zone = zone;
|
||||
|
||||
// Init future linked lists
|
||||
new_block->prev = NULL;
|
||||
new_block->prev_free = NULL;
|
||||
new_block->prev_used = NULL;
|
||||
new_block->next = NULL;
|
||||
new_block->next_free = NULL;
|
||||
new_block->next_used = NULL;
|
||||
|
||||
if (zone->free) {
|
||||
zone->free->prev = new_block;
|
||||
zone->free->prev_free = new_block;
|
||||
new_block->next = zone->free;
|
||||
new_block->next_free = zone->free;
|
||||
}
|
||||
zone->free = new_block;
|
||||
assert(zone->free == new_block);
|
||||
}
|
||||
|
||||
int new_kzone(block_type_t type, uint32_t size)
|
||||
{
|
||||
// assert(current_task->pid);
|
||||
void *heap = alloc_frame();
|
||||
if (heap == NULL) {
|
||||
kprintf(KERN_ERR "error: alloc_frame failed\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
Zone *zone = (Zone *)heap;
|
||||
zone->type = type;
|
||||
zone->size = size;
|
||||
zone->used = NULL;
|
||||
zone->next = NULL;
|
||||
zone->prev = NULL;
|
||||
|
||||
new_block(zone, size);
|
||||
add_zone(heap, type);
|
||||
|
||||
return (0);
|
||||
}
|
52
src/memory/phys/info.c
Normal file
52
src/memory/phys/info.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "alloc.h"
|
||||
#include "kprintf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// FULL_INFO is to display (or not) both used and unused blocks
|
||||
#define FULL_INFO 1
|
||||
|
||||
void show_kalloc_mem(void)
|
||||
{
|
||||
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||
uint32_t total_size = 0;
|
||||
|
||||
for (block_type_t type = 0; type < 3; ++type) {
|
||||
int count = 0;
|
||||
for (Zone *zone_it = kzones[type]; zone_it != NULL;
|
||||
zone_it = zone_it->next) {
|
||||
if (zone_it->used)
|
||||
kprintf("---------- IN_USE %s [n°%d - %p] "
|
||||
"----------\n",
|
||||
zones_name[type], count, zone_it);
|
||||
for (Block *block_it = zone_it->used; block_it != NULL;
|
||||
block_it = block_it->next_used) {
|
||||
/* i++; */
|
||||
/* if (i < 10) */
|
||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||
(uint32_t)block_it->ptr +
|
||||
block_it->sub_size + sizeof(Block),
|
||||
block_it->sub_size);
|
||||
total_size += block_it->sub_size;
|
||||
}
|
||||
if (zone_it->used)
|
||||
kprintf("\n");
|
||||
count++;
|
||||
#if FULL_INFO
|
||||
if (zone_it->free)
|
||||
kprintf("---------- AVAILABLE %s [n°%d - %p] "
|
||||
"----------\n",
|
||||
zones_name[type], count, zone_it);
|
||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||
block_it = block_it->next_free) {
|
||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||
(uint32_t)block_it->ptr +
|
||||
block_it->sub_size + sizeof(Block),
|
||||
block_it->sub_size);
|
||||
}
|
||||
if (zone_it->free)
|
||||
kprintf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
kprintf("Total: %u\n", total_size);
|
||||
}
|
116
src/memory/phys/kfree.c
Normal file
116
src/memory/phys/kfree.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "alloc.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static void remove_used(Block *to_free)
|
||||
{
|
||||
Block *left = to_free->prev_used;
|
||||
Block *right = to_free->next_used;
|
||||
|
||||
to_free->next_used = NULL;
|
||||
to_free->prev_used = NULL;
|
||||
|
||||
if (!left && !right) {
|
||||
to_free->zone->used = NULL;
|
||||
return;
|
||||
}
|
||||
if (!left)
|
||||
to_free->zone->used = right;
|
||||
else
|
||||
left->next_used = right;
|
||||
if (right)
|
||||
right->prev_used = left;
|
||||
}
|
||||
|
||||
/*
|
||||
* If all the blocks of the zone have been kfreed,
|
||||
* we can unmap the zone and delete it from the list of zones
|
||||
*/
|
||||
static int unmap_zone(Zone *zone)
|
||||
{
|
||||
int err = 0;
|
||||
block_type_t type = zone->type;
|
||||
Zone *left = zone->prev;
|
||||
Zone *right = zone->next;
|
||||
zone->prev = NULL;
|
||||
zone->next = NULL;
|
||||
|
||||
if (!left && !right) {
|
||||
kzones[type] = NULL;
|
||||
goto unmap;
|
||||
}
|
||||
if (!left)
|
||||
kzones[type] = right;
|
||||
else
|
||||
left->next = right;
|
||||
if (right)
|
||||
right->prev = left;
|
||||
unmap:
|
||||
err = free_pages((void *)zone, zone->size);
|
||||
if (err)
|
||||
kprintf(KERN_ERR "error: munmap failed\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the newly kfreed block is next to another previously
|
||||
* kfreed block, merge both of these and update the size
|
||||
*/
|
||||
static Block *merge_blocks(Block *left, Block *right)
|
||||
{
|
||||
if (right->next)
|
||||
right->next->prev = left;
|
||||
if (right->next_free) {
|
||||
right->next_free->prev_free = left;
|
||||
left->next_free = right->next_free;
|
||||
}
|
||||
left->next = right->next;
|
||||
left->size += right->size + sizeof(Block);
|
||||
return (left);
|
||||
}
|
||||
|
||||
// Simply add the new block to the list of available blocks
|
||||
static int add_available(Block *available, Block *merged)
|
||||
{
|
||||
Zone *zone = available->zone;
|
||||
if (merged != zone->free && available != zone->free)
|
||||
available->next_free = zone->free;
|
||||
if (zone->free)
|
||||
zone->free->prev_free = available;
|
||||
zone->free = available;
|
||||
if (zone->type == LARGE)
|
||||
return (unmap_zone(zone));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ptr: pointer to kfree, if the pointer is invalid the kfree()
|
||||
* function will have an undefined behavior (most likely segfault)
|
||||
*
|
||||
* First, we remove the block from the list of in_use blocks
|
||||
* Then, we check if the block needs to be merged with another
|
||||
* neighboring block, if so we replace the previous block by the
|
||||
* newly merged block
|
||||
* Finally, we add the block to the list of available blocks
|
||||
*/
|
||||
void kfree(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||
Block *to_merge = NULL;
|
||||
to_free->in_use = false;
|
||||
remove_used(to_free);
|
||||
if (to_free->prev && !to_free->prev->in_use) {
|
||||
to_merge = to_free;
|
||||
to_free = merge_blocks(to_free->prev, to_free);
|
||||
}
|
||||
if (to_free->next && !to_free->next->in_use) {
|
||||
to_merge = to_free->next;
|
||||
to_free = merge_blocks(to_free, to_free->next);
|
||||
}
|
||||
int err = add_available(to_free, to_merge);
|
||||
if (err)
|
||||
kprintf(KERN_ERR "kfree: fatal error\n");
|
||||
}
|
162
src/memory/phys/kmalloc.c
Normal file
162
src/memory/phys/kmalloc.c
Normal file
@ -0,0 +1,162 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "kprintf.h"
|
||||
#include "terminal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Find first available (not in_use) block
|
||||
* in a zone matching the size we need
|
||||
*/
|
||||
static Block *find_block(Zone *head, uint32_t size)
|
||||
{
|
||||
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
|
||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||
block_it = block_it->next_free) {
|
||||
assert(block_it);
|
||||
assert(!block_it->in_use);
|
||||
if (size <= block_it->size) {
|
||||
assert(block_it->zone == zone_it);
|
||||
return (block_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// PARTIALLY DEPRECATED
|
||||
/*
|
||||
* This will split the newly allocated block to use
|
||||
* the remaining bytes for a new block
|
||||
* This is our linked list of blocks
|
||||
* ... -> [5] -> [6] -> ...
|
||||
* After the allocation, this will become
|
||||
* ... -> [5] -> [new] -> [6] -> ...
|
||||
*
|
||||
* For an example of [5].size = 32 and requiring a kmalloc of 10
|
||||
* Let's say the metadata takes a size of 2:
|
||||
* ... -> [metadata][data][remaining size] -> [6]
|
||||
* ^ ^ ^
|
||||
* 2 10 20
|
||||
*
|
||||
* So now our block [new] will become:
|
||||
* [5] -> [metadata][available data] -> [6]
|
||||
* ^ ^
|
||||
* 2 18
|
||||
* We can see that it now has its own metadata and available
|
||||
* data and it points towards [6]
|
||||
*/
|
||||
static void frag_block(Zone *zone, Block *old_block, uint32_t size)
|
||||
{
|
||||
Block *new_block = (Block *)align_mem((uint32_t)old_block + size);
|
||||
assert(new_block <
|
||||
(Block *)((uint32_t)zone + get_zone_size(zone->type)));
|
||||
|
||||
if (old_block->size - align_mem(size) < sizeof(Block)) {
|
||||
zone->free = NULL;
|
||||
goto last_block;
|
||||
}
|
||||
|
||||
// Newly created block metadata
|
||||
new_block->size = old_block->size - align_mem(size);
|
||||
new_block->sub_size = new_block->size;
|
||||
new_block->in_use = false;
|
||||
new_block->ptr = (void *)((uint32_t)new_block + sizeof(Block));
|
||||
new_block->zone = zone;
|
||||
|
||||
new_block->prev = old_block;
|
||||
new_block->next = old_block->next;
|
||||
old_block->next = new_block;
|
||||
|
||||
new_block->prev_used = NULL;
|
||||
new_block->next_used = NULL;
|
||||
|
||||
new_block->prev_free = old_block->prev_free;
|
||||
new_block->next_free = NULL;
|
||||
if (new_block != old_block->next_free)
|
||||
new_block->next_free = old_block->next_free;
|
||||
|
||||
if (zone->free == old_block)
|
||||
zone->free = new_block;
|
||||
|
||||
last_block:
|
||||
old_block->next_free = NULL;
|
||||
old_block->prev_free = NULL;
|
||||
|
||||
// Newly in_use block metadata
|
||||
old_block->in_use = true;
|
||||
old_block->size = size - sizeof(Block);
|
||||
old_block->sub_size = old_block->size;
|
||||
|
||||
if (zone->used == NULL) {
|
||||
zone->used = old_block;
|
||||
return;
|
||||
}
|
||||
old_block->prev_used = NULL;
|
||||
old_block->next_used = zone->used;
|
||||
zone->used->prev_used = old_block;
|
||||
zone->used = old_block;
|
||||
}
|
||||
|
||||
// Set the block to used and unset free
|
||||
static void save_block(Zone *head, Block *block, Zone *zone)
|
||||
{
|
||||
zone->free = NULL;
|
||||
block->in_use = true;
|
||||
if (head->used) {
|
||||
head->used->prev_used = block;
|
||||
head->used->prev = block;
|
||||
block->next = head->used;
|
||||
block->next_used = head->used;
|
||||
}
|
||||
head->used = block;
|
||||
}
|
||||
|
||||
/*
|
||||
* size: size needed by the user to get allocated
|
||||
*
|
||||
* First, we init the allocator if it's the first time
|
||||
* Then we search if there is an available block in all
|
||||
* the zones currently mapped
|
||||
* If no block has been found (NULL), we create 1 new zone of
|
||||
* the corresponding type
|
||||
* We then search again for an available block (should not be NULL)
|
||||
* Finally, if type == LARGE, we just have to change the block to used
|
||||
* else, we frag the block to use just what's needed
|
||||
*
|
||||
* ptr: returns the aligned pointer of the block (after the metadata)
|
||||
*/
|
||||
void *kmalloc(uint32_t size)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
kprintf(KERN_WARNING "kmalloc: can't kmalloc(0)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find the zone we need to search
|
||||
block_type_t type = get_type(size);
|
||||
Zone *head = kzones[type];
|
||||
|
||||
// Find an available block in a zone of type "type"
|
||||
Block *available = find_block(head, size);
|
||||
if (available == NULL) {
|
||||
uint32_t full_size;
|
||||
if (type == LARGE)
|
||||
full_size = size + sizeof(Block) + sizeof(Zone);
|
||||
else
|
||||
full_size = get_zone_size(type);
|
||||
if (new_kzone(type, full_size) == -1)
|
||||
return NULL;
|
||||
head = kzones[type];
|
||||
available = find_block(head, size);
|
||||
}
|
||||
assert(available != NULL);
|
||||
if (type == LARGE)
|
||||
save_block(head, available, available->zone);
|
||||
else
|
||||
frag_block(available->zone, available, size + sizeof(Block));
|
||||
ptr = available->ptr;
|
||||
return ptr;
|
||||
}
|
37
src/memory/phys/krealloc.c
Normal file
37
src/memory/phys/krealloc.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "alloc.h"
|
||||
#include "string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// Prototype for kfree and kmalloc
|
||||
void kfree(void *ptr);
|
||||
void *kmalloc(uint32_t size);
|
||||
|
||||
/*
|
||||
* ptr: block to resize (undefined behavior if invalid)
|
||||
* size: size needed by the user to get kreallocated
|
||||
*
|
||||
* If we have a size <= to the previous size, we don't have
|
||||
* to do anything, we just change sub_size for info purposes
|
||||
* and return the same pointer
|
||||
* Else, we allocate a new block and copy the content of
|
||||
* the previous block in the new one and kfree the old block
|
||||
*
|
||||
* ptr: returns the aligned pointer of the kreallocated block
|
||||
*/
|
||||
void *krealloc(void *ptr, uint32_t size)
|
||||
{
|
||||
void *new_ptr = NULL;
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
Block *block = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||
if (block->size >= size) {
|
||||
block->sub_size = size;
|
||||
return (ptr);
|
||||
}
|
||||
new_ptr = kmalloc(size);
|
||||
if (new_ptr == NULL)
|
||||
return NULL;
|
||||
memmove(new_ptr, ptr, block->size);
|
||||
kfree(ptr);
|
||||
return (new_ptr);
|
||||
}
|
9
src/memory/phys/ksize.c
Normal file
9
src/memory/phys/ksize.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "alloc.h"
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t ksize(void *ptr)
|
||||
{
|
||||
Block *meta_data = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||
|
||||
return meta_data->sub_size;
|
||||
}
|
34
src/memory/utils.c
Normal file
34
src/memory/utils.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "alloc.h"
|
||||
#include "memory.h"
|
||||
|
||||
static size_t get_block_size(block_type_t type)
|
||||
{
|
||||
if (type == TINY)
|
||||
return ((PAGES_TINY * PAGE_SIZE) / BPZ - sizeof(Block));
|
||||
if (type == SMALL)
|
||||
return ((PAGES_SMALL * PAGE_SIZE) / BPZ - sizeof(Block));
|
||||
return (0);
|
||||
}
|
||||
|
||||
block_type_t get_type(size_t size)
|
||||
{
|
||||
if (size <= get_block_size(TINY))
|
||||
return (TINY);
|
||||
if (size <= get_block_size(SMALL))
|
||||
return (SMALL);
|
||||
return (LARGE);
|
||||
}
|
||||
|
||||
size_t get_zone_size(block_type_t type)
|
||||
{
|
||||
if (type == TINY)
|
||||
return (PAGES_TINY * PAGE_SIZE);
|
||||
if (type == SMALL)
|
||||
return (PAGES_SMALL * PAGE_SIZE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
size_t align_mem(size_t addr)
|
||||
{
|
||||
return (addr + (MEM_ALIGN - 1)) & ~(MEM_ALIGN - 1);
|
||||
}
|
70
src/memory/virt/allocator.c
Normal file
70
src/memory/virt/allocator.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "task.h"
|
||||
|
||||
Zone *vzones[3];
|
||||
|
||||
static void add_zone(Zone *zone, block_type_t type)
|
||||
{
|
||||
// We put the zone at the beginning of the list
|
||||
if (vzones[type]) {
|
||||
assert(vzones[type] != zone);
|
||||
zone->next = vzones[type];
|
||||
vzones[type]->prev = zone;
|
||||
}
|
||||
vzones[type] = zone;
|
||||
}
|
||||
|
||||
static void new_block(Zone *zone, uint32_t zone_size)
|
||||
{
|
||||
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
|
||||
|
||||
// Metadata
|
||||
new_block->in_use = false;
|
||||
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
||||
new_block->sub_size = new_block->size;
|
||||
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
|
||||
new_block->zone = zone;
|
||||
|
||||
// Init future linked lists
|
||||
new_block->prev = NULL;
|
||||
new_block->prev_free = NULL;
|
||||
new_block->prev_used = NULL;
|
||||
new_block->next = NULL;
|
||||
new_block->next_free = NULL;
|
||||
new_block->next_used = NULL;
|
||||
|
||||
if (zone->free) {
|
||||
zone->free->prev = new_block;
|
||||
zone->free->prev_free = new_block;
|
||||
new_block->next = zone->free;
|
||||
new_block->next_free = zone->free;
|
||||
}
|
||||
zone->free = new_block;
|
||||
assert(zone->free == new_block);
|
||||
}
|
||||
|
||||
int new_vzone(block_type_t type, uint32_t size)
|
||||
{
|
||||
// assert(current_task->pid);
|
||||
void *heap = alloc_pages(size, NULL);
|
||||
if (heap == NULL) {
|
||||
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
Zone *zone = (Zone *)heap;
|
||||
zone->type = type;
|
||||
zone->size = size;
|
||||
zone->used = NULL;
|
||||
zone->next = NULL;
|
||||
zone->prev = NULL;
|
||||
|
||||
new_block(zone, size);
|
||||
add_zone(heap, type);
|
||||
|
||||
return (0);
|
||||
}
|
52
src/memory/virt/info.c
Normal file
52
src/memory/virt/info.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "alloc.h"
|
||||
#include "kprintf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// FULL_INFO is to display (or not) both used and unused blocks
|
||||
#define FULL_INFO 1
|
||||
|
||||
void show_valloc_mem(void)
|
||||
{
|
||||
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||
uint32_t total_size = 0;
|
||||
|
||||
for (block_type_t type = 0; type < 3; ++type) {
|
||||
int count = 0;
|
||||
for (Zone *zone_it = vzones[type]; zone_it != NULL;
|
||||
zone_it = zone_it->next) {
|
||||
if (zone_it->used)
|
||||
kprintf("---------- IN_USE %s [n°%d - %p] "
|
||||
"----------\n",
|
||||
zones_name[type], count, zone_it);
|
||||
for (Block *block_it = zone_it->used; block_it != NULL;
|
||||
block_it = block_it->next_used) {
|
||||
/* i++; */
|
||||
/* if (i < 10) */
|
||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||
(uint32_t)block_it->ptr +
|
||||
block_it->sub_size + sizeof(Block),
|
||||
block_it->sub_size);
|
||||
total_size += block_it->sub_size;
|
||||
}
|
||||
if (zone_it->used)
|
||||
kprintf("\n");
|
||||
count++;
|
||||
#if FULL_INFO
|
||||
if (zone_it->free)
|
||||
kprintf("---------- AVAILABLE %s [n°%d - %p] "
|
||||
"----------\n",
|
||||
zones_name[type], count, zone_it);
|
||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||
block_it = block_it->next_free) {
|
||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||
(uint32_t)block_it->ptr +
|
||||
block_it->sub_size + sizeof(Block),
|
||||
block_it->sub_size);
|
||||
}
|
||||
if (zone_it->free)
|
||||
kprintf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
kprintf("Total: %u\n", total_size);
|
||||
}
|
116
src/memory/virt/vfree.c
Normal file
116
src/memory/virt/vfree.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "alloc.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static void remove_used(Block *to_free)
|
||||
{
|
||||
Block *left = to_free->prev_used;
|
||||
Block *right = to_free->next_used;
|
||||
|
||||
to_free->next_used = NULL;
|
||||
to_free->prev_used = NULL;
|
||||
|
||||
if (!left && !right) {
|
||||
to_free->zone->used = NULL;
|
||||
return;
|
||||
}
|
||||
if (!left)
|
||||
to_free->zone->used = right;
|
||||
else
|
||||
left->next_used = right;
|
||||
if (right)
|
||||
right->prev_used = left;
|
||||
}
|
||||
|
||||
/*
|
||||
* If all the blocks of the zone have been kfreed,
|
||||
* we can unmap the zone and delete it from the list of zones
|
||||
*/
|
||||
static int unmap_zone(Zone *zone)
|
||||
{
|
||||
int err = 0;
|
||||
block_type_t type = zone->type;
|
||||
Zone *left = zone->prev;
|
||||
Zone *right = zone->next;
|
||||
zone->prev = NULL;
|
||||
zone->next = NULL;
|
||||
|
||||
if (!left && !right) {
|
||||
vzones[type] = NULL;
|
||||
goto unmap;
|
||||
}
|
||||
if (!left)
|
||||
vzones[type] = right;
|
||||
else
|
||||
left->next = right;
|
||||
if (right)
|
||||
right->prev = left;
|
||||
unmap:
|
||||
err = free_pages((void *)zone, zone->size);
|
||||
if (err)
|
||||
kprintf(KERN_ERR "error: munmap failed\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the newly kfreed block is next to another previously
|
||||
* kfreed block, merge both of these and update the size
|
||||
*/
|
||||
static Block *merge_blocks(Block *left, Block *right)
|
||||
{
|
||||
if (right->next)
|
||||
right->next->prev = left;
|
||||
if (right->next_free) {
|
||||
right->next_free->prev_free = left;
|
||||
left->next_free = right->next_free;
|
||||
}
|
||||
left->next = right->next;
|
||||
left->size += right->size + sizeof(Block);
|
||||
return (left);
|
||||
}
|
||||
|
||||
// Simply add the new block to the list of available blocks
|
||||
static int add_available(Block *available, Block *merged)
|
||||
{
|
||||
Zone *zone = available->zone;
|
||||
if (merged != zone->free && available != zone->free)
|
||||
available->next_free = zone->free;
|
||||
if (zone->free)
|
||||
zone->free->prev_free = available;
|
||||
zone->free = available;
|
||||
if (zone->type == LARGE)
|
||||
return (unmap_zone(zone));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ptr: pointer to kfree, if the pointer is invalid the kfree()
|
||||
* function will have an undefined behavior (most likely segfault)
|
||||
*
|
||||
* First, we remove the block from the list of in_use blocks
|
||||
* Then, we check if the block needs to be merged with another
|
||||
* neighboring block, if so we replace the previous block by the
|
||||
* newly merged block
|
||||
* Finally, we add the block to the list of available blocks
|
||||
*/
|
||||
void vfree(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||
Block *to_merge = NULL;
|
||||
to_free->in_use = false;
|
||||
remove_used(to_free);
|
||||
if (to_free->prev && !to_free->prev->in_use) {
|
||||
to_merge = to_free;
|
||||
to_free = merge_blocks(to_free->prev, to_free);
|
||||
}
|
||||
if (to_free->next && !to_free->next->in_use) {
|
||||
to_merge = to_free->next;
|
||||
to_free = merge_blocks(to_free, to_free->next);
|
||||
}
|
||||
int err = add_available(to_free, to_merge);
|
||||
if (err)
|
||||
kprintf(KERN_ERR "kfree: fatal error\n");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user