├── .gitignore ├── C ├── io.asm ├── io.h ├── kernel.c ├── keys.c ├── keys.h ├── link.ld ├── vga.c └── vga.h ├── LICENSE.txt ├── README.txt ├── bftk └── makefile /.gitignore: -------------------------------------------------------------------------------- 1 | /blib/ 2 | /.build/ 3 | _build/ 4 | cover_db/ 5 | inc/ 6 | Build 7 | !Build/ 8 | Build.bat 9 | .last_cover_stats 10 | /Makefile 11 | /Makefile.old 12 | /MANIFEST.bak 13 | /META.yml 14 | /META.json 15 | /MYMETA.* 16 | nytprof.out 17 | /pm_to_blib 18 | *.o 19 | *.bs 20 | /_eumm/ 21 | -------------------------------------------------------------------------------- /C/io.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2015 Hullu2000 2 | 3 | ;Permission is hereby granted, free of charge, to any person obtaining 4 | ;a copy of this software and associated documentation files (the 5 | ;"Software"), to deal in the Software without restriction, including 6 | ;without limitation the rights to use, copy, modify, merge, publish, 7 | ;distribute, sublicense, and/or sell copies of the Software, and to 8 | ;permit persons to whom the Software is furnished to do so, subject to 9 | ;the following conditions: 10 | 11 | ;The above copyright notice and this permission notice shall be included 12 | ;in all copies or substantial portions of the Software. 13 | 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | ;EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | ;MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | ;IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | ;CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | ;TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | ;SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | bits 32 23 | section .text 24 | 25 | extern keyboard_handler_main 26 | 27 | global keyboard_handler 28 | global read_port 29 | global write_port 30 | global load_idt 31 | 32 | read_port: 33 | mov edx, [esp + 4] 34 | in al, dx 35 | ret 36 | 37 | write_port: 38 | mov edx, [esp + 4] 39 | mov al, [esp + 4 + 4] 40 | out dx, al 41 | ret 42 | 43 | load_idt: 44 | mov edx, [esp + 4] 45 | lidt [edx] 46 | sti 47 | ret 48 | 49 | keyboard_handler: 50 | %ifdef KB 51 | call keyboard_handler_main 52 | %endif 53 | iretd 54 | 55 | -------------------------------------------------------------------------------- /C/io.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #ifndef _IO_H 23 | #define _IO_H 24 | 25 | void keyboard_handler(void); 26 | char read_port(unsigned short port); 27 | void write_port(unsigned short port, unsigned char data); 28 | void load_idt(unsigned long *idt_ptr); 29 | 30 | void beep(void); 31 | 32 | #endif // _IO_H 33 | -------------------------------------------------------------------------------- /C/kernel.c: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #if !defined(__cplusplus) 23 | #include 24 | #endif 25 | #include 26 | #include 27 | 28 | #if !defined(__i386__) 29 | #error "This piece of code needs to be compiled with an ix86-elf compiler" 30 | #endif 31 | 32 | #include "keys.h" 33 | #include "vga.h" 34 | 35 | #if defined(__cplusplus) 36 | extern "C" 37 | #endif 38 | void kernel_main() 39 | { 40 | terminal_initialize(); 41 | #ifdef KB 42 | idt_init(); 43 | kb_init(); 44 | #endif // KB 45 | } 46 | -------------------------------------------------------------------------------- /C/keys.c: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #include "vga.h" 23 | 24 | #include "keys.h" 25 | 26 | char *bfc; 27 | 28 | void set_addr(char *addr) 29 | { 30 | bfc = addr; 31 | } 32 | 33 | unsigned char keyboard_map[128] = 34 | { 35 | 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ 36 | '9', '0', '-', '=', '\b', /* Backspace */ 37 | '\t', /* Tab */ 38 | 'q', 'w', 'e', 'r', /* 19 */ 39 | 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */ 40 | 0, /* 29 - Control */ 41 | 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ 42 | '\'', '`', 0, /* Left shift */ 43 | '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ 44 | 'm', ',', '.', '/', 0, /* Right shift */ 45 | '*', 46 | 0, /* Alt */ 47 | ' ', /* Space bar */ 48 | 0, /* Caps lock */ 49 | 0, /* 59 - F1 key ... > */ 50 | 0, 0, 0, 0, 0, 0, 0, 0, 51 | 0, /* < ... F10 */ 52 | 0, /* 69 - Num lock*/ 53 | 0, /* Scroll Lock */ 54 | 0, /* Home key */ 55 | 0, /* Up Arrow */ 56 | 0, /* Page Up */ 57 | '-', 58 | 0, /* Left Arrow */ 59 | 0, 60 | 0, /* Right Arrow */ 61 | '+', 62 | 0, /* 79 - End key*/ 63 | 0, /* Down Arrow */ 64 | 0, /* Page Down */ 65 | 0, /* Insert Key */ 66 | 0, /* Delete Key */ 67 | 0, 0, 0, 68 | 0, /* F11 Key */ 69 | 0, /* F12 Key */ 70 | 0, /* All other keys are undefined */ 71 | }; 72 | 73 | #define KEYBOARD_DATA_PORT 0x60 74 | #define KEYBOARD_STATUS_PORT 0x64 75 | #define IDT_SIZE 256 76 | #define INTERRUPT_GATE 0x8e 77 | #define KERNEL_CODE_SEGMENT_OFFSET 0x08 78 | 79 | #define ENTER_KEY_CODE 0x1C 80 | 81 | typedef unsigned char uint8_t; 82 | 83 | #include "io.h" 84 | #include "vga.h" 85 | 86 | #include "keys.h" 87 | 88 | extern unsigned char keyboard_map[128]; 89 | 90 | 91 | unsigned int current_loc = 0; 92 | char *vidptr = (char*)0xb8000; 93 | 94 | struct IDT_entry{ 95 | unsigned short int offset_lowerbits; 96 | unsigned short int selector; 97 | unsigned char zero; 98 | unsigned char type_attr; 99 | unsigned short int offset_higherbits; 100 | }; 101 | 102 | struct IDT_entry IDT[IDT_SIZE]; 103 | 104 | 105 | void idt_init(void) 106 | { 107 | unsigned long keyboard_address; 108 | unsigned long idt_address; 109 | unsigned long idt_ptr[2]; 110 | 111 | keyboard_address = (unsigned long)keyboard_handler; 112 | IDT[0x21].offset_lowerbits = keyboard_address & 0xffff; 113 | IDT[0x21].selector = KERNEL_CODE_SEGMENT_OFFSET; 114 | IDT[0x21].zero = 0; 115 | IDT[0x21].type_attr = INTERRUPT_GATE; 116 | IDT[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16; 117 | 118 | /* Ports 119 | * PIC1 PIC2 120 | *Command 0x20 0xA0 121 | *Data 0x21 0xA1 122 | */ 123 | 124 | /* ICW1 - begin initialization */ 125 | write_port(0x20 , 0x11); 126 | write_port(0xA0 , 0x11); 127 | 128 | /* ICW2 - remap offset address of IDT */ 129 | write_port(0x21 , 0x20); 130 | write_port(0xA1 , 0x28); 131 | 132 | /* ICW3 - setup cascading */ 133 | write_port(0x21 , 0x00); 134 | write_port(0xA1 , 0x00); 135 | 136 | /* ICW4 - environment info */ 137 | write_port(0x21 , 0x01); 138 | write_port(0xA1 , 0x01); 139 | /* Initialization finished */ 140 | 141 | /* mask interrupts */ 142 | write_port(0x21 , 0xff); 143 | write_port(0xA1 , 0xff); 144 | 145 | /* fill the IDT descriptor */ 146 | idt_address = (unsigned long)IDT ; 147 | idt_ptr[0] = (sizeof (struct IDT_entry) * IDT_SIZE) + ((idt_address & 0xffff) << 16); 148 | idt_ptr[1] = idt_address >> 16 ; 149 | 150 | load_idt(idt_ptr); 151 | } 152 | 153 | void kb_init(void) 154 | { 155 | /* 0xFD is 11111101 - enables only IRQ1 (keyboard)*/ 156 | write_port(0x21 , 0xFD); 157 | } 158 | 159 | void keyboard_handler_main(void) { 160 | unsigned char status; 161 | char keycode; 162 | 163 | /* write EOI */ 164 | write_port(0x20, 0x20); 165 | 166 | status = read_port(KEYBOARD_STATUS_PORT); 167 | /* Lowest bit of status will be set if buffer is not empty */ 168 | if (status & 0x01) { 169 | keycode = read_port(KEYBOARD_DATA_PORT); 170 | char c = keyboard_map[keycode]; 171 | if(c != 0) 172 | { 173 | terminal_putchar(c); 174 | *bfc = c; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /C/keys.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #ifndef _KEYS_H 23 | #define _KEYS_H 24 | 25 | void idt_init(void); 26 | void kb_init(void); 27 | 28 | extern unsigned char keyboard_map[128]; 29 | 30 | #endif // _KEYS_H 31 | -------------------------------------------------------------------------------- /C/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 1M; 6 | 7 | .text : 8 | { 9 | *(.multiboot) 10 | *(.text) 11 | } 12 | 13 | /* Read-only data. */ 14 | .rodata BLOCK(4K) : ALIGN(4K) 15 | { 16 | *(.rodata) 17 | } 18 | 19 | /* Read-write data (initialized) */ 20 | .data BLOCK(4K) : ALIGN(4K) 21 | { 22 | *(.data) 23 | } 24 | 25 | /* Read-write data (uninitialized) and stack */ 26 | .bss BLOCK(4K) : ALIGN(4K) 27 | { 28 | *(COMMON) 29 | *(.bootstrap_stack) 30 | *(.bss) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /C/vga.c: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #if !defined(__cplusplus) 23 | #include 24 | #endif 25 | #include 26 | #include 27 | 28 | #include "io.h" 29 | #include "keys.h" 30 | 31 | #include "vga.h" 32 | 33 | uint16_t make_vgaentry(char c, uint8_t color) 34 | { 35 | uint16_t c16 = c; 36 | uint16_t color16 = color; 37 | return c16 | color16 << 8; 38 | } 39 | 40 | size_t strlen(const char* str) 41 | { 42 | size_t ret = 0; 43 | while ( str[ret] != 0 ) 44 | ret++; 45 | return ret; 46 | } 47 | 48 | static const size_t VGA_WIDTH = 80; 49 | static const size_t VGA_HEIGHT = 25; 50 | 51 | size_t terminal_row; 52 | size_t terminal_column; 53 | uint8_t terminal_color; 54 | uint16_t* terminal_buffer; 55 | 56 | void terminal_initialize() 57 | { 58 | terminal_row = 0; 59 | terminal_column = 0; 60 | terminal_color = FG | BG << 4; 61 | terminal_buffer = (uint16_t*) 0xB8000; 62 | for ( size_t y = 0; y < VGA_HEIGHT; y++ ) 63 | { 64 | for ( size_t x = 0; x < VGA_WIDTH; x++ ) 65 | { 66 | const size_t index = y * VGA_WIDTH + x; 67 | terminal_buffer[index] = make_vgaentry(' ', terminal_color); 68 | } 69 | } 70 | } 71 | 72 | void terminal_setcolor(uint8_t color) 73 | { 74 | terminal_color = color; 75 | } 76 | 77 | void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) 78 | { 79 | const size_t index = y * VGA_WIDTH + x; 80 | terminal_buffer[index] = make_vgaentry(c, color); 81 | } 82 | 83 | void update_cursor(int row, int col) 84 | { 85 | unsigned short position=(row*80) + col; 86 | 87 | // cursor LOW port to vga INDEX register 88 | write_port(0x3D4, 0x0F); 89 | write_port(0x3D5, (unsigned char)(position&0xFF)); 90 | // cursor HIGH port to vga INDEX register 91 | write_port(0x3D4, 0x0E); 92 | write_port(0x3D5, (unsigned char)((position>>8)&0xFF)); 93 | } 94 | 95 | void terminal_putchar(char c) 96 | { 97 | bool rc = false; 98 | switch(c) 99 | { 100 | case '\n': 101 | terminal_column = 0; 102 | rc = true; 103 | break; 104 | case '\b': 105 | terminal_column--; 106 | if(terminal_column < 0) 107 | { 108 | terminal_column = 0; 109 | terminal_row--; 110 | } 111 | terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); 112 | break; 113 | 114 | default: 115 | terminal_putentryat(c, terminal_color, terminal_column, terminal_row); 116 | if ( ++terminal_column == VGA_WIDTH ) 117 | { 118 | terminal_column = 0; 119 | rc = true; 120 | } 121 | break; 122 | } 123 | if(rc) 124 | { 125 | if (++terminal_row == VGA_HEIGHT) 126 | { 127 | for(int i = 0; i < VGA_HEIGHT - 1; i++) 128 | { 129 | for(int j = 0; j < VGA_WIDTH; j++) 130 | { 131 | terminal_buffer[i * VGA_WIDTH + j] = terminal_buffer[(i + 1) * VGA_WIDTH + j]; 132 | } 133 | } 134 | for(int j = 0; j < VGA_WIDTH; j++) 135 | { 136 | terminal_putentryat(' ', terminal_color, j, 24); 137 | } 138 | terminal_row = VGA_HEIGHT - 1; 139 | } 140 | } 141 | update_cursor(terminal_row, terminal_column); 142 | } 143 | 144 | void terminal_writestring(const char* data) 145 | { 146 | size_t datalen = strlen(data); 147 | for ( size_t i = 0; i < datalen; i++ ) 148 | terminal_putchar(data[i]); 149 | } 150 | 151 | -------------------------------------------------------------------------------- /C/vga.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 21 | 22 | #ifndef _VGH_H 23 | #define _VGA_H 24 | 25 | #include 26 | #include 27 | 28 | void terminal_initialize(); 29 | 30 | uint16_t make_vgaentry(char c, uint8_t color); 31 | void terminal_setcolor(uint8_t color); 32 | void terminal_writestring(const char* data); 33 | void terminal_putchar(char c); 34 | 35 | #endif // _VGH_H 36 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Hullu2000 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | BFTK (BrainFuck To Kernel) version 1.1 2 | 3 | BFTK is a Perl script that turns Brainfuck into assembly and 4 | links it with a few C files to create a working kernel that 5 | can be booted with GRUB or Qemu. Currently BFTK requires 6 | Perl to run and i686-elf-gcc and Nasm to work. You should be 7 | able to find them in the package repository of your distro. 8 | 9 | If you don't want to or can't install i686-elf-gcc you can 10 | use the m32 branch instead. 11 | 12 | BFTK is free software released under the MIT license. 13 | The C files are based on a few tutorials online. Mainly in 14 | osdev.org. If I have used some of your code there that you 15 | haven't released as public domain (as everything on osdev.org 16 | should have been since 2011) please contact me and I'll fix 17 | the licensing. But to be honest, why did you even put code in 18 | a tutorial if you didn't want it to be used. 19 | 20 | INSTALLATION 21 | 22 | BFTK doesn't need to be compiled since it's just a script. 23 | It can be installed with the "make install" command and 24 | uninstalled with the "make uninstall" command. 25 | 26 | USAGE 27 | 28 | bftk /path/to/brainfuck/program [BG colour] [FG colour] 29 | 30 | This will produce a file called bfos.bin. This is a kernel 31 | that can be booted on any i686 (Pentium Pro) or newer system. 32 | Boot loader not included. Use GRUB. You can also boot it in 33 | Qemu with the command "qemu-system-x86_68 -kernel bfos.bin" 34 | 35 | To input colours use numbers: 36 | 37 | BLACK = 0 38 | BLUE = 1 39 | GREEN = 2 40 | CYAN = 3 41 | RED = 4 42 | MAGENTA = 5 43 | BROWN = 6 44 | LIGHT_GREY = 7 45 | DARK_GREY = 8 46 | LIGHT_BLUE = 9 47 | LIGHT_GREEN = 10 48 | LIGHT_CYAN = 11 49 | LIGHT_RED = 12 50 | LIGHT_MAGENTA = 13 51 | LIGHT_BROWN = 14 52 | WHITE = 15 53 | -------------------------------------------------------------------------------- /bftk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | #Copyright (c) 2015 Hullu2000 4 | 5 | #Permission is hereby granted, free of charge, to any person obtaining 6 | #a copy of this software and associated documentation files (the 7 | #"Software"), to deal in the Software without restriction, including 8 | #without limitation the rights to use, copy, modify, merge, publish, 9 | #distribute, sublicense, and/or sell copies of the Software, and to 10 | #permit persons to whom the Software is furnished to do so, subject to 11 | #the following conditions: 12 | 13 | #The above copyright notice and this permission notice shall be included 14 | #in all copies or substantial portions of the Software. 15 | 16 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | #MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | #IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | #CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | #TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | #SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 23 | 24 | my $code = "extern kernel_main 25 | extern terminal_putchar 26 | extern set_addr 27 | 28 | ;multiboot header constants 29 | MBALIGN equ 1<<0 ;align loaded modules on page boundaries 30 | MEMINFO equ 1<<1 ;provide memory map 31 | FLAGS equ MBALIGN | MEMINFO ;multiboot 'flag' field 32 | MAGIC equ 0x1BADB002 ;magic number 33 | CHECKSUM equ -(MAGIC + FLAGS) ;checksum 34 | 35 | ;Declare a header as in the Multiboot Standard 36 | section .multiboot 37 | align 4 38 | dd MAGIC 39 | dd FLAGS 40 | dd CHECKSUM 41 | 42 | ;stack pointer 43 | section .bootstrap_stack;, nobits 44 | align 4 45 | stack_bottom: 46 | times 16384 db 0 47 | stack_top: 48 | 49 | ;start 50 | section .text 51 | global _start 52 | _start: 53 | ;stack setup 54 | cli 55 | mov esp, stack_top 56 | 57 | call kernel_main 58 | cli 59 | 60 | mov ebx, 0x00007E00 ;0x00100000\n"; 61 | 62 | $/ = \1; 63 | 64 | my ($buf, $data, $n, $nl, $loop, @loops); 65 | 66 | $nl = 0; 67 | $loop = 0; 68 | 69 | open my $fh, "<:encoding(UTF-8)", $ARGV[0] or die "$!\n"; 70 | 71 | my $kb = 0; 72 | 73 | while (read $fh, $data, 1) 74 | { 75 | LS: 76 | if($data eq ">") 77 | { 78 | my $count = 0; 79 | while ($data eq ">") 80 | { 81 | read $fh, $data, 1; 82 | $count++; 83 | } 84 | $buf .= "add EBX, $count\n"; 85 | goto LS; 86 | } 87 | elsif($data eq "<") 88 | { 89 | my $count = 0; 90 | while ($data eq "<") 91 | { 92 | read $fh, $data, 1; 93 | $count++; 94 | } 95 | $buf .= "sub EBX, $count\n"; 96 | goto LS; 97 | } 98 | elsif($data eq "+") 99 | { 100 | my $count = 0; 101 | while ($data eq "+") 102 | { 103 | read $fh, $data, 1; 104 | $count++; 105 | } 106 | $buf .= "add byte[EBX], $count\n"; 107 | goto LS; 108 | } 109 | elsif($data eq "-") 110 | { 111 | my $count = 0; 112 | while ($data eq "-") 113 | { 114 | read $fh, $data, 1; 115 | $count++; 116 | } 117 | $buf .= "sub byte[EBX], $count\n"; 118 | goto LS; 119 | } 120 | elsif($data eq ".") 121 | { 122 | $buf .= "push ebp\nmov ebp, esp\nmov eax, [ebx]\npush eax\ncall terminal_putchar\npop ebp\n"; 123 | } 124 | elsif($data eq ",") 125 | { 126 | $kb = 1; 127 | $buf .= "push ebp\nmov ebp, esp\npush ebx\ncall set_addr\npop ebp\nsti\nhlt\nhlt\ncli\n" 128 | } 129 | elsif($data eq "[") 130 | { 131 | $loops[$nl] = $loop; 132 | $buf .= "cmp byte[EBX], 0\nje b_$loops[$nl]\na_$loops[$nl]:\n"; 133 | $nl++; 134 | $loop++; 135 | } 136 | elsif($data eq "]") 137 | { 138 | $nl--; 139 | $buf .= "cmp byte[EBX], 0\njne a_$loops[$nl]\nb_$loops[$nl]:\n"; 140 | } 141 | } 142 | 143 | close $fh; 144 | 145 | $code .= $buf; 146 | $code .= ".hang: 147 | hlt 148 | jmp .hang"; 149 | 150 | system("mkdir .out-tmp"); 151 | open my $fh, ">:encoding(UTF-8)", ".out-tmp/boot.asm" or die "$!\n"; 152 | print $fh $code; 153 | 154 | my $out = "./.out-tmp/"; 155 | my $path = "/usr/share/BFTK/"; 156 | 157 | my $bgc; 158 | my $fgc; 159 | 160 | if(defined $ARGV[1]) {$bgc = $ARGV[1];} else {$bgc = 0;} 161 | if(defined $ARGV[2]) {$fgc = $ARGV[2];} else {$fgc = 2;} 162 | 163 | my $kbd; 164 | if($kb) {$kbd = "-D KB";} 165 | 166 | system("nasm -felf32 ${out}boot.asm -o ${out}boot.o"); 167 | system("nasm -felf32 ${path}io.asm -o ${out}io.o $kbd"); 168 | system("i686-elf-gcc -c ${path}kernel.c -o ${out}kernel.o -std=gnu99 -ffreestanding -O2 $kbd"); 169 | if ($kb) {system("i686-elf-gcc -c ${path}keys.c -o ${out}keys.o -std=gnu99 -ffreestanding -O2");} 170 | system("i686-elf-gcc -c ${path}vga.c -o ${out}vga.o -DBG=${bgc} -DFG=${fgc} -std=gnu99 -ffreestanding -O2"); 171 | 172 | if($kb) 173 | { 174 | print("kb"); 175 | system("i686-elf-gcc -T ${path}link.ld -o bfos.bin -ffreestanding -O2 -nostdlib ${out}boot.o ${out}io.o ${out}keys.o ${out}kernel.o ${out}vga.o -lgcc"); 176 | } 177 | else 178 | { 179 | print("nkb"); 180 | system("i686-elf-gcc -T ${path}link.ld -o bfos.bin -ffreestanding -O2 -nostdlib ${out}boot.o ${out}io.o ${out}kernel.o ${out}vga.o -lgcc"); 181 | } 182 | system("rm -r $out"); 183 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | ri: uninstall install 2 | 3 | install: 4 | mkdir /usr/share/BFTK 5 | cp ./C/* /usr/share/BFTK 6 | cp ./bftk /usr/bin 7 | 8 | uninstall: 9 | rm -r /usr/share/BFTK 10 | rm /usr/bin/bftk --------------------------------------------------------------------------------