From bd7d4366b6643b5c6cd04f40dd32f5d9c9575fd6 Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Fri, 5 Aug 2022 14:33:51 +0200 Subject: organised files; switched to recursive make --- kernel/Makefile | 37 +++++ kernel/boot.S | 181 --------------------- kernel/boot64.S | 19 --- kernel/debug.c | 6 - kernel/graphics.c | 119 -------------- kernel/grub.cfg | 8 - kernel/header.S | 40 ----- kernel/idt.c | 88 ---------- kernel/include/debug.h | 8 + kernel/include/font.h | 369 ++++++++++++++++++++++++++++++++++++++++++ kernel/include/graphics.h | 34 ++++ kernel/include/idt.h | 34 ++++ kernel/include/io.h | 9 ++ kernel/include/irq.h | 58 +++++++ kernel/include/keyboard.h | 9 ++ kernel/include/multiboot2.h | 40 +++++ kernel/include/pic.h | 30 ++++ kernel/io.c | 13 -- kernel/irq.c | 289 --------------------------------- kernel/irq_stub.S | 108 ------------- kernel/kernel.ld | 39 ----- kernel/keyboard.c | 20 --- kernel/main.c | 18 --- kernel/multiboot2.c | 41 ----- kernel/pic.c | 24 --- kernel/src/boot/boot.S | 181 +++++++++++++++++++++ kernel/src/boot/boot64.S | 19 +++ kernel/src/boot/header.S | 40 +++++ kernel/src/boot/multiboot2.c | 41 +++++ kernel/src/cpu/idt.c | 88 ++++++++++ kernel/src/cpu/io.c | 13 ++ kernel/src/cpu/irq.c | 289 +++++++++++++++++++++++++++++++++ kernel/src/cpu/irq_stub.S | 108 +++++++++++++ kernel/src/cpu/pic.c | 24 +++ kernel/src/devices/keyboard.c | 20 +++ kernel/src/grub.cfg | 8 + kernel/src/kernel.ld | 39 +++++ kernel/src/main.c | 18 +++ kernel/src/misc/debug.c | 6 + kernel/src/misc/graphics.c | 119 ++++++++++++++ 40 files changed, 1641 insertions(+), 1013 deletions(-) create mode 100644 kernel/Makefile delete mode 100644 kernel/boot.S delete mode 100644 kernel/boot64.S delete mode 100644 kernel/debug.c delete mode 100644 kernel/graphics.c delete mode 100644 kernel/grub.cfg delete mode 100644 kernel/header.S delete mode 100644 kernel/idt.c create mode 100644 kernel/include/debug.h create mode 100644 kernel/include/font.h create mode 100644 kernel/include/graphics.h create mode 100644 kernel/include/idt.h create mode 100644 kernel/include/io.h create mode 100644 kernel/include/irq.h create mode 100644 kernel/include/keyboard.h create mode 100644 kernel/include/multiboot2.h create mode 100644 kernel/include/pic.h delete mode 100644 kernel/io.c delete mode 100644 kernel/irq.c delete mode 100644 kernel/irq_stub.S delete mode 100644 kernel/kernel.ld delete mode 100644 kernel/keyboard.c delete mode 100644 kernel/main.c delete mode 100644 kernel/multiboot2.c delete mode 100644 kernel/pic.c create mode 100644 kernel/src/boot/boot.S create mode 100644 kernel/src/boot/boot64.S create mode 100644 kernel/src/boot/header.S create mode 100644 kernel/src/boot/multiboot2.c create mode 100644 kernel/src/cpu/idt.c create mode 100644 kernel/src/cpu/io.c create mode 100644 kernel/src/cpu/irq.c create mode 100644 kernel/src/cpu/irq_stub.S create mode 100644 kernel/src/cpu/pic.c create mode 100644 kernel/src/devices/keyboard.c create mode 100644 kernel/src/grub.cfg create mode 100644 kernel/src/kernel.ld create mode 100644 kernel/src/main.c create mode 100644 kernel/src/misc/debug.c create mode 100644 kernel/src/misc/graphics.c (limited to 'kernel') diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..8bdb9f7 --- /dev/null +++ b/kernel/Makefile @@ -0,0 +1,37 @@ +CFLAGS += -I include + +OBJS = \ + src/boot/boot64.o \ + src/boot/boot.o \ + src/boot/header.o \ + src/boot/multiboot2.o \ + src/cpu/idt.o \ + src/cpu/io.o \ + src/cpu/irq.o \ + src/cpu/irq_stub.o \ + src/cpu/pic.o \ + src/devices/keyboard.o \ + src/main.o \ + src/misc/debug.o \ + src/misc/graphics.o \ + +all: kernel.bin + +kernel.bin: $(OBJS) src/kernel.ld ../Makefile Makefile + $(info [kernel] $@) + @$(LD) $(LDFLAGS) -T src/kernel.ld $(OBJS) -o kernel.bin + + +%.o: %.c + $(info [kernel] $@) + @$(CC) $(CFLAGS) -c $< -o $@ + + +%.o: %.S + $(info [kernel] $@) + @$(CC) $(CFLAGS) -c $< -o $@ + + +.PHONY: all + +-include $(OBJS:.o=.d) diff --git a/kernel/boot.S b/kernel/boot.S deleted file mode 100644 index ee35eeb..0000000 --- a/kernel/boot.S +++ /dev/null @@ -1,181 +0,0 @@ -.global _start -.extern begin_long_mode - -.section .text -.code32 - -_start: - cli - mov $stack_top, %esp - pushl $0 - pushl %eax - pushl $0 - pushl %ebx - - call check_multiboot - call check_cpuid - call check_long_mode - - call setup_page_tables - call enable_paging - - lgdt gdt_pointer - ljmp $0x08, $begin_long_mode - - -check_multiboot: - cmp $0x36d76289, %eax - jne no_multiboot - - ret - -check_cpuid: - pushfl - pop %eax - mov %eax, %ecx - xor $1<<21, %eax - push %eax - popfl - pushfl - pop %eax - push %ecx - popfl - cmp %eax, %ecx - je no_cpuid - - ret - -check_long_mode: - mov $0x80000000, %eax - cpuid - cmp $0x80000001, %eax - jb no_long_mode - - mov $0x80000001, %eax - cpuid - test $1<<29, %edx - jz no_long_mode - - ret - -setup_page_tables: - mov $page_table_lvl3, %eax - or $0x3, %eax - mov %eax, page_table_lvl4 - - mov $page_table_lvl2, %eax - or $0x3, %eax - mov %eax, page_table_lvl3 - - mov $page_table_lvl2 + 4096, %eax - or $0x3, %eax - mov %eax, page_table_lvl3+8 - - mov $page_table_lvl2 + 8192, %eax - or $0x3, %eax - mov %eax, page_table_lvl3+16 - - mov $page_table_lvl2 + 12288, %eax - or $0x3, %eax - mov %eax, page_table_lvl3+24 - - - movl $0, %ecx -1: - movl $0x200000, %eax - mul %ecx - or $0b10000011, %eax - movl $page_table_lvl2, %edx - leal (%edx, %ecx, 8), %edx - movl %eax, (%edx) - inc %ecx - cmp $512*4, %ecx - jne 1b - - ret - -enable_paging: - // enable PAE - mov %cr4, %edx - or $1<<5 ,%edx - mov %edx, %cr4 - - // set LME (long mode enable) - mov $0xC0000080, %ecx - rdmsr - or $1<<8, %eax - wrmsr - - // page_table_lvl4 - mov $page_table_lvl4, %eax - mov %eax, %cr3 - - // enable paging (+ protected mode if not already enabled) - mov %cr0, %eax - or $1<<31 + 1<<0, %eax - mov %eax, %cr0 - - ret - -no_multiboot: - hlt - -no_cpuid: - hlt - -no_long_mode: - hlt - - -.section .bss -.align 4096 - -// stack -stack_bottom: - .skip 4096*4 -stack_top: - -// page tables -page_table_lvl4: - .skip 4096 -page_table_lvl3: - .skip 4096 -// map first 4GB -page_table_lvl2: - .skip 4096*4 - -// Access bits -.section .rodata -.set PRESENT, 1 << 7 -.set NOT_SYS, 1 << 4 -.set EXEC, 1 << 3 -.set DC, 1 << 2 -.set RW, 1 << 1 -.set ACCESSED, 1 << 0 - -// Flags bits -.set GRAN_4K, 1 << 7 -.set SZ_32, 1 << 6 -.set LONG_MODE, 1 << 5 - -gdt: -gdt_null = . - gdt - .quad 0 -gdt_code = . - gdt - .long 0xFFFF // Limit & Base (low, bits 0-15) - .byte 0 // Base (mid, bits 16-23) - .byte PRESENT | NOT_SYS | EXEC | RW // Access - .byte GRAN_4K | LONG_MODE | 0xF // Flags & Limit (high, bits 16-19) - .byte 0 // Base (high, bits 24-31) -gdt_data = . - gdt - .long 0xFFFF - .byte 0 - .byte PRESENT | NOT_SYS | RW - .byte GRAN_4K | SZ_32 | 0xF - .byte 0 -gdt_tss = . - gdt - .long 0x00000068 - .long 0x00CF8900 -gdt_pointer: - .word . - gdt - 1 - .quad gdt diff --git a/kernel/boot64.S b/kernel/boot64.S deleted file mode 100644 index be87412..0000000 --- a/kernel/boot64.S +++ /dev/null @@ -1,19 +0,0 @@ -.global begin_long_mode - -.section .text -.code64 - -begin_long_mode: - // reload segment registers - mov $0x10, %eax - mov %eax, %ss - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - - popq %rdi - popq %rsi - - call kernel_main - hlt diff --git a/kernel/debug.c b/kernel/debug.c deleted file mode 100644 index 5f3c327..0000000 --- a/kernel/debug.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void bochs_breakpoint(void) -{ - __asm__ volatile ("xchgw %bx, %bx;"); -} diff --git a/kernel/graphics.c b/kernel/graphics.c deleted file mode 100644 index d4fc7c7..0000000 --- a/kernel/graphics.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include - -uint64_t* pixel_offset(fb_t fb, uint32_t x, uint32_t y) -{ - return (uint64_t*)((char*)fb.addr + y * fb.pitch + x * fb.bpp / 8); -} - -void fb_draw_pixel(fb_t fb, uint32_t x, uint32_t y, uint32_t col) -{ - if (x >= fb.width || y >= fb.height) return; - - uint32_t* fb_offset = (uint32_t*)pixel_offset(fb, x, y); - *fb_offset = col; -} - -/* https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm */ - -void fb_draw_line_low(fb_t fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t col) -{ - int32_t dx = x1 - x0; - int32_t dy = y1 - y0; - int32_t yi = 1; - if (dy < 0) { - yi = -1; - dy = -dy; - } - int32_t D = (2 * dy) - dx; - int32_t y = y0; - - for (int32_t x = x0; x <= x1; x++) { - fb_draw_pixel(fb, x, y, col); - if (D > 0) { - y = y + yi; - D = D + (2 * (dy - dx)); - } else { - D = D + 2 * dy; - } - } - -} - -void fb_draw_line_high(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) -{ - int32_t dx = x1 - x0; - int32_t dy = y1 - y0; - int32_t xi = 1; - if (dx < 0) { - xi = -1; - dx = -dx; - } - int32_t D = (2 * dx) - dy; - int32_t x = x0; - - for (int32_t y = y0; y <= y1; y++) { - fb_draw_pixel(fb, x, y, col); - if (D > 0) { - x = x + xi; - D = D + (2 * (dx - dy)); - } else { - D = D + 2 * dx; - } - } -} - -int32_t abs(int32_t val) -{ - if (val < 0) return -val; - return val; -} - -void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) -{ - if (abs(y1 - y0) < abs(x1 - x0)) { - if (x0 > x1) - fb_draw_line_low(fb, x1, y1, x0, y0, col); - else - fb_draw_line_low(fb, x0, y0, x1, y1, col); - } else { - if (y0 > y1) - fb_draw_line_high(fb, x1, y1, x0, y0, col); - else - fb_draw_line_high(fb, x0, y0, x1, y1, col); - } -} - -void fb_draw_character(fb_t fb, char c, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col) -{ - if (c < 0) return; - - uint32_t offset = 32 + c * 16; - for (uint32_t i = 0 ; i < 16; i++) - { - for (uint32_t j = 0 ; j < 8; j++) - { - if (font[offset + i] & (1 << (7 - j))) { - fb_draw_pixel(fb, x + j, y + i, char_col); - } else { - fb_draw_pixel(fb, x + j, y + i, bg_col); - } - } - } -} - -uint32_t strlen(const char* s) -{ - char *p = (char*)s; - while (*p) p++; - return p - s; -} - -void fb_draw_string(fb_t fb, const char* s, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col) -{ - for (uint32_t i = 0; i < strlen(s); i++) { - fb_draw_character(fb, s[i], x + i * 8, y, char_col, bg_col); - } -} diff --git a/kernel/grub.cfg b/kernel/grub.cfg deleted file mode 100644 index 05a13f7..0000000 --- a/kernel/grub.cfg +++ /dev/null @@ -1,8 +0,0 @@ -set timeout=0 -set default=0 - -insmod efi_gop -menuentry "mykernel64" { - multiboot2 /boot/kernel.bin - boot -} diff --git a/kernel/header.S b/kernel/header.S deleted file mode 100644 index bbcb9be..0000000 --- a/kernel/header.S +++ /dev/null @@ -1,40 +0,0 @@ -// multiboot tags -.set TAG_END, 0 -.set TAG_FRAMEBUFFER, 5 - -// multiboot flags -.set TAG_REQUIRED, 0 -.set TAG_OPTIONAL, 1 - -# multiboot2 header constants -.set MAGIC, 0xe85250d6 -.set ARCH, 0 -.set HEADER_LENGTH, (header_end - header_start) -.set CHECKSUM, 0x100000000 - (MAGIC + ARCH + HEADER_LENGTH) - -.section .multiboot_header, "a" -.align 4 -header_start: - # magic - .align 8 - .long MAGIC - .long ARCH - .long HEADER_LENGTH - .long CHECKSUM - - # framebuffer - .align 8 - .word TAG_FRAMEBUFFER - .word TAG_REQUIRED - .long 20 - .long 1024 - .long 768 - .long 32 - - # end tag - .align 8 - .word TAG_END - .word TAG_REQUIRED - .long 8 - -header_end: diff --git a/kernel/idt.c b/kernel/idt.c deleted file mode 100644 index bf285b7..0000000 --- a/kernel/idt.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include - -__attribute__((aligned(0x10))) static idt_entry idt_table[256]; -idtp idt_pointer; - -void load_idt(idtp* pointer) -{ - __asm__ volatile ("lidt (%0); sti;" : : "r"(pointer) : ); -} - -void add_to_idt(uint16_t num, uint64_t offset, uint16_t selector, uint8_t type) -{ - idt_table[num].offset_1 = offset & 0xFFFF; - idt_table[num].offset_2 = (offset >> 16) & 0xFFFF; - idt_table[num].offset_3 = offset >> 32; - idt_table[num].selector = selector; - idt_table[num].type_attributes = type; - idt_table[num].ist = 0; - idt_table[num].zero = 0; -} - -void init_idt_table(void) -{ - // exceptions - add_to_idt(0, (uint64_t)isr0, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(1, (uint64_t)isr1, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(2, (uint64_t)isr2, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(3, (uint64_t)isr3, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(4, (uint64_t)isr4, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(5, (uint64_t)isr5, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(6, (uint64_t)isr6, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(7, (uint64_t)isr7, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(8, (uint64_t)isr8, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(9, (uint64_t)isr9, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(10, (uint64_t)isr10, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(11, (uint64_t)isr11, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(12, (uint64_t)isr12, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(13, (uint64_t)isr13, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(14, (uint64_t)isr14, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(15, (uint64_t)isr15, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(16, (uint64_t)isr16, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(17, (uint64_t)isr17, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(18, (uint64_t)isr18, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(19, (uint64_t)isr19, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(20, (uint64_t)isr20, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(21, (uint64_t)isr21, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(22, (uint64_t)isr22, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(23, (uint64_t)isr23, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(24, (uint64_t)isr24, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(25, (uint64_t)isr25, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(26, (uint64_t)isr26, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(27, (uint64_t)isr27, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(28, (uint64_t)isr28, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(29, (uint64_t)isr29, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(30, (uint64_t)isr30, GDT_CODE_SEG, TRAP_GATE); - add_to_idt(31, (uint64_t)isr31, GDT_CODE_SEG, TRAP_GATE); - - // interrupts - add_to_idt(32, (uint64_t)irq0, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(33, (uint64_t)irq1, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(34, (uint64_t)irq2, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(35, (uint64_t)irq3, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(36, (uint64_t)irq4, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(37, (uint64_t)irq5, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(38, (uint64_t)irq6, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(39, (uint64_t)irq7, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(40, (uint64_t)irq8, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(41, (uint64_t)irq9, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(42, (uint64_t)irq10, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(43, (uint64_t)irq11, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(44, (uint64_t)irq12, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(45, (uint64_t)irq13, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(46, (uint64_t)irq14, GDT_CODE_SEG, INTERRUPT_GATE); - add_to_idt(47, (uint64_t)irq15, GDT_CODE_SEG, INTERRUPT_GATE); -} - -void init_idt() -{ - init_idt_table(); - idt_pointer.size = sizeof(idt_entry) * 256 - 1; - idt_pointer.offset = (uint64_t)&idt_table; - - remap_pic(); - - load_idt(&idt_pointer); -} diff --git a/kernel/include/debug.h b/kernel/include/debug.h new file mode 100644 index 0000000..ebe3a52 --- /dev/null +++ b/kernel/include/debug.h @@ -0,0 +1,8 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include + +void bochs_breakpoint(void); + +#endif diff --git a/kernel/include/font.h b/kernel/include/font.h new file mode 100644 index 0000000..678a6c2 --- /dev/null +++ b/kernel/include/font.h @@ -0,0 +1,369 @@ +#ifndef FONT_H +#define FONT_H + +#include + +#define PSF_FONT_MAGIC 0x864ab572 + +typedef struct { + uint32_t magic; /* magic bytes to identify PSF */ + uint32_t version; /* zero */ + uint32_t headersize; /* offset of bitmaps in file, 32 */ + uint32_t flags; /* 0 if there's no unicode table */ + uint32_t numglyph; /* number of glyphs */ + uint32_t bytesperglyph; /* size of each glyph */ + uint32_t height; /* height in pixels */ + uint32_t width; /* width in pixels */ +} PSF_font; + +/* font i used: /usr/share/kbd/consolefonts/lat9-16.psf.gz */ +/* xxd -i font.psf */ + +#endif +unsigned char font[] = { + 0x72, 0xb5, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc3, + 0x99, 0x99, 0xf3, 0xe7, 0xe7, 0xff, 0xe7, 0xe7, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xf8, 0xd8, 0xd8, 0xdc, 0xd8, + 0xd8, 0xd8, 0xf8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6e, 0xdb, 0xdb, 0xdf, 0xd8, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x00, 0x3e, + 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xe0, + 0x80, 0x80, 0x00, 0x3e, 0x20, 0x38, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x88, 0x80, 0x88, 0x70, 0x00, 0x3c, 0x22, 0x3c, 0x24, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x00, 0x3e, + 0x20, 0x38, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x88, 0xc8, 0xa8, 0x98, 0x88, 0x00, 0x20, + 0x20, 0x20, 0x20, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x50, + 0x50, 0x20, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, + 0xe0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x0c, 0xfe, 0x18, 0x30, 0xfe, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x1e, 0x7e, 0xfe, 0x7e, 0x1e, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xfe, + 0xfc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, + 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, + 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, + 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, + 0xd6, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, + 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, + 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, + 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, + 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, + 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, + 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, + 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, + 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, + 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x64, 0x38, 0x0c, + 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, + 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, + 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, + 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x30, 0x30, 0x30, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, + 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, + 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, + 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, + 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, + 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, + 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, + 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, + 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, + 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, + 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x60, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6f, 0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x60, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x60, 0x6f, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0xec, 0x0c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0xef, 0x00, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x7c, 0xd6, 0xd0, 0xd0, 0xd0, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0xf0, 0x60, 0x60, 0x66, 0xf6, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x32, 0x60, 0x60, 0xfc, 0x60, 0xfc, + 0x60, 0x60, 0x32, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, + 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, + 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, + 0xb9, 0xa5, 0xb9, 0xa5, 0xa5, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x18, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x18, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x00, 0xfe, + 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, + 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xd6, 0xd6, 0x76, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6c, 0x38, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xcc, 0xcc, 0xcc, 0xcf, 0xcf, + 0xcc, 0xcc, 0xcc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6e, 0xdb, 0xdb, 0xdf, 0xd8, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, + 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x60, 0x30, 0x00, 0x38, + 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x38, + 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x78, + 0xd8, 0xd8, 0xfc, 0xd8, 0xd8, 0xd8, 0xd8, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, + 0x0c, 0x66, 0x3c, 0x00, 0x60, 0x30, 0x00, 0xfe, 0x66, 0x60, 0x60, 0x7c, + 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, + 0x66, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0xfe, 0x66, 0x60, 0x60, 0x7c, + 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x3c, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x0c, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x3c, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, + 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x18, + 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc6, + 0xce, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, + 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xcc, 0xc6, 0xc6, 0xc6, 0xd6, 0xdc, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0x1b, + 0x7f, 0xd8, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x6c, 0x38, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x78, + 0x0c, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xce, 0xde, + 0xfe, 0xf6, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, + 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, + 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, + 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, + 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00 +}; +unsigned int font_len = 4128; diff --git a/kernel/include/graphics.h b/kernel/include/graphics.h new file mode 100644 index 0000000..84505d8 --- /dev/null +++ b/kernel/include/graphics.h @@ -0,0 +1,34 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include + +struct fb_t { + uint64_t addr; + uint32_t pitch; + uint32_t width; + uint32_t height; + uint8_t bpp; + uint8_t type; +} __attribute__((packed, aligned(8))); +typedef struct fb_t fb_t; + +extern fb_t fb; + +#define RED 0x00ff0000 +#define GREEN 0x0000ff00 +#define BLUE 0x000000ff +#define YELLOW 0x00ffff00 +#define PURPLE 0x00ff00ff +#define WHITE 0x00ffffff +#define BLACK 0x00000000 + +uint64_t* pixel_offset(fb_t fb, uint32_t x, uint32_t y); +void fb_draw_pixel(fb_t fb, uint32_t x, uint32_t y, uint32_t col); +void fb_draw_line_low(fb_t fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t col); +void fb_draw_line_high(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col); +void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col); +void fb_draw_character(fb_t fb, char c, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col); +void fb_draw_string(fb_t fb, const char* str, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col); + +#endif diff --git a/kernel/include/idt.h b/kernel/include/idt.h new file mode 100644 index 0000000..9ca9c3a --- /dev/null +++ b/kernel/include/idt.h @@ -0,0 +1,34 @@ +#ifndef IDT_H +#define IDT_H + +#include + +#define GDT_CODE_SEG 0x08 + +#define INTERRUPT_GATE 0x8E +#define TRAP_GATE 0x8F + +struct idt_entry { + uint16_t offset_1; // offset bits 0..15 + uint16_t selector; // a code segment selector in GDT or LDT + uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. + uint8_t type_attributes; // gate type, dpl, and p fields + uint16_t offset_2; // offset bits 16..31 + uint32_t offset_3; // offset bits 32..63 + uint32_t zero; // reserved +} __attribute__((packed)); +typedef struct idt_entry idt_entry; + +struct idtp { + uint16_t size; + uint64_t offset; +} __attribute__((packed)); +typedef struct idtp idtp; + +void init_idt(void); +void load_idt(idtp* pointer); +void init_idt_table(void); +void add_to_idt(uint16_t num, uint64_t offset, uint16_t selector, uint8_t type); + + +#endif diff --git a/kernel/include/io.h b/kernel/include/io.h new file mode 100644 index 0000000..76c401d --- /dev/null +++ b/kernel/include/io.h @@ -0,0 +1,9 @@ +#ifndef IO_H +#define IO_H + +#include + +uint8_t inb(uint32_t port); +void outb(uint32_t port, uint8_t value); + +#endif diff --git a/kernel/include/irq.h b/kernel/include/irq.h new file mode 100644 index 0000000..f0e38d6 --- /dev/null +++ b/kernel/include/irq.h @@ -0,0 +1,58 @@ +#ifndef IRQ_H +#define IRQ_H + +#include + +// exceptions +void isr0(void); +void isr1(void); +void isr2(void); +void isr3(void); +void isr4(void); +void isr5(void); +void isr6(void); +void isr7(void); +void isr8(uint64_t error); +void isr9(void); +void isr10(uint64_t error); +void isr11(uint64_t error); +void isr12(uint64_t error); +void isr13(uint64_t error); +void isr14(uint64_t error); +void isr15(void); +void isr16(void); +void isr17(uint64_t error); +void isr18(void); +void isr19(void); +void isr20(void); +void isr21(uint64_t error); +void isr22(void); +void isr23(void); +void isr24(void); +void isr25(void); +void isr26(void); +void isr27(void); +void isr28(void); +void isr29(uint64_t error); +void isr30(uint64_t error); +void isr31(void); + +// interrupts +void irq0(void); +void irq1(void); +void irq2(void); +void irq3(void); +void irq4(void); +void irq5(void); +void irq6(void); +void irq7(void); +void irq8(void); +void irq9(void); +void irq10(void); +void irq11(void); +void irq12(void); +void irq13(void); +void irq14(void); +void irq15(void); + +#endif diff --git a/kernel/include/keyboard.h b/kernel/include/keyboard.h new file mode 100644 index 0000000..3a1b7f1 --- /dev/null +++ b/kernel/include/keyboard.h @@ -0,0 +1,9 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + +void keyboard_handler(void); + +#endif diff --git a/kernel/include/multiboot2.h b/kernel/include/multiboot2.h new file mode 100644 index 0000000..f22fd8e --- /dev/null +++ b/kernel/include/multiboot2.h @@ -0,0 +1,40 @@ +#ifndef MULTIBOOT2_H +#define MULTIBOOT2_H + +#include + +struct mb2_tag_header { + uint32_t type; + uint32_t size; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_header mb2_tag_header; + +struct mb2_tag_fb { + uint32_t type; + uint32_t size; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_fb mb2_tag_fb; + +// multiboot2 magic check +#define MB2_MAGIC 0x36D76289 + +// multiboot2 tag +#define MB2_TAG_END 0 +#define MB2_TAG_CMDLINE 1 +#define MB2_TAG_BOOTLOADER 2 +#define MB2_TAG_MODULES 3 +#define MB2_TAG_MEM 4 +#define MB2_TAG_BIOS 5 +#define MB2_TAG_MMAP 6 +#define MB2_TAG_VBE 7 +#define MB2_TAG_FB 8 + +void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic); + +#endif diff --git a/kernel/include/pic.h b/kernel/include/pic.h new file mode 100644 index 0000000..f1f4e44 --- /dev/null +++ b/kernel/include/pic.h @@ -0,0 +1,30 @@ +#ifndef PIC_H +#define PIC_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 PIC_EOI 0x20 /* End-of-interrupt command code */ + +/* reinitialize the PIC controllers, giving them specified vector offsets + rather than 8h and 70h, as configured by default */ + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void remap_pic(void); + +#endif diff --git a/kernel/io.c b/kernel/io.c deleted file mode 100644 index 6bf67d0..0000000 --- a/kernel/io.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -uint8_t inb(uint32_t port) -{ - uint8_t ret; - __asm__ volatile ("inb %%dx, %%al" : "=a"(ret) : "d"(port)); - return ret; -} - -void outb(uint32_t port, uint8_t value) -{ - __asm__ volatile ("outb %%al, %%dx" : : "d"(port), "a"(value)); -} diff --git a/kernel/irq.c b/kernel/irq.c deleted file mode 100644 index 1e02f23..0000000 --- a/kernel/irq.c +++ /dev/null @@ -1,289 +0,0 @@ -#include -#include -#include -#include -#include - -char* exception_name[] = { - "Divide-by-zero Error", - "Debug", - "Non-maskable Interrupt", - "Breakpoint", - "Overflow", - "Bound Range Exceeded", - "Invalid Opcode", - "Device Not Available", - "Double Fault", - "Coprocessor Segment Overrun", - "Invalid TSS", - "Segment Not Present", - "Stack-Segment Fault", - "General Protection Fault", - "Page Fault", - "Reserved", - "x87 Floating-Point Exception", - "Alignment Check", - "Machine Check", - "SIMD Floating-Point Exception", - "Virtualization Exception", - "Control Protection Exception", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Hypervisor Injection Exception", - "VMM Communication Exception", - "Security Exception", - "Reserved", -}; - -void isr0_handler(void) -{ - fb_draw_string(fb, exception_name[0], 0, 0, WHITE, BLACK); -} - -void isr1_handler(void) -{ - fb_draw_string(fb, exception_name[1], 0, 0, WHITE, BLACK); -} - -void isr2_handler(void) -{ - fb_draw_string(fb, exception_name[2], 0, 0, WHITE, BLACK); -} - -void isr3_handler(void) -{ - fb_draw_string(fb, exception_name[3], 0, 0, WHITE, BLACK); -} - -void isr4_handler(void) -{ - fb_draw_string(fb, exception_name[4], 0, 0, WHITE, BLACK); -} - -void isr5_handler(void) -{ - fb_draw_string(fb, exception_name[5], 0, 0, WHITE, BLACK); -} - -void isr6_handler(void) -{ - fb_draw_string(fb, exception_name[6], 0, 0, WHITE, BLACK); -} - -void isr7_handler(void) -{ - fb_draw_string(fb, exception_name[7], 0, 0, WHITE, BLACK); -} - -void isr8_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[8], 0, 0, WHITE, BLACK); -} - -void isr9_handler(void) -{ - fb_draw_string(fb, exception_name[9], 0, 0, WHITE, BLACK); -} - -void isr10_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[10], 0, 0, WHITE, BLACK); -} - -void isr11_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[11], 0, 0, WHITE, BLACK); -} - -void isr12_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[12], 0, 0, WHITE, BLACK); -} - -void isr13_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[13], 0, 0, WHITE, BLACK); -} - -void isr14_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[14], 0, 0, WHITE, BLACK); -} - -void isr15_handler(void) -{ - fb_draw_string(fb, exception_name[15], 0, 0, WHITE, BLACK); -} - -void isr16_handler(void) -{ - fb_draw_string(fb, exception_name[16], 0, 0, WHITE, BLACK); -} - -void isr17_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[17], 0, 0, WHITE, BLACK); -} - -void isr18_handler(void) -{ - fb_draw_string(fb, exception_name[18], 0, 0, WHITE, BLACK); -} - -void isr19_handler(void) -{ - fb_draw_string(fb, exception_name[19], 0, 0, WHITE, BLACK); -} - -void isr20_handler(void) -{ - fb_draw_string(fb, exception_name[20], 0, 0, WHITE, BLACK); -} - -void isr21_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[21], 0, 0, WHITE, BLACK); -} - -void isr22_handler(void) -{ - fb_draw_string(fb, exception_name[22], 0, 0, WHITE, BLACK); -} - -void isr23_handler(void) -{ - fb_draw_string(fb, exception_name[23], 0, 0, WHITE, BLACK); -} - -void isr24_handler(void) -{ - fb_draw_string(fb, exception_name[24], 0, 0, WHITE, BLACK); -} - -void isr25_handler(void) -{ - fb_draw_string(fb, exception_name[25], 0, 0, WHITE, BLACK); -} - -void isr26_handler(void) -{ - fb_draw_string(fb, exception_name[26], 0, 0, WHITE, BLACK); -} - -void isr27_handler(void) -{ - fb_draw_string(fb, exception_name[27], 0, 0, WHITE, BLACK); -} - -void isr28_handler(void) -{ - fb_draw_string(fb, exception_name[28], 0, 0, WHITE, BLACK); -} - -void isr29_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[29], 0, 0, WHITE, BLACK); -} - -void isr30_handler(uint64_t error) -{ - fb_draw_string(fb, exception_name[30], 0, 0, WHITE, BLACK); -} - -void isr31_handler(void) -{ - fb_draw_string(fb, exception_name[31], 0, 0, WHITE, BLACK); -} - -void irq0_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq1_handler(void) -{ - keyboard_handler(); - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq2_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq3_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq4_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq5_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq6_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq7_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); -} - -void irq8_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq9_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq10_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq11_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq12_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq13_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq14_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} - -void irq15_handler(void) -{ - outb(PIC1_COMMAND, PIC_EOI); - outb(PIC2_COMMAND, PIC_EOI); -} diff --git a/kernel/irq_stub.S b/kernel/irq_stub.S deleted file mode 100644 index ddd197a..0000000 --- a/kernel/irq_stub.S +++ /dev/null @@ -1,108 +0,0 @@ -.macro pushall - push %rax - push %rcx - push %rdx - push %rsi - push %rdi - push %r8 - push %r9 - push %r10 - push %r11 - pushfq -.endm - -.macro popall - popfq - pop %r11 - pop %r10 - pop %r9 - pop %r8 - pop %rdi - pop %rsi - pop %rdx - pop %rcx - pop %rax -.endm - - -.macro isr_no_error number -.global isr\number -isr\number: - pushall - cld - call isr\number\()_handler - popall - iretq -.endm - -.macro isr_error number -.global isr\number -isr\number: - # rdi not saved - pop %rdi - pushall - cld - call isr\number\()_handler - popall - iretq -.endm - -isr_no_error 0 -isr_no_error 1 -isr_no_error 2 -isr_no_error 3 -isr_no_error 4 -isr_no_error 5 -isr_no_error 6 -isr_no_error 7 -isr_error 8 -isr_no_error 9 -isr_error 10 -isr_error 11 -isr_error 12 -isr_error 13 -isr_error 14 -isr_no_error 15 -isr_no_error 16 -isr_error 17 -isr_no_error 18 -isr_no_error 19 -isr_no_error 20 -isr_no_error 21 -isr_no_error 22 -isr_no_error 23 -isr_no_error 24 -isr_no_error 25 -isr_no_error 26 -isr_no_error 27 -isr_no_error 28 -isr_error 29 -isr_error 30 -isr_no_error 31 - -.macro irq number -.global irq\number -irq\number: - pushall - cld - call irq\number\()_handler - popall - iretq -.endm - -irq 0 -irq 1 -irq 2 -irq 3 -irq 4 -irq 5 -irq 6 -irq 7 -irq 8 -irq 9 -irq 10 -irq 11 -irq 12 -irq 13 -irq 14 -irq 15 diff --git a/kernel/kernel.ld b/kernel/kernel.ld deleted file mode 100644 index da5c87c..0000000 --- a/kernel/kernel.ld +++ /dev/null @@ -1,39 +0,0 @@ -ENTRY(_start) - -SECTIONS -{ - . = 1M; - - .boot BLOCK(4K) : ALIGN(4K) - { - KEEP(*(.multiboot_header)) - } - - .text BLOCK(4K) : ALIGN(4K) - { - *(.text) - } - - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - - /DISCARD/ : - { - *(.comment.*) - *(.note.*) - *(.eh_frame) - } -} diff --git a/kernel/keyboard.c b/kernel/keyboard.c deleted file mode 100644 index 105c3a8..0000000 --- a/kernel/keyboard.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -#include - -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_STATUS_PORT 0x64 - -uint8_t i = 0; - -void keyboard_handler(void) -{ - uint8_t status = inb(KEYBOARD_STATUS_PORT); - if (!(status & 0x1)) { - return; - } - uint8_t keycode = inb(KEYBOARD_DATA_PORT); - fb_draw_character(fb, keycode, 0, 0, RED, BLACK); -} diff --git a/kernel/main.c b/kernel/main.c deleted file mode 100644 index 96f3572..0000000 --- a/kernel/main.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include -#include -#include - -int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) -{ - init_idt(); - init_fb(multiboot_bootinfo, multiboot_magic); - - fb_draw_string(fb, "Still working...", 8, 0, WHITE, BLACK); - - for(;;) { - __asm__ volatile ("hlt;"); - } - return 0; -} diff --git a/kernel/multiboot2.c b/kernel/multiboot2.c deleted file mode 100644 index e228ce1..0000000 --- a/kernel/multiboot2.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include - -fb_t fb; - -/* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Boot-information-format.html */ - -void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) -{ - if (multiboot_magic != MB2_MAGIC) { - // not loaded by multiboot2 bootloader - __asm__ volatile ("hlt;"); - } - - // we will store framebuffer information here - static mb2_tag_fb* tag_fb; - - // skip first 8 bytes (total_size + reserved) - mb2_tag_header* tag_header = multiboot_bootinfo + 1; - - while (tag_header->type != MB2_TAG_END) { - // process tag_type - switch(tag_header->type) { - case MB2_TAG_FB: - tag_fb = (mb2_tag_fb*)tag_header; - break; - default: - break; - } - - // next mb2_tag - tag_header += tag_header->size / 8 + ((tag_header->size % 8) > 0); - } - - fb.addr = tag_fb->framebuffer_addr; - fb.width = tag_fb->framebuffer_width; - fb.height = tag_fb->framebuffer_height; - fb.pitch = tag_fb->framebuffer_pitch; - fb.bpp = tag_fb->framebuffer_bpp; -} diff --git a/kernel/pic.c b/kernel/pic.c deleted file mode 100644 index 801556d..0000000 --- a/kernel/pic.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -void remap_pic(void) -{ - // save masks -// uint8_t a1 = inb(PIC1_DATA); -// uint8_t a2 = inb(PIC2_DATA); - - // starts the initialization sequence (in cascade mode) - outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset - outb(PIC2_DATA, 0x28); // ICW2: Slave PIC vector offset - outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) - outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) - - outb(PIC1_DATA, ICW4_8086); - outb(PIC2_DATA, ICW4_8086); - - // mask interrupts - outb(PIC1_DATA, 0xfd); - outb(PIC2_DATA, 0xff); -} diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S new file mode 100644 index 0000000..ee35eeb --- /dev/null +++ b/kernel/src/boot/boot.S @@ -0,0 +1,181 @@ +.global _start +.extern begin_long_mode + +.section .text +.code32 + +_start: + cli + mov $stack_top, %esp + pushl $0 + pushl %eax + pushl $0 + pushl %ebx + + call check_multiboot + call check_cpuid + call check_long_mode + + call setup_page_tables + call enable_paging + + lgdt gdt_pointer + ljmp $0x08, $begin_long_mode + + +check_multiboot: + cmp $0x36d76289, %eax + jne no_multiboot + + ret + +check_cpuid: + pushfl + pop %eax + mov %eax, %ecx + xor $1<<21, %eax + push %eax + popfl + pushfl + pop %eax + push %ecx + popfl + cmp %eax, %ecx + je no_cpuid + + ret + +check_long_mode: + mov $0x80000000, %eax + cpuid + cmp $0x80000001, %eax + jb no_long_mode + + mov $0x80000001, %eax + cpuid + test $1<<29, %edx + jz no_long_mode + + ret + +setup_page_tables: + mov $page_table_lvl3, %eax + or $0x3, %eax + mov %eax, page_table_lvl4 + + mov $page_table_lvl2, %eax + or $0x3, %eax + mov %eax, page_table_lvl3 + + mov $page_table_lvl2 + 4096, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+8 + + mov $page_table_lvl2 + 8192, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+16 + + mov $page_table_lvl2 + 12288, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+24 + + + movl $0, %ecx +1: + movl $0x200000, %eax + mul %ecx + or $0b10000011, %eax + movl $page_table_lvl2, %edx + leal (%edx, %ecx, 8), %edx + movl %eax, (%edx) + inc %ecx + cmp $512*4, %ecx + jne 1b + + ret + +enable_paging: + // enable PAE + mov %cr4, %edx + or $1<<5 ,%edx + mov %edx, %cr4 + + // set LME (long mode enable) + mov $0xC0000080, %ecx + rdmsr + or $1<<8, %eax + wrmsr + + // page_table_lvl4 + mov $page_table_lvl4, %eax + mov %eax, %cr3 + + // enable paging (+ protected mode if not already enabled) + mov %cr0, %eax + or $1<<31 + 1<<0, %eax + mov %eax, %cr0 + + ret + +no_multiboot: + hlt + +no_cpuid: + hlt + +no_long_mode: + hlt + + +.section .bss +.align 4096 + +// stack +stack_bottom: + .skip 4096*4 +stack_top: + +// page tables +page_table_lvl4: + .skip 4096 +page_table_lvl3: + .skip 4096 +// map first 4GB +page_table_lvl2: + .skip 4096*4 + +// Access bits +.section .rodata +.set PRESENT, 1 << 7 +.set NOT_SYS, 1 << 4 +.set EXEC, 1 << 3 +.set DC, 1 << 2 +.set RW, 1 << 1 +.set ACCESSED, 1 << 0 + +// Flags bits +.set GRAN_4K, 1 << 7 +.set SZ_32, 1 << 6 +.set LONG_MODE, 1 << 5 + +gdt: +gdt_null = . - gdt + .quad 0 +gdt_code = . - gdt + .long 0xFFFF // Limit & Base (low, bits 0-15) + .byte 0 // Base (mid, bits 16-23) + .byte PRESENT | NOT_SYS | EXEC | RW // Access + .byte GRAN_4K | LONG_MODE | 0xF // Flags & Limit (high, bits 16-19) + .byte 0 // Base (high, bits 24-31) +gdt_data = . - gdt + .long 0xFFFF + .byte 0 + .byte PRESENT | NOT_SYS | RW + .byte GRAN_4K | SZ_32 | 0xF + .byte 0 +gdt_tss = . - gdt + .long 0x00000068 + .long 0x00CF8900 +gdt_pointer: + .word . - gdt - 1 + .quad gdt diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S new file mode 100644 index 0000000..be87412 --- /dev/null +++ b/kernel/src/boot/boot64.S @@ -0,0 +1,19 @@ +.global begin_long_mode + +.section .text +.code64 + +begin_long_mode: + // reload segment registers + mov $0x10, %eax + mov %eax, %ss + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + + popq %rdi + popq %rsi + + call kernel_main + hlt diff --git a/kernel/src/boot/header.S b/kernel/src/boot/header.S new file mode 100644 index 0000000..bbcb9be --- /dev/null +++ b/kernel/src/boot/header.S @@ -0,0 +1,40 @@ +// multiboot tags +.set TAG_END, 0 +.set TAG_FRAMEBUFFER, 5 + +// multiboot flags +.set TAG_REQUIRED, 0 +.set TAG_OPTIONAL, 1 + +# multiboot2 header constants +.set MAGIC, 0xe85250d6 +.set ARCH, 0 +.set HEADER_LENGTH, (header_end - header_start) +.set CHECKSUM, 0x100000000 - (MAGIC + ARCH + HEADER_LENGTH) + +.section .multiboot_header, "a" +.align 4 +header_start: + # magic + .align 8 + .long MAGIC + .long ARCH + .long HEADER_LENGTH + .long CHECKSUM + + # framebuffer + .align 8 + .word TAG_FRAMEBUFFER + .word TAG_REQUIRED + .long 20 + .long 1024 + .long 768 + .long 32 + + # end tag + .align 8 + .word TAG_END + .word TAG_REQUIRED + .long 8 + +header_end: diff --git a/kernel/src/boot/multiboot2.c b/kernel/src/boot/multiboot2.c new file mode 100644 index 0000000..e228ce1 --- /dev/null +++ b/kernel/src/boot/multiboot2.c @@ -0,0 +1,41 @@ +#include +#include +#include + +fb_t fb; + +/* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Boot-information-format.html */ + +void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) +{ + if (multiboot_magic != MB2_MAGIC) { + // not loaded by multiboot2 bootloader + __asm__ volatile ("hlt;"); + } + + // we will store framebuffer information here + static mb2_tag_fb* tag_fb; + + // skip first 8 bytes (total_size + reserved) + mb2_tag_header* tag_header = multiboot_bootinfo + 1; + + while (tag_header->type != MB2_TAG_END) { + // process tag_type + switch(tag_header->type) { + case MB2_TAG_FB: + tag_fb = (mb2_tag_fb*)tag_header; + break; + default: + break; + } + + // next mb2_tag + tag_header += tag_header->size / 8 + ((tag_header->size % 8) > 0); + } + + fb.addr = tag_fb->framebuffer_addr; + fb.width = tag_fb->framebuffer_width; + fb.height = tag_fb->framebuffer_height; + fb.pitch = tag_fb->framebuffer_pitch; + fb.bpp = tag_fb->framebuffer_bpp; +} diff --git a/kernel/src/cpu/idt.c b/kernel/src/cpu/idt.c new file mode 100644 index 0000000..bf285b7 --- /dev/null +++ b/kernel/src/cpu/idt.c @@ -0,0 +1,88 @@ +#include +#include +#include + +__attribute__((aligned(0x10))) static idt_entry idt_table[256]; +idtp idt_pointer; + +void load_idt(idtp* pointer) +{ + __asm__ volatile ("lidt (%0); sti;" : : "r"(pointer) : ); +} + +void add_to_idt(uint16_t num, uint64_t offset, uint16_t selector, uint8_t type) +{ + idt_table[num].offset_1 = offset & 0xFFFF; + idt_table[num].offset_2 = (offset >> 16) & 0xFFFF; + idt_table[num].offset_3 = offset >> 32; + idt_table[num].selector = selector; + idt_table[num].type_attributes = type; + idt_table[num].ist = 0; + idt_table[num].zero = 0; +} + +void init_idt_table(void) +{ + // exceptions + add_to_idt(0, (uint64_t)isr0, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(1, (uint64_t)isr1, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(2, (uint64_t)isr2, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(3, (uint64_t)isr3, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(4, (uint64_t)isr4, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(5, (uint64_t)isr5, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(6, (uint64_t)isr6, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(7, (uint64_t)isr7, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(8, (uint64_t)isr8, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(9, (uint64_t)isr9, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(10, (uint64_t)isr10, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(11, (uint64_t)isr11, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(12, (uint64_t)isr12, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(13, (uint64_t)isr13, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(14, (uint64_t)isr14, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(15, (uint64_t)isr15, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(16, (uint64_t)isr16, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(17, (uint64_t)isr17, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(18, (uint64_t)isr18, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(19, (uint64_t)isr19, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(20, (uint64_t)isr20, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(21, (uint64_t)isr21, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(22, (uint64_t)isr22, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(23, (uint64_t)isr23, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(24, (uint64_t)isr24, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(25, (uint64_t)isr25, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(26, (uint64_t)isr26, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(27, (uint64_t)isr27, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(28, (uint64_t)isr28, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(29, (uint64_t)isr29, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(30, (uint64_t)isr30, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(31, (uint64_t)isr31, GDT_CODE_SEG, TRAP_GATE); + + // interrupts + add_to_idt(32, (uint64_t)irq0, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(33, (uint64_t)irq1, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(34, (uint64_t)irq2, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(35, (uint64_t)irq3, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(36, (uint64_t)irq4, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(37, (uint64_t)irq5, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(38, (uint64_t)irq6, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(39, (uint64_t)irq7, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(40, (uint64_t)irq8, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(41, (uint64_t)irq9, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(42, (uint64_t)irq10, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(43, (uint64_t)irq11, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(44, (uint64_t)irq12, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(45, (uint64_t)irq13, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(46, (uint64_t)irq14, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(47, (uint64_t)irq15, GDT_CODE_SEG, INTERRUPT_GATE); +} + +void init_idt() +{ + init_idt_table(); + idt_pointer.size = sizeof(idt_entry) * 256 - 1; + idt_pointer.offset = (uint64_t)&idt_table; + + remap_pic(); + + load_idt(&idt_pointer); +} diff --git a/kernel/src/cpu/io.c b/kernel/src/cpu/io.c new file mode 100644 index 0000000..6bf67d0 --- /dev/null +++ b/kernel/src/cpu/io.c @@ -0,0 +1,13 @@ +#include + +uint8_t inb(uint32_t port) +{ + uint8_t ret; + __asm__ volatile ("inb %%dx, %%al" : "=a"(ret) : "d"(port)); + return ret; +} + +void outb(uint32_t port, uint8_t value) +{ + __asm__ volatile ("outb %%al, %%dx" : : "d"(port), "a"(value)); +} diff --git a/kernel/src/cpu/irq.c b/kernel/src/cpu/irq.c new file mode 100644 index 0000000..1e02f23 --- /dev/null +++ b/kernel/src/cpu/irq.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include + +char* exception_name[] = { + "Divide-by-zero Error", + "Debug", + "Non-maskable Interrupt", + "Breakpoint", + "Overflow", + "Bound Range Exceeded", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Segment Overrun", + "Invalid TSS", + "Segment Not Present", + "Stack-Segment Fault", + "General Protection Fault", + "Page Fault", + "Reserved", + "x87 Floating-Point Exception", + "Alignment Check", + "Machine Check", + "SIMD Floating-Point Exception", + "Virtualization Exception", + "Control Protection Exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Hypervisor Injection Exception", + "VMM Communication Exception", + "Security Exception", + "Reserved", +}; + +void isr0_handler(void) +{ + fb_draw_string(fb, exception_name[0], 0, 0, WHITE, BLACK); +} + +void isr1_handler(void) +{ + fb_draw_string(fb, exception_name[1], 0, 0, WHITE, BLACK); +} + +void isr2_handler(void) +{ + fb_draw_string(fb, exception_name[2], 0, 0, WHITE, BLACK); +} + +void isr3_handler(void) +{ + fb_draw_string(fb, exception_name[3], 0, 0, WHITE, BLACK); +} + +void isr4_handler(void) +{ + fb_draw_string(fb, exception_name[4], 0, 0, WHITE, BLACK); +} + +void isr5_handler(void) +{ + fb_draw_string(fb, exception_name[5], 0, 0, WHITE, BLACK); +} + +void isr6_handler(void) +{ + fb_draw_string(fb, exception_name[6], 0, 0, WHITE, BLACK); +} + +void isr7_handler(void) +{ + fb_draw_string(fb, exception_name[7], 0, 0, WHITE, BLACK); +} + +void isr8_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[8], 0, 0, WHITE, BLACK); +} + +void isr9_handler(void) +{ + fb_draw_string(fb, exception_name[9], 0, 0, WHITE, BLACK); +} + +void isr10_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[10], 0, 0, WHITE, BLACK); +} + +void isr11_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[11], 0, 0, WHITE, BLACK); +} + +void isr12_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[12], 0, 0, WHITE, BLACK); +} + +void isr13_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[13], 0, 0, WHITE, BLACK); +} + +void isr14_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[14], 0, 0, WHITE, BLACK); +} + +void isr15_handler(void) +{ + fb_draw_string(fb, exception_name[15], 0, 0, WHITE, BLACK); +} + +void isr16_handler(void) +{ + fb_draw_string(fb, exception_name[16], 0, 0, WHITE, BLACK); +} + +void isr17_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[17], 0, 0, WHITE, BLACK); +} + +void isr18_handler(void) +{ + fb_draw_string(fb, exception_name[18], 0, 0, WHITE, BLACK); +} + +void isr19_handler(void) +{ + fb_draw_string(fb, exception_name[19], 0, 0, WHITE, BLACK); +} + +void isr20_handler(void) +{ + fb_draw_string(fb, exception_name[20], 0, 0, WHITE, BLACK); +} + +void isr21_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[21], 0, 0, WHITE, BLACK); +} + +void isr22_handler(void) +{ + fb_draw_string(fb, exception_name[22], 0, 0, WHITE, BLACK); +} + +void isr23_handler(void) +{ + fb_draw_string(fb, exception_name[23], 0, 0, WHITE, BLACK); +} + +void isr24_handler(void) +{ + fb_draw_string(fb, exception_name[24], 0, 0, WHITE, BLACK); +} + +void isr25_handler(void) +{ + fb_draw_string(fb, exception_name[25], 0, 0, WHITE, BLACK); +} + +void isr26_handler(void) +{ + fb_draw_string(fb, exception_name[26], 0, 0, WHITE, BLACK); +} + +void isr27_handler(void) +{ + fb_draw_string(fb, exception_name[27], 0, 0, WHITE, BLACK); +} + +void isr28_handler(void) +{ + fb_draw_string(fb, exception_name[28], 0, 0, WHITE, BLACK); +} + +void isr29_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[29], 0, 0, WHITE, BLACK); +} + +void isr30_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[30], 0, 0, WHITE, BLACK); +} + +void isr31_handler(void) +{ + fb_draw_string(fb, exception_name[31], 0, 0, WHITE, BLACK); +} + +void irq0_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq1_handler(void) +{ + keyboard_handler(); + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq2_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq3_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq4_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq5_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq6_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq7_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq8_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq9_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq10_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq11_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq12_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq13_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq14_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq15_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} diff --git a/kernel/src/cpu/irq_stub.S b/kernel/src/cpu/irq_stub.S new file mode 100644 index 0000000..ddd197a --- /dev/null +++ b/kernel/src/cpu/irq_stub.S @@ -0,0 +1,108 @@ +.macro pushall + push %rax + push %rcx + push %rdx + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + pushfq +.endm + +.macro popall + popfq + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %rax +.endm + + +.macro isr_no_error number +.global isr\number +isr\number: + pushall + cld + call isr\number\()_handler + popall + iretq +.endm + +.macro isr_error number +.global isr\number +isr\number: + # rdi not saved + pop %rdi + pushall + cld + call isr\number\()_handler + popall + iretq +.endm + +isr_no_error 0 +isr_no_error 1 +isr_no_error 2 +isr_no_error 3 +isr_no_error 4 +isr_no_error 5 +isr_no_error 6 +isr_no_error 7 +isr_error 8 +isr_no_error 9 +isr_error 10 +isr_error 11 +isr_error 12 +isr_error 13 +isr_error 14 +isr_no_error 15 +isr_no_error 16 +isr_error 17 +isr_no_error 18 +isr_no_error 19 +isr_no_error 20 +isr_no_error 21 +isr_no_error 22 +isr_no_error 23 +isr_no_error 24 +isr_no_error 25 +isr_no_error 26 +isr_no_error 27 +isr_no_error 28 +isr_error 29 +isr_error 30 +isr_no_error 31 + +.macro irq number +.global irq\number +irq\number: + pushall + cld + call irq\number\()_handler + popall + iretq +.endm + +irq 0 +irq 1 +irq 2 +irq 3 +irq 4 +irq 5 +irq 6 +irq 7 +irq 8 +irq 9 +irq 10 +irq 11 +irq 12 +irq 13 +irq 14 +irq 15 diff --git a/kernel/src/cpu/pic.c b/kernel/src/cpu/pic.c new file mode 100644 index 0000000..801556d --- /dev/null +++ b/kernel/src/cpu/pic.c @@ -0,0 +1,24 @@ +#include +#include + +void remap_pic(void) +{ + // save masks +// uint8_t a1 = inb(PIC1_DATA); +// uint8_t a2 = inb(PIC2_DATA); + + // starts the initialization sequence (in cascade mode) + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset + outb(PIC2_DATA, 0x28); // ICW2: Slave PIC vector offset + outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) + outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) + + outb(PIC1_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); + + // mask interrupts + outb(PIC1_DATA, 0xfd); + outb(PIC2_DATA, 0xff); +} diff --git a/kernel/src/devices/keyboard.c b/kernel/src/devices/keyboard.c new file mode 100644 index 0000000..105c3a8 --- /dev/null +++ b/kernel/src/devices/keyboard.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + +uint8_t i = 0; + +void keyboard_handler(void) +{ + uint8_t status = inb(KEYBOARD_STATUS_PORT); + if (!(status & 0x1)) { + return; + } + uint8_t keycode = inb(KEYBOARD_DATA_PORT); + fb_draw_character(fb, keycode, 0, 0, RED, BLACK); +} diff --git a/kernel/src/grub.cfg b/kernel/src/grub.cfg new file mode 100644 index 0000000..05a13f7 --- /dev/null +++ b/kernel/src/grub.cfg @@ -0,0 +1,8 @@ +set timeout=0 +set default=0 + +insmod efi_gop +menuentry "mykernel64" { + multiboot2 /boot/kernel.bin + boot +} diff --git a/kernel/src/kernel.ld b/kernel/src/kernel.ld new file mode 100644 index 0000000..da5c87c --- /dev/null +++ b/kernel/src/kernel.ld @@ -0,0 +1,39 @@ +ENTRY(_start) + +SECTIONS +{ + . = 1M; + + .boot BLOCK(4K) : ALIGN(4K) + { + KEEP(*(.multiboot_header)) + } + + .text BLOCK(4K) : ALIGN(4K) + { + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } + + /DISCARD/ : + { + *(.comment.*) + *(.note.*) + *(.eh_frame) + } +} diff --git a/kernel/src/main.c b/kernel/src/main.c new file mode 100644 index 0000000..96f3572 --- /dev/null +++ b/kernel/src/main.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) +{ + init_idt(); + init_fb(multiboot_bootinfo, multiboot_magic); + + fb_draw_string(fb, "Still working...", 8, 0, WHITE, BLACK); + + for(;;) { + __asm__ volatile ("hlt;"); + } + return 0; +} diff --git a/kernel/src/misc/debug.c b/kernel/src/misc/debug.c new file mode 100644 index 0000000..5f3c327 --- /dev/null +++ b/kernel/src/misc/debug.c @@ -0,0 +1,6 @@ +#include + +void bochs_breakpoint(void) +{ + __asm__ volatile ("xchgw %bx, %bx;"); +} diff --git a/kernel/src/misc/graphics.c b/kernel/src/misc/graphics.c new file mode 100644 index 0000000..d4fc7c7 --- /dev/null +++ b/kernel/src/misc/graphics.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include + +uint64_t* pixel_offset(fb_t fb, uint32_t x, uint32_t y) +{ + return (uint64_t*)((char*)fb.addr + y * fb.pitch + x * fb.bpp / 8); +} + +void fb_draw_pixel(fb_t fb, uint32_t x, uint32_t y, uint32_t col) +{ + if (x >= fb.width || y >= fb.height) return; + + uint32_t* fb_offset = (uint32_t*)pixel_offset(fb, x, y); + *fb_offset = col; +} + +/* https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm */ + +void fb_draw_line_low(fb_t fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t col) +{ + int32_t dx = x1 - x0; + int32_t dy = y1 - y0; + int32_t yi = 1; + if (dy < 0) { + yi = -1; + dy = -dy; + } + int32_t D = (2 * dy) - dx; + int32_t y = y0; + + for (int32_t x = x0; x <= x1; x++) { + fb_draw_pixel(fb, x, y, col); + if (D > 0) { + y = y + yi; + D = D + (2 * (dy - dx)); + } else { + D = D + 2 * dy; + } + } + +} + +void fb_draw_line_high(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) +{ + int32_t dx = x1 - x0; + int32_t dy = y1 - y0; + int32_t xi = 1; + if (dx < 0) { + xi = -1; + dx = -dx; + } + int32_t D = (2 * dx) - dy; + int32_t x = x0; + + for (int32_t y = y0; y <= y1; y++) { + fb_draw_pixel(fb, x, y, col); + if (D > 0) { + x = x + xi; + D = D + (2 * (dx - dy)); + } else { + D = D + 2 * dx; + } + } +} + +int32_t abs(int32_t val) +{ + if (val < 0) return -val; + return val; +} + +void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) +{ + if (abs(y1 - y0) < abs(x1 - x0)) { + if (x0 > x1) + fb_draw_line_low(fb, x1, y1, x0, y0, col); + else + fb_draw_line_low(fb, x0, y0, x1, y1, col); + } else { + if (y0 > y1) + fb_draw_line_high(fb, x1, y1, x0, y0, col); + else + fb_draw_line_high(fb, x0, y0, x1, y1, col); + } +} + +void fb_draw_character(fb_t fb, char c, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col) +{ + if (c < 0) return; + + uint32_t offset = 32 + c * 16; + for (uint32_t i = 0 ; i < 16; i++) + { + for (uint32_t j = 0 ; j < 8; j++) + { + if (font[offset + i] & (1 << (7 - j))) { + fb_draw_pixel(fb, x + j, y + i, char_col); + } else { + fb_draw_pixel(fb, x + j, y + i, bg_col); + } + } + } +} + +uint32_t strlen(const char* s) +{ + char *p = (char*)s; + while (*p) p++; + return p - s; +} + +void fb_draw_string(fb_t fb, const char* s, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col) +{ + for (uint32_t i = 0; i < strlen(s); i++) { + fb_draw_character(fb, s[i], x + i * 8, y, char_col, bg_col); + } +} -- cgit v1.2.3