diff --git a/DEVELOPERS.md b/DEVELOPERS.md new file mode 100644 index 0000000..0551f5b --- /dev/null +++ b/DEVELOPERS.md @@ -0,0 +1,23 @@ +# Blank OS Developer's Manual + +## Getting Started + +### System description + +Blank OS runs on a monolithic kernel booted by a 3rd party bootloader; GRUB (whose executable is named `stage2_eltorito`). The kernel is compiled in ELF format. The target processor architecture is 32-bit x86. Blank OS is BIOS-independent which means it does not use Real mode BIOS functions as its routines. It rather uses in and out port communication to communicate with hardware directly (such as the keyboard) and it uses specific memory locations (for example the framebuffer to manage the screen in text mode). + +### Code structure + +The source code is available in folder `src`. You will find subfolders corresponding to appropriate system parts, such as the kernel, the C library (including drivers) and programs. + +## Making programs for the OS + +### Programming + +Basically you can use the kernel C library functions available in `src/libc/` and make programs out of those functions. Then you can set up the shell for your program to be launchable. + +More on that soon. + +### Compiling and linking + +The linking process should be taken care by the appropriate Linker script `link.ld` and the Makefile instructions and targets. diff --git a/README.md b/README.md index de1a7cf..0fa4573 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,10 @@ # BlankOS -Rewritten monolithic version of Blank OS for the x86 processor architecture. Features a framebuffer, serial port driver, GDT, IDT. The OS relies on an old, legacy version of GRUB as the bootloader (eltorito). This *should* be GRUB 2 compatible. Emulation was tested on Arch Linux 6.9.7-arch1-1. The long-term goal of this OS is to be capable of running user programs and having its own complete kernel C library so that users can write their own C programs to be ran using the kernel. +Rewritten monolithic version of Blank OS for the x86 processor architecture. Features a framebuffer, serial port driver, GDT, IDT. The OS relies on an old, legacy version of GRUB as the bootloader (eltorito). This *should* be GRUB 2 compatible. Emulation was tested on Arch Linux 6.9.7-arch1-1. The long-term goal of this OS is to be capable of running user programs and having its own complete kernel C library so that users can write their own C programs and expand the system! Next steps for this project will be: -- ISRs and making the PIC work -- Keyboard driver - User programs -- Shell -- Kernel libc +- Completing the kernel libc - Filesystem support ## Usage @@ -54,6 +51,10 @@ sudo dd bs=4M if=blankos.iso of=/dev/sdX status=progress oflag=sync Replace `sdX` with your USB drive name (you can find it by doing `sudo fdisk -l`). Tada! You now have a working BlankOS USB stick. Go ahead and try it out! +## Post-install guides + +Two documents are available to help you understand the project better. One is the User's Manual, labelled `USERS.md`, and the other one is the Developer's Manual, labelled `DEVELOPERS.md`. They are full of useful resources around Blank OS. + ### ⚠️ Disclaimer This is a hobbyist operating system kernel and it comes without any warranty whatsoever! It isn't capable of anything really. Feedback and contributions are highly appreciated! diff --git a/USERS.md b/USERS.md new file mode 100644 index 0000000..bf15b39 --- /dev/null +++ b/USERS.md @@ -0,0 +1,17 @@ +# Blank OS User's Manual + +## Getting started + +### Installation and emulation/execution + +Please refer to the relevant sections in the project `README.md` available in the root folder. + +### First steps + +Once you have launched the OS for the first time, you should first see the welcome banner with the system version. Then, the kernel shell will spawn and you will be able to execute commands. + +To get the list of available commands on the system, type `help`. + +## Next what? + +Once programs will be added, there will be more info here. For now you can just play around and make the kernel panic. That's it. diff --git a/iso/boot/kernel.elf b/iso/boot/kernel.elf index 5a127df..8602aa2 100755 Binary files a/iso/boot/kernel.elf and b/iso/boot/kernel.elf differ diff --git a/os.iso b/os.iso index 2f222c7..1eea564 100644 Binary files a/os.iso and b/os.iso differ diff --git a/src/kernel/kb.c b/src/kernel/kb.c index 437d0d8..77d3c31 100644 --- a/src/kernel/kb.c +++ b/src/kernel/kb.c @@ -4,6 +4,11 @@ #define KEYBOARD_BUFFER_SIZE 256 +#define LEFT_SHIFT_PRESSED 0x2A +#define RIGHT_SHIFT_PRESSED 0x36 +#define LEFT_SHIFT_RELEASED 0xAA +#define RIGHT_SHIFT_RELEASED 0xB6 + unsigned char kbdus[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ @@ -44,9 +49,50 @@ unsigned char kbdus[128] = 0, /* All other keys are undefined */ }; +unsigned char kbdus_shift[128] = +{ + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */ + '(', ')', '_', '+', '\b', /* Backspace */ + '\t', /* Tab */ + 'Q', 'W', 'E', 'R', /* 19 */ + 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter key */ + 0, /* 29 - Control */ + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */ + '"', '~', 0, /* Left shift */ + '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */ + 'M', '<', '>', '?', 0, /* Right shift */ + '*', + 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + 0, /* 59 - F1 key ... > */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* < ... F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + 0, /* Home key */ + 0, /* Up Arrow */ + 0, /* Page Up */ + '-', + 0, /* Left Arrow */ + 0, + 0, /* Right Arrow */ + '+', + 0, /* 79 - End key*/ + 0, /* Down Arrow */ + 0, /* Page Down */ + 0, /* Insert Key */ + 0, /* Delete Key */ + 0, 0, 0, + 0, /* F11 Key */ + 0, /* F12 Key */ + 0, /* All other keys are undefined */ +}; + static char keyboard_buffer[KEYBOARD_BUFFER_SIZE]; static unsigned int keyboard_buffer_start = 0; static unsigned int keyboard_buffer_end = 0; +static int shift_pressed = 0; void keyboard_handler() { @@ -56,14 +102,27 @@ void keyboard_handler() if (scancode & 0x80) { + if (scancode == LEFT_SHIFT_RELEASED || scancode == RIGHT_SHIFT_RELEASED) { + shift_pressed = 0; + } } else { - char c = kbdus[scancode]; - if (c) - { - keyboard_buffer[keyboard_buffer_end] = c; - keyboard_buffer_end = (keyboard_buffer_end+1) % KEYBOARD_BUFFER_SIZE; + if (scancode == LEFT_SHIFT_PRESSED || scancode == RIGHT_SHIFT_PRESSED) { + shift_pressed = 1; + } else { + char c; + if (shift_pressed) { + c = kbdus_shift[scancode]; + } else { + c = kbdus[scancode]; + } + + if (c) + { + keyboard_buffer[keyboard_buffer_end] = c; + keyboard_buffer_end = (keyboard_buffer_end+1) % KEYBOARD_BUFFER_SIZE; + } } } } diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index a382462..4371303 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -4,6 +4,15 @@ #include "idt.h" #include "system.h" +char* ascii_title = +"\n" +" oooooooooo o888 oooo ooooooo oooooooo8\n" +" 888 888 888 ooooooo oo oooooo 888 ooooo o888 888o 888 \n" +" 888oooo88 888 ooooo888 888 888 888o888 888 888 888oooooo \n" +" 888 888 888 888 888 888 888 8888 88o 888o o888 888\n" +" o888ooo888 o888o 88ooo88 8o o888o o888o o888o o888o 88ooo88 o88oooo888\n\n" +" --------------------------------- v0.3.31 --------------------------------\n\n"; + int kmain(int retvalue) { @@ -23,12 +32,10 @@ int kmain(int retvalue) clear(); - colorputs("Blank OS version 1 iteration 3 minor 20\n", 10); + colorputs(ascii_title, 10); - // TODO: Serial printf to dump registers on kernel panic - // TODO: Fix scrolling bug (framebuffer driver) - // TODO: Fix keyboard driver bug (some keys mapped weirdly) + add suport for SHIFT and backspace (deleting character) // TODO: Grub modules to load programs + //timer_install(); keyboard_install(); diff --git a/src/kernel/shell.c b/src/kernel/shell.c index ef5036a..d94cb2c 100644 --- a/src/kernel/shell.c +++ b/src/kernel/shell.c @@ -27,7 +27,7 @@ void shell_install() printf("%d", 4/0); } else { - puts("Unknown command\n"); + printf("Unknown command %s\n", input_buffer); } } } diff --git a/src/libc/stdio.c b/src/libc/stdio.c index 5749432..c356875 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -101,6 +101,17 @@ void putc(char c) VGA_Y++; } break; + case '\b': + if (VGA_X > 0) + { + VGA_X--; + } + else if (VGA_Y > 0) { + VGA_Y--; + VGA_X = VGA_WIDTH-1; + } + putchar(VGA_X, VGA_Y, ' '); + break; default: putchar(VGA_X, VGA_Y, c); VGA_X++; @@ -366,10 +377,19 @@ void get_input(char *buffer, int size) { while (index < size-1) { c = getch(); - if (c == '\n') break; - - buffer[index++] = c; - putc(c); + if (c == '\n') { + break; + } else if (c == '\b') { + if (index > 0) { + index--; + putc('\b'); + putc(' '); + putc('\b'); + } + } else { + buffer[index++] = c; + putc(c); + } } buffer[index] = '\0'; }