Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f45fbeb6 | ||
|
|
6f5c05e0d9 | ||
|
|
a4b036dfbd | ||
|
|
a316367236 | ||
|
|
93f5feff85 | ||
|
|
7c80cc8af9 | ||
|
|
88debf5085 | ||
|
|
449873f55d | ||
|
|
adcfdc8231 | ||
|
|
deafe2439b | ||
|
|
b1e4ef8ad2 |
19
README.md
19
README.md
@@ -1,8 +1,12 @@
|
|||||||

|

|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> The project is currently paused, after months of work around the subject. I've had enough for now, and I'll surely come back in some time to implement the more advanced stuff I had planned. For now, enjoy the latest alpha version.
|
||||||
|
> This is a hobbyist operating system, and it comes without any warranty whatsoever! See the license for more info. Feedback and contributions are highly appreciated.
|
||||||
|
|
||||||
# BlankOS
|
# BlankOS
|
||||||
|
|
||||||
Rewritten monolithic, ring 0, lower-half, singletasking kernel for the x86 processor architecture, using GRUB 2 as bootloader. Emulation was tested on QEMU using Arch Linux 6.9.7-arch1-1, and on real hardware too.
|
Rewritten monolithic, ring 0, lower-half, singletasking kernel for the x86 processor architecture, using GRUB 2 as bootloader. Emulation was tested on QEMU using Arch Linux 6.9.7-arch1-1, and on real hardware (UEFI and BIOS).
|
||||||
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!
|
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!
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -36,10 +40,11 @@ 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`).
|
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!
|
Tada! You now have a working BlankOS USB stick. Go ahead and try it out!
|
||||||
|
(*Might not work properly on monitors that aren't Full HD*)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](docs/USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](docs/DEVELOPERS.md). They are full of useful resources around Blank OS. You'll learn how to use the system and how to contribute to it. *(The docs might not always be up-to-date)*
|
Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](docs/USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](docs/DEVELOPERS.md). They are full of useful resources: you'll learn how to use the system and how to contribute to it. *(The docs might not always be up-to-date)*
|
||||||
|
|
||||||
### Resources
|
### Resources
|
||||||
|
|
||||||
@@ -56,11 +61,12 @@ Two other documents are available to help you understand the project better. One
|
|||||||
|
|
||||||
- [X] Booting with GRUB
|
- [X] Booting with GRUB
|
||||||
- [X] Common basic structures (IDT, GDT, ISRs, IRQs)
|
- [X] Common basic structures (IDT, GDT, ISRs, IRQs)
|
||||||
- [X] Common drivers (framebuffer, keyboard, serial, timer)
|
- [X] Common drivers (framebuffer, keyboard, serial, timer, RTC, ATA PIO)
|
||||||
- [X] Kernel-space utilities (shell, simple programs)
|
- [X] Kernel-space utilities (shell, simple programs)
|
||||||
- [ ] Filesystem (FAT32 or VFS ramdisk)
|
- [ ] Filesystem (FAT32 or VFS ramdisk)
|
||||||
- [ ] Changing the default VGA font
|
- [ ] Changing the default VGA font
|
||||||
- [X] Paging/Page Frame Allocation
|
- [ ] Dynamic memory allocator (get memmap from GRUB?)
|
||||||
|
- [ ] Paging/Page Frame Allocation
|
||||||
- [ ] TCP/IP Network stack
|
- [ ] TCP/IP Network stack
|
||||||
- [ ] Getting to Ring-3 (userspace)
|
- [ ] Getting to Ring-3 (userspace)
|
||||||
- [ ] Multitasking (via round robin scheduling)
|
- [ ] Multitasking (via round robin scheduling)
|
||||||
@@ -70,6 +76,3 @@ Two other documents are available to help you understand the project better. One
|
|||||||
- [ ] System calls
|
- [ ] System calls
|
||||||
- [ ] GUI
|
- [ ] GUI
|
||||||
- [ ] POSIX and ANSI specification compatibility
|
- [ ] POSIX and ANSI specification compatibility
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
> This is a hobbyist operating system, and it comes without any warranty whatsoever! See the license for more info. Feedback and contributions are highly appreciated.
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Blank OS Developer's Manual
|
# Blank OS Developer's Manual
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- Getting Started
|
||||||
|
- Writing programs for BlankOS
|
||||||
|
- Changing the TTY font
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
### System description
|
### System description
|
||||||
@@ -27,7 +33,9 @@ gdb kernel.elf
|
|||||||
(gdb) target remote localhost:1234
|
(gdb) target remote localhost:1234
|
||||||
```
|
```
|
||||||
|
|
||||||
## Making programs for the OS
|
## Writing programs for BlankOS
|
||||||
|
|
||||||
|
Be warned, these are not actual programs in the sense you'd expect. These are indeed functions that are called from the shell, and embedded in the kernel ELF binary. Real programs apart from the kernel are not yet a thing here, but might be one day.
|
||||||
|
|
||||||
### Step 1 - Making the program and the entry point
|
### Step 1 - Making the program and the entry point
|
||||||
|
|
||||||
@@ -86,4 +94,18 @@ The linking process should be taken care of by the appropriate Linker script `li
|
|||||||
|
|
||||||
If you're proud of what you've made, you can clone the repo, make your changes, open a pull request and maybe your program will be added to the main BlankOS repo, and later distributed in the new ISOs!
|
If you're proud of what you've made, you can clone the repo, make your changes, open a pull request and maybe your program will be added to the main BlankOS repo, and later distributed in the new ISOs!
|
||||||
|
|
||||||
|
## Changing the TTY font
|
||||||
|
|
||||||
|
In order to change the default font, first get your hands on a 8x16 `.psf` (PC Screen Font 2) formatted font. Then, put it in `include/fonts` and remove the default one (`UniCyr_8x16.psf`).
|
||||||
|
|
||||||
|
Go ahead and run `make` one time. The compilation/linking will fail because of unresolved symbols, but an object file should have been created in `build/fonts` with your custom font's name.
|
||||||
|
|
||||||
|
Read the symbols in that object file:
|
||||||
|
|
||||||
|
```
|
||||||
|
readelf -s -W build/fonts/YOUR_FONT_8x16.o
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the symbol name that ends with `_start` and replace all occurences of it in the `src/drivers/framebuffer.c` file.
|
||||||
|
|
||||||
|
Then, run `make` again and the font should have changed properly.
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Shows all of the available commands, which are explained here.
|
|||||||
|
|
||||||
#### `panic`
|
#### `panic`
|
||||||
|
|
||||||
Triggers a kernel panic by trying to divide four by zero.
|
Triggers a kernel panic by reserved exception.
|
||||||
|
|
||||||
#### `words`
|
#### `words`
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ Options:
|
|||||||
- `<nothing>` will default to `PRIMES_MAX` (a million)
|
- `<nothing>` will default to `PRIMES_MAX` (a million)
|
||||||
- `<integer>` will compute primes up to that number
|
- `<integer>` will compute primes up to that number
|
||||||
|
|
||||||
#### `rainbow`
|
#### `rainbow <string>`
|
||||||
|
|
||||||
Asks for text and then outputs it with different vibrant colors.
|
Asks for text and then outputs it with different vibrant colors.
|
||||||
|
|
||||||
@@ -77,11 +77,11 @@ A brainfuck interpreter with every instruction and default tape size (30k cells)
|
|||||||
|
|
||||||
Gets system uptime from the timer in ticks. Ticks are incremented at a rate of 18.222Hz (18.222 ticks per second).
|
Gets system uptime from the timer in ticks. Ticks are incremented at a rate of 18.222Hz (18.222 ticks per second).
|
||||||
|
|
||||||
#### `echo`
|
#### `echo <string>`
|
||||||
|
|
||||||
The classic echo command, that outputs your input.
|
The classic echo command, that outputs your input.
|
||||||
|
|
||||||
#### `sysinfo`
|
#### `sysinfo [option]`
|
||||||
|
|
||||||
Outputs information about the current system (CPU and RAM).
|
Outputs information about the current system (CPU and RAM).
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ Options:
|
|||||||
- `<nothing>` will show basic info about the CPUid and lower/upper memory.
|
- `<nothing>` will show basic info about the CPUid and lower/upper memory.
|
||||||
- `-v` will output the CPUID, lower/upper memory, and the memory map.
|
- `-v` will output the CPUID, lower/upper memory, and the memory map.
|
||||||
|
|
||||||
#### `conway`
|
#### `conway [option]`
|
||||||
|
|
||||||
A classic Game of Life implementation with standard rules and 100 generations.
|
A classic Game of Life implementation with standard rules and 100 generations.
|
||||||
|
|
||||||
@@ -98,14 +98,18 @@ Options:
|
|||||||
- `-g` will spawn a classic glider
|
- `-g` will spawn a classic glider
|
||||||
- `-l` will spawn a lightweight spaceship
|
- `-l` will spawn a lightweight spaceship
|
||||||
|
|
||||||
#### `rot13`
|
#### `rot13 <string>`
|
||||||
|
|
||||||
Encode a string using the rot13 cipher.
|
Encode a string using the rot13 cipher.
|
||||||
|
|
||||||
#### `morse`
|
#### `morse <string>`
|
||||||
|
|
||||||
Convert a string to its morse equivalent.
|
Convert a string to its morse equivalent.
|
||||||
|
|
||||||
#### `cowsay`
|
#### `cowsay <string>`
|
||||||
|
|
||||||
Makes a cow speak!
|
Makes a cow speak!
|
||||||
|
|
||||||
|
#### `pi <terms>`
|
||||||
|
|
||||||
|
Computes Pi up to a couple of digits using the Leibniz series; takes one integer argument, the number of terms of the series to compute.
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "paging.h"
|
|
||||||
#include "../drivers/ata.h"
|
#include "../drivers/ata.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../drivers/framebuffer.h"
|
#include "../drivers/framebuffer.h"
|
||||||
@@ -62,10 +61,7 @@ void kmain(multiboot2_info *mb_info)
|
|||||||
irq_install();
|
irq_install();
|
||||||
__asm__ __volatile__("sti");
|
__asm__ __volatile__("sti");
|
||||||
|
|
||||||
//init_paging();
|
|
||||||
//test_read_sector();
|
//test_read_sector();
|
||||||
//uint32_t *ptr = (uint32_t*)0xA0000000;
|
|
||||||
//uint32_t do_page_fault = *ptr;
|
|
||||||
|
|
||||||
timer_install();
|
timer_install();
|
||||||
keyboard_install();
|
keyboard_install();
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ global loader
|
|||||||
|
|
||||||
section .multiboot_header
|
section .multiboot_header
|
||||||
|
|
||||||
|
mb_start:
|
||||||
align 8
|
align 8
|
||||||
|
|
||||||
; ASM macros
|
; ASM macros
|
||||||
|
|
||||||
MAGIC_NUMBER equ 0xe85250d6 ; multiboot2 magic
|
MAGIC_NUMBER equ 0xe85250d6 ; multiboot2 magic
|
||||||
FLAGS equ 0x0 ; 32-bit protected mode for i386
|
FLAGS equ 0x0 ; 32-bit protected mode for i386
|
||||||
HEADER_LEN equ 44 ; Tags=2+2+4+4+4+4+2+2+4=28
|
HEADER_LEN equ mb_end-mb_start
|
||||||
CHECKSUM equ -(MAGIC_NUMBER + FLAGS + HEADER_LEN)
|
CHECKSUM equ -(MAGIC_NUMBER + FLAGS + HEADER_LEN)
|
||||||
|
|
||||||
; Multiboot 2 header, according to specification (16bytes)
|
; Multiboot 2 header, according to specification (16bytes)
|
||||||
@@ -26,7 +27,7 @@ CHECKSUM equ -(MAGIC_NUMBER + FLAGS + HEADER_LEN)
|
|||||||
; Tags? (28bytes)
|
; Tags? (28bytes)
|
||||||
|
|
||||||
; Tag 1 : set graphics mode (only recommended, can be overriden by GRUB)
|
; Tag 1 : set graphics mode (only recommended, can be overriden by GRUB)
|
||||||
|
align 8
|
||||||
dw 5 ; 2
|
dw 5 ; 2
|
||||||
dw 0 ; 2
|
dw 0 ; 2
|
||||||
dd 20 ; 4
|
dd 20 ; 4
|
||||||
@@ -36,11 +37,13 @@ CHECKSUM equ -(MAGIC_NUMBER + FLAGS + HEADER_LEN)
|
|||||||
|
|
||||||
; End of tags
|
; End of tags
|
||||||
|
|
||||||
|
align 8
|
||||||
|
dw 0 ; 2
|
||||||
dw 0 ; 2
|
dw 0 ; 2
|
||||||
;dw 0 ; 2
|
|
||||||
dd 8 ; 4
|
dd 8 ; 4
|
||||||
|
|
||||||
; End of Multiboot 2 header
|
; End of Multiboot 2 header
|
||||||
|
mb_end:
|
||||||
|
|
||||||
section .text:
|
section .text:
|
||||||
|
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
// Paging kernel module
|
|
||||||
// Author: xamidev
|
|
||||||
// Licensed under the Unlicense. See the repo below.
|
|
||||||
// https://github.com/xamidev/blankos
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "paging.h"
|
|
||||||
#include "../libc/stdio.h"
|
|
||||||
#include "system.h"
|
|
||||||
#include "kheap.h"
|
|
||||||
|
|
||||||
uint32_t *frames;
|
|
||||||
uint32_t nframes;
|
|
||||||
|
|
||||||
extern uint32_t placement_address;
|
|
||||||
|
|
||||||
static void set_frame(uint32_t frame_addr)
|
|
||||||
{
|
|
||||||
uint32_t frame = frame_addr/0x1000;
|
|
||||||
uint32_t idx = INDEX_FROM_BIT(frame);
|
|
||||||
uint32_t off = OFFSET_FROM_BIT(frame);
|
|
||||||
frames[idx] |= (0x1 << off);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_frame(uint32_t frame_addr)
|
|
||||||
{
|
|
||||||
uint32_t frame = frame_addr/0x1000;
|
|
||||||
uint32_t idx = INDEX_FROM_BIT(frame);
|
|
||||||
uint32_t off = OFFSET_FROM_BIT(frame);
|
|
||||||
frames[idx] &= ~(0x1 << off);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static uint32_t test_frame(uint32_t frame_addr)
|
|
||||||
{
|
|
||||||
uint32_t frame = frame_addr/0x1000;
|
|
||||||
uint32_t idx = INDEX_FROM_BIT(frame);
|
|
||||||
uint32_t off = OFFSET_FROM_BIT(frame);
|
|
||||||
return (frames[idx] & (0x1 << off));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static uint32_t first_frame()
|
|
||||||
{
|
|
||||||
uint32_t i, j;
|
|
||||||
for (i=0; i<INDEX_FROM_BIT(nframes); i++)
|
|
||||||
{
|
|
||||||
if (frames[i] != 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
for (j=0; j<32; j++)
|
|
||||||
{
|
|
||||||
uint32_t toTest = 0x1 << j;
|
|
||||||
if (!(frames[i]&toTest))
|
|
||||||
{
|
|
||||||
return i*4*8+j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void alloc_frame(page_t *page, int is_kernel, int is_writeable)
|
|
||||||
{
|
|
||||||
if (page->frame != 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
uint32_t idx = first_frame();
|
|
||||||
if (idx == (uint32_t)-1)
|
|
||||||
{
|
|
||||||
panic();
|
|
||||||
}
|
|
||||||
set_frame(idx*0x1000);
|
|
||||||
page->present = 1;
|
|
||||||
page->rw = (is_writeable)?1:0;
|
|
||||||
page->user = (is_kernel)?0:1;
|
|
||||||
page->frame = idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_frame(page_t *page)
|
|
||||||
{
|
|
||||||
uint32_t frame;
|
|
||||||
if (!(frame=page->frame))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
clear_frame(frame);
|
|
||||||
page->frame = 0x0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_paging()
|
|
||||||
{
|
|
||||||
uint32_t mem_end_page = 0x10000000;
|
|
||||||
nframes = mem_end_page / 0x1000;
|
|
||||||
frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes));
|
|
||||||
memset(frames, 0, INDEX_FROM_BIT(nframes));
|
|
||||||
|
|
||||||
page_directory_t* kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t));
|
|
||||||
memset(kernel_directory, 0, sizeof(page_directory_t));
|
|
||||||
//page_directory_t* current_directory = kernel_directory;
|
|
||||||
|
|
||||||
unsigned int i = 0;
|
|
||||||
while (i < placement_address)
|
|
||||||
{
|
|
||||||
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
|
|
||||||
i += 0x1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
irq_install_handler(14, page_fault);
|
|
||||||
|
|
||||||
switch_page_directory(kernel_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void switch_page_directory(page_directory_t *dir)
|
|
||||||
{
|
|
||||||
//page_directory_t* current_directory = dir;
|
|
||||||
asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
|
|
||||||
uint32_t cr0;
|
|
||||||
asm volatile("mov %%cr0, %0": "=r"(cr0));
|
|
||||||
cr0 |= 0x80000000;
|
|
||||||
asm volatile("mov %0, %%cr0":: "r"(cr0));
|
|
||||||
}
|
|
||||||
|
|
||||||
page_t *get_page(uint32_t address, int make, page_directory_t *dir)
|
|
||||||
{
|
|
||||||
address /= 0x1000;
|
|
||||||
uint32_t table_idx = address / 1024;
|
|
||||||
if (dir->tables[table_idx])
|
|
||||||
{
|
|
||||||
return &dir->tables[table_idx]->pages[address%1024];
|
|
||||||
} else if (make)
|
|
||||||
{
|
|
||||||
uint32_t tmp;
|
|
||||||
dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), &tmp);
|
|
||||||
memset(dir->tables[table_idx], 0, 0x1000);
|
|
||||||
dir->tablesPhysical[table_idx] = tmp | 0x7;
|
|
||||||
return &dir->tables[table_idx]->pages[address%1024];
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void page_fault()
|
|
||||||
{
|
|
||||||
puts("Page fault");
|
|
||||||
panic();
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// Paging kernel module header
|
|
||||||
// Author: xamidev
|
|
||||||
// Licensed under the Unlicense. See the repo below.
|
|
||||||
// https://github.com/xamidev/blankos
|
|
||||||
|
|
||||||
#ifndef PAGING_H
|
|
||||||
#define PAGING_H
|
|
||||||
|
|
||||||
#include "system.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define INDEX_FROM_BIT(a) (a/(8*4))
|
|
||||||
#define OFFSET_FROM_BIT(a) (a%(8*4))
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t present : 1;
|
|
||||||
uint32_t rw : 1;
|
|
||||||
uint32_t user : 1;
|
|
||||||
uint32_t accessed : 1;
|
|
||||||
uint32_t dirty : 1;
|
|
||||||
uint32_t unused : 7;
|
|
||||||
uint32_t frame : 20;
|
|
||||||
} page_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
page_t pages[1024];
|
|
||||||
} page_table_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
page_table_t *tables[1024];
|
|
||||||
uint32_t tablesPhysical[1024];
|
|
||||||
uint32_t physicalAsddr;
|
|
||||||
} page_directory_t;
|
|
||||||
|
|
||||||
void init_paging();
|
|
||||||
void switch_page_directory(page_directory_t *new);
|
|
||||||
page_t *get_page(uint32_t address, int make, page_directory_t *dir);
|
|
||||||
void page_fault();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -12,25 +12,49 @@
|
|||||||
#include "../drivers/rtc.h"
|
#include "../drivers/rtc.h"
|
||||||
|
|
||||||
#define BUFFER_SIZE 256
|
#define BUFFER_SIZE 256
|
||||||
#define MAX_COMMANDS 16
|
#define MAX_COMMANDS 64
|
||||||
#define MAX_ARGS 64
|
#define MAX_ARGS 64
|
||||||
|
|
||||||
// Splash screen: esthetic stuff.
|
// Splash screen: esthetic stuff.
|
||||||
|
char* motd[] =
|
||||||
char* motd[] =
|
|
||||||
{
|
{
|
||||||
|
"I should be root, really.",
|
||||||
|
"Not watching you!",
|
||||||
"Now in 2D!",
|
"Now in 2D!",
|
||||||
"Supercalifragilisticexpialidocious!",
|
"Supercalifragilisticexpialidocious!",
|
||||||
"Tylko jedno w glowie mam!",
|
"Tylko jedno w glowie mam!",
|
||||||
|
"Greetings, magic poppy!",
|
||||||
|
"I'm stuck in this kernel's shell, get me out!",
|
||||||
|
"And now, solve that equation!",
|
||||||
|
"Powered by TCC Incorporated.",
|
||||||
|
"Compiled at 69, CoquaineBaule Ave.",
|
||||||
|
"Shouldn't we be, uh, doing something?",
|
||||||
|
"We are the florists, we pick the plants!",
|
||||||
|
"Lalalalala, I pick the plants!",
|
||||||
|
"Woah, we're half-way there...",
|
||||||
|
"The CROU will never die!",
|
||||||
|
"Technoblade never dies!",
|
||||||
|
"Hi. My name is Guitar.",
|
||||||
|
"space station No. 9",
|
||||||
|
"May the orange juice be with you !",
|
||||||
|
"Bloody grated carrots!",
|
||||||
|
"Good night, kiddos...",
|
||||||
|
"I like trains",
|
||||||
|
"I fear planes",
|
||||||
|
"Bruteforce.exe",
|
||||||
|
"Ohayogozaimasu!",
|
||||||
};
|
};
|
||||||
|
|
||||||
int motd_size = sizeof(motd)/sizeof(motd[0]);
|
int motd_size = sizeof(motd)/sizeof(motd[0]);
|
||||||
|
|
||||||
|
bool do_splash = true;
|
||||||
|
|
||||||
void splash()
|
void splash()
|
||||||
{
|
{
|
||||||
int random = randint(time_seed());
|
int random = randint(time_seed());
|
||||||
char* motd_pick = motd[random%motd_size];
|
char* motd_pick = motd[random%motd_size];
|
||||||
cowsay(motd_pick, red, black);
|
cowsay(motd_pick, red, black);
|
||||||
colorputs(" blankOS 0.3.86-alpha", red, black);
|
colorputs(" blankOS 0.3.97-alpha", red, black);
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
|
||||||
|
|
||||||
@@ -87,7 +111,11 @@ int parse_input(char* input, char* argv[], int max_args)
|
|||||||
|
|
||||||
void shell_install()
|
void shell_install()
|
||||||
{
|
{
|
||||||
splash();
|
if (do_splash == true)
|
||||||
|
{
|
||||||
|
do_splash = false;
|
||||||
|
splash();
|
||||||
|
}
|
||||||
|
|
||||||
register_command("help", program_help);
|
register_command("help", program_help);
|
||||||
register_command("panic", program_panic);
|
register_command("panic", program_panic);
|
||||||
@@ -104,6 +132,10 @@ void shell_install()
|
|||||||
register_command("rot13", program_rot13);
|
register_command("rot13", program_rot13);
|
||||||
register_command("morse", program_morse);
|
register_command("morse", program_morse);
|
||||||
register_command("cowsay", program_cowsay);
|
register_command("cowsay", program_cowsay);
|
||||||
|
register_command("time", program_time);
|
||||||
|
register_command("read", program_read);
|
||||||
|
register_command("reboot", program_reboot);
|
||||||
|
register_command("pi", program_pi);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,12 +56,35 @@ void dtostrf(double val, char *buffer, int precision);
|
|||||||
enum Colors
|
enum Colors
|
||||||
{
|
{
|
||||||
// AARRGGBB?
|
// AARRGGBB?
|
||||||
white = 0xFFFFFFFF,
|
white = 0xFFFFFFFF,
|
||||||
black = 0x00000000,
|
black = 0x00000000,
|
||||||
red = 0x00FF0000,
|
red = 0x00FF0000,
|
||||||
green = 0x0000FF00,
|
green = 0x0000FF00,
|
||||||
blue = 0x000000FF,
|
blue = 0x000000FF,
|
||||||
yellow = 0x00FFFF00,
|
yellow = 0x00FFFF00,
|
||||||
|
cyan = 0x0000FFFF,
|
||||||
|
magenta = 0x00FF00FF,
|
||||||
|
orange = 0x00FFA500,
|
||||||
|
purple = 0x00800080,
|
||||||
|
brown = 0x00A52A2A,
|
||||||
|
gray = 0x00808080,
|
||||||
|
pink = 0x00FFC0CB,
|
||||||
|
lime = 0x00BFFF00,
|
||||||
|
navy = 0x00000080,
|
||||||
|
teal = 0x00008080,
|
||||||
|
maroon = 0x00800000,
|
||||||
|
olive = 0x00808000,
|
||||||
|
silver = 0x00C0C0C0,
|
||||||
|
gold = 0x00FFD700,
|
||||||
|
indigo = 0x004B0082,
|
||||||
|
violet = 0x00EE82EE,
|
||||||
|
coral = 0x00FF7F50,
|
||||||
|
turquoise = 0x0040E0D0,
|
||||||
|
salmon = 0x00FA8072,
|
||||||
|
chocolate = 0x00D2691E,
|
||||||
|
khaki = 0x00F0E68C,
|
||||||
|
lavender = 0x00E6E6FA,
|
||||||
|
beige = 0x00F5F5DC
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,14 +29,27 @@ void rot13(char* input, char* output)
|
|||||||
output[i] = '\0';
|
output[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_rot13()
|
void program_rot13(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
char input_buffer[BUFFER_SIZE];
|
if (argc < 2)
|
||||||
char output[BUFFER_SIZE];
|
{
|
||||||
puts("String? ");
|
printf("Usage: %s <string>\n", argv[0]);
|
||||||
get_input(input_buffer, BUFFER_SIZE);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char input_buffer[BUFFER_SIZE] = {0};
|
||||||
|
char output[BUFFER_SIZE] = {0};
|
||||||
|
|
||||||
|
for (int i=1; i<argc; i++)
|
||||||
|
{
|
||||||
|
strcat(input_buffer, argv[i]);
|
||||||
|
if (i<argc-1)
|
||||||
|
{
|
||||||
|
strcat(input_buffer, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
rot13(input_buffer, output);
|
rot13(input_buffer, output);
|
||||||
printf("\n%s\n", output);
|
printf("%s\n", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* morse_alphabet[] = {
|
const char* morse_alphabet[] = {
|
||||||
@@ -121,12 +134,27 @@ void to_morse(const char* input, char* output) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_morse() {
|
void program_morse(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <string>\n", argv[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char output[512];
|
char output[512];
|
||||||
char input_buffer[BUFFER_SIZE];
|
char message[BUFFER_SIZE];
|
||||||
puts("String? ");
|
|
||||||
get_input(input_buffer, BUFFER_SIZE);
|
for (int i=1; i<argc; i++)
|
||||||
to_morse(input_buffer, output);
|
{
|
||||||
printf("\n%s\n", output);
|
strcat(message, argv[i]);
|
||||||
|
if (i < argc-1)
|
||||||
|
{
|
||||||
|
strcat(message, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_morse(message, output);
|
||||||
|
printf("%s\n", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,22 +7,46 @@
|
|||||||
#include "../kernel/system.h"
|
#include "../kernel/system.h"
|
||||||
#include "../libc/string.h"
|
#include "../libc/string.h"
|
||||||
#include "../drivers/framebuffer.h"
|
#include "../drivers/framebuffer.h"
|
||||||
|
#include "../drivers/ata.h"
|
||||||
|
#include "../drivers/rtc.h"
|
||||||
|
#include "../kernel/io.h"
|
||||||
|
|
||||||
// Print a rainbow colorful text for testing
|
// Print a rainbow colorful text for testing
|
||||||
|
|
||||||
#define BUF_SIZE 256
|
#define BUF_SIZE 256
|
||||||
#define COLORS 20
|
#define COLORS 20
|
||||||
|
|
||||||
void program_rainbow()
|
void program_rainbow(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
char input_buffer[BUF_SIZE];
|
if (argc < 2)
|
||||||
puts("What to print? ");
|
|
||||||
get_input(input_buffer, BUF_SIZE);
|
|
||||||
puts("\n");
|
|
||||||
|
|
||||||
for (int i=0; i<COLORS; i++)
|
|
||||||
{
|
{
|
||||||
//colorputs(input_buffer, i);
|
printf("Usage: %s <string>\n", argv[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char input_buffer[BUF_SIZE] = {0};
|
||||||
|
for (int i=1; i<argc; i++)
|
||||||
|
{
|
||||||
|
strcat(input_buffer, argv[i]);
|
||||||
|
if (i<argc-1)
|
||||||
|
{
|
||||||
|
strcat(input_buffer, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Colors colors[] = {
|
||||||
|
white, black, red, green, blue, yellow,
|
||||||
|
cyan, magenta, orange, purple, brown,
|
||||||
|
gray, pink, lime, navy, teal, maroon,
|
||||||
|
olive, silver, gold, indigo, violet,
|
||||||
|
coral, turquoise, salmon, chocolate,
|
||||||
|
khaki, lavender, beige
|
||||||
|
};
|
||||||
|
int colors_count = sizeof(colors)/sizeof(colors[0]);
|
||||||
|
|
||||||
|
for (int i=0; i<colors_count-1; i++)
|
||||||
|
{
|
||||||
|
colorputs(input_buffer, colors[i], colors[i+1]);
|
||||||
puts("\n");
|
puts("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +73,7 @@ void program_uptime()
|
|||||||
|
|
||||||
void program_help()
|
void program_help()
|
||||||
{
|
{
|
||||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay\n");
|
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panic
|
// Panic
|
||||||
@@ -72,3 +96,50 @@ void program_echo(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
puts("\n");
|
puts("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get current RTC time
|
||||||
|
|
||||||
|
void program_time()
|
||||||
|
{
|
||||||
|
rtc_time_t time;
|
||||||
|
rtc_read_time(&time);
|
||||||
|
puts("Current RTC time: ");
|
||||||
|
print_time(&time);
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a sector
|
||||||
|
|
||||||
|
void program_read(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <sector>\n", argv[0]);
|
||||||
|
} else if (argc == 2)
|
||||||
|
{
|
||||||
|
uint8_t buffer[512];
|
||||||
|
ata_read_sector(atoi(argv[1]), buffer);
|
||||||
|
|
||||||
|
for (int i=0; i<512; i++)
|
||||||
|
{
|
||||||
|
if (i%50==0) puts("\n"); // hardcoded = bad
|
||||||
|
printf("%02x ", buffer[i]);
|
||||||
|
}
|
||||||
|
puts("\n");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
puts("Invalid argument number\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reboots the machine (might just shutdown)
|
||||||
|
|
||||||
|
void program_reboot()
|
||||||
|
{
|
||||||
|
puts("Rebooting...\n");
|
||||||
|
|
||||||
|
while(inb(0x64) & 0x02);
|
||||||
|
outb(0x64, 0xFE);
|
||||||
|
|
||||||
|
while (1) asm volatile("hlt");
|
||||||
|
}
|
||||||
|
|||||||
34
src/programs/pi.c
Normal file
34
src/programs/pi.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// Program for Pi computation using Leibniz series
|
||||||
|
// Author: xamidev
|
||||||
|
// Licensed under the Unlicense. See the repo below.
|
||||||
|
// https://github.com/xamidev/blankos
|
||||||
|
|
||||||
|
#include "../libc/stdio.h"
|
||||||
|
#include "../libc/string.h"
|
||||||
|
|
||||||
|
void program_pi(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <terms>\n", argv[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double pi = 0.0;
|
||||||
|
int terms = atoi(argv[1]);
|
||||||
|
|
||||||
|
for (int i=0; i<terms; i++)
|
||||||
|
{
|
||||||
|
double term = 1.0/(2*i+1);
|
||||||
|
if (i%2 == 0)
|
||||||
|
{
|
||||||
|
pi += term;
|
||||||
|
} else {
|
||||||
|
pi -= term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pi *= 4;
|
||||||
|
|
||||||
|
printf("%f\n", pi);
|
||||||
|
}
|
||||||
@@ -31,9 +31,12 @@ void program_primes(int argc, char* argv[])
|
|||||||
|
|
||||||
for (long long x=0; x<primes_max; x++)
|
for (long long x=0; x<primes_max; x++)
|
||||||
{
|
{
|
||||||
if (isPrime(x))
|
if (isPrime(x) && x != 3301)
|
||||||
{
|
{
|
||||||
printf("%d ", x);
|
printf("%d ", x);
|
||||||
|
} else if(x == 3301)
|
||||||
|
{
|
||||||
|
colorputs("3301 ", red, black);
|
||||||
}
|
}
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ void get_meminfo(unsigned int multiboot_info_address);
|
|||||||
void program_conway();
|
void program_conway();
|
||||||
void program_cowsay();
|
void program_cowsay();
|
||||||
void cowsay(); // Splash screen
|
void cowsay(); // Splash screen
|
||||||
|
void program_pi();
|
||||||
|
|
||||||
// Ciphers
|
// Ciphers
|
||||||
void program_rot13();
|
void program_rot13();
|
||||||
@@ -29,5 +30,8 @@ void program_uptime();
|
|||||||
void program_panic();
|
void program_panic();
|
||||||
void program_help();
|
void program_help();
|
||||||
void program_echo();
|
void program_echo();
|
||||||
|
void program_time();
|
||||||
|
void program_read();
|
||||||
|
void program_reboot();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ void get_cpuid()
|
|||||||
printf("CPU information\n\tvendor: %s\n\tfamily: %u\n\tmodel: %u\n\tfeatures: 0x%x\n", vendor, family, model, edx);
|
printf("CPU information\n\tvendor: %s\n\tfamily: %u\n\tmodel: %u\n\tfeatures: 0x%x\n", vendor, family, model, edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not really working anymore as it was made for multiboot1, now using multiboot2
|
||||||
void get_meminfo(unsigned int multiboot_info_address, int verbose)
|
void get_meminfo(unsigned int multiboot_info_address, int verbose)
|
||||||
{
|
{
|
||||||
// RAM
|
// RAM
|
||||||
@@ -56,13 +57,15 @@ void get_meminfo(unsigned int multiboot_info_address, int verbose)
|
|||||||
|
|
||||||
while ((unsigned int)mmap < multiboot_info_address + *((unsigned int*)(multiboot_info_address + 40)))
|
while ((unsigned int)mmap < multiboot_info_address + *((unsigned int*)(multiboot_info_address + 40)))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (mmap->length_high != 0 && mmap->length_low != 0)
|
if (mmap->length_high != 0 && mmap->length_low != 0)
|
||||||
{
|
{*/
|
||||||
printf("0x%x%x | 0x%x%x | %u\n",
|
printf("0x%x%x | 0x%x%x | %u\n",
|
||||||
mmap->base_addr_high, mmap->base_addr_low,
|
mmap->base_addr_high, mmap->base_addr_low,
|
||||||
mmap->length_high, mmap->length_low,
|
mmap->length_high, mmap->length_low,
|
||||||
mmap->type);
|
mmap->type);
|
||||||
}
|
//}
|
||||||
|
|
||||||
mmap = (multiboot_memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
|
mmap = (multiboot_memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user