Add: morse, rot13, and more docs
This commit is contained in:
@@ -10,14 +10,67 @@ Blank OS runs on a monolithic kernel booted by a 3rd party bootloader; GRUB (who
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
### System calls
|
||||||
|
|
||||||
|
No system calls are available, as the OS runs in kernel-space.
|
||||||
|
|
||||||
## Making programs for the OS
|
## Making programs for the OS
|
||||||
|
|
||||||
### Programming
|
### Step 1 - Making the program and the entry point
|
||||||
|
|
||||||
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.
|
To make a program for the OS, first create the appropriate C source file and header file in the `src/programs` subfolder. Name it appropriately, for example `myprogram.c`.
|
||||||
|
|
||||||
More on that soon.
|
In this file, you will put the functions your program will use. The entry point for the program should be a void function named `program_<PROGRAM_NAME>`. The entry point can either take no arguments, or use the classic argc/argv structure.
|
||||||
|
|
||||||
|
Valid examples for entry points include:
|
||||||
|
|
||||||
|
```
|
||||||
|
void program_myprogram()
|
||||||
|
void program_myprogram(void)
|
||||||
|
void program_myprogram(int argc, char* argv[])
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, code your stuff freely. The entry point function will basically be the "main" function of your program, like in a regular C file. You can make your own header file too, for example `myprogram.h`.
|
||||||
|
Keep in mind that the standard C library is not available here, so you'll have to use functions from the BlankOS C library, which is located in `src/libc`. Also feel free to look at the header files in `src/drivers` and `src/kernel`, there might be interesting functions in there too (managing input/output devices, the timer, etc..)
|
||||||
|
|
||||||
|
### Step 2 - Registering the program
|
||||||
|
|
||||||
|
Now that your program is done, you will need to make it a part of the OS.
|
||||||
|
|
||||||
|
#### General program header file registering
|
||||||
|
|
||||||
|
To make the entry point function reachable from the shell, you first have to include it in the general programs header file located in `src/programs/programs.h`.
|
||||||
|
|
||||||
|
Put the entry point function prototype in that file. A valid example might be:
|
||||||
|
|
||||||
|
```
|
||||||
|
void program_myprogram(int argc, char* argv[]);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Shell command registering
|
||||||
|
|
||||||
|
Now that your entry point is reachable from the shell source file, you'll have to register it as a command. To do that, locate the section in `src/kernel/shell.c`, in the very beginning of the `shell_install()` function that has a lot of similar lines to the one below:
|
||||||
|
|
||||||
|
```
|
||||||
|
register_command("myprogram", program_myprogram);
|
||||||
|
```
|
||||||
|
|
||||||
|
Add one of these lines for your entry point and the command name you'd like. (like the line above). First argument is the desired command name, and second argument is the entry point for your program.
|
||||||
|
|
||||||
|
Don't make your command name too long, preferably a few characters, like the other ones.
|
||||||
|
|
||||||
|
#### Help utility registering (optional)
|
||||||
|
|
||||||
|
Finally, you can add your command to the list of available commands by adding it to the `printf` call in the `src/programs/misc.c` source file, in the function `program_help()`.
|
||||||
|
|
||||||
|
If possible make sure that the new command name is aligned with the other ones.
|
||||||
|
|
||||||
|
### Step 3 - Compiling and linking
|
||||||
|
|
||||||
|
The linking process should be taken care by the appropriate Linker script `link.ld` and the Makefile instructions and targets. Nothing should be changed in those files, and your source files should be added automatically.
|
||||||
|
|
||||||
|
### Step 4 - Contributing to the project (optional)
|
||||||
|
|
||||||
|
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!
|
||||||
|
|
||||||
### Compiling and linking
|
|
||||||
|
|
||||||
The linking process should be taken care by the appropriate Linker script `link.ld` and the Makefile instructions and targets.
|
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# BlankOS
|
# BlankOS
|
||||||
|
|
||||||
Rewritten monolithic version of Blank OS for the x86 processor architecture. The OS relies on an old, legacy version of GRUB as the bootloader (eltorito). This *should* be GRUB 2 compatible. Emulation was tested on Bochs and QEMU using Arch Linux 6.9.7-arch1-1, and on real hardware too.
|
Rewritten monolithic, ring 0, lower-half, single-threaded kernel for the x86 processor architecture, using GRUB (eltorito) as bootloader. Emulation was tested on Bochs and QEMU using Arch Linux 6.9.7-arch1-1, and on real hardware too.
|
||||||
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!
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@@ -17,6 +17,14 @@ The long-term goal of this OS is to be capable of running user programs and havi
|
|||||||
- Cool color output!!
|
- Cool color output!!
|
||||||
- Some small working kernel-space programs!!
|
- Some small working kernel-space programs!!
|
||||||
|
|
||||||
|
### Kernel-space programs
|
||||||
|
|
||||||
|
- A brainfuck interpreter
|
||||||
|
- An arithmetic calculator
|
||||||
|
- ROT13 and Morse cipher programs
|
||||||
|
- Conway's Game of Life
|
||||||
|
- And some more...
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Download the latest BlankOS ISO image from the "Releases" tab, and emulate it directly using the QEMU emulator:
|
Download the latest BlankOS ISO image from the "Releases" tab, and emulate it directly using the QEMU emulator:
|
||||||
|
|||||||
14
USERS.md
14
USERS.md
@@ -56,7 +56,11 @@ The classic echo command, that outputs your input.
|
|||||||
|
|
||||||
#### `sysinfo`
|
#### `sysinfo`
|
||||||
|
|
||||||
Outputs information about the current system. Calling the command without options will show basic info about the CPUid and the lower/upper memory. To show the full memory map, use the verbose flag `-v`.
|
Outputs information about the current system (CPU and RAM).
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `nothing` will show basic info about the CPUid and lower/upper memory.
|
||||||
|
- `-v` will output the CPUID, lower/upper memory, and the memory map.
|
||||||
|
|
||||||
#### `conway`
|
#### `conway`
|
||||||
|
|
||||||
@@ -66,3 +70,11 @@ Options:
|
|||||||
- `<nothing>` will spawn a random soup of cells
|
- `<nothing>` will spawn a random soup of cells
|
||||||
- `-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`
|
||||||
|
|
||||||
|
Encode a string using the rot13 cipher.
|
||||||
|
|
||||||
|
#### `morse`
|
||||||
|
|
||||||
|
Convert a string to its morse equivalent.
|
||||||
|
|||||||
Binary file not shown.
@@ -66,6 +66,8 @@ void shell_install()
|
|||||||
register_command("echo", program_echo);
|
register_command("echo", program_echo);
|
||||||
register_command("sysinfo", program_sysinfo);
|
register_command("sysinfo", program_sysinfo);
|
||||||
register_command("conway", program_conway);
|
register_command("conway", program_conway);
|
||||||
|
register_command("rot13", program_rot13);
|
||||||
|
register_command("morse", program_morse);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
128
src/programs/ciphers.c
Normal file
128
src/programs/ciphers.c
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
#include "../libc/stdio.h"
|
||||||
|
#include "ciphers.h"
|
||||||
|
|
||||||
|
void rot13(char* input, char* output)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (input[i] != '\0')
|
||||||
|
{
|
||||||
|
char c = input[i];
|
||||||
|
|
||||||
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
output[i] = ((c - 'a' + 13) % 26) + 'a';
|
||||||
|
} else if (c >= 'A' && c <= 'Z') {
|
||||||
|
output[i] = ((c - 'A' + 13) % 26) + 'A';
|
||||||
|
} else {
|
||||||
|
output[i] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
output[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void program_rot13()
|
||||||
|
{
|
||||||
|
char input_buffer[BUFFER_SIZE];
|
||||||
|
char output[BUFFER_SIZE];
|
||||||
|
puts("String? ");
|
||||||
|
get_input(input_buffer, BUFFER_SIZE);
|
||||||
|
rot13(input_buffer, output);
|
||||||
|
printf("\n%s\n", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../libc/string.h"
|
||||||
|
#include "../libc/stdint.h"
|
||||||
|
|
||||||
|
const char* morse_alphabet[] = {
|
||||||
|
".-", // A
|
||||||
|
"-...", // B
|
||||||
|
"-.-.", // C
|
||||||
|
"-..", // D
|
||||||
|
".", // E
|
||||||
|
"..-.", // F
|
||||||
|
"--.", // G
|
||||||
|
"....", // H
|
||||||
|
"..", // I
|
||||||
|
".---", // J
|
||||||
|
"-.-", // K
|
||||||
|
".-..", // L
|
||||||
|
"--", // M
|
||||||
|
"-.", // N
|
||||||
|
"---", // O
|
||||||
|
".--.", // P
|
||||||
|
"--.-", // Q
|
||||||
|
".-.", // R
|
||||||
|
"...", // S
|
||||||
|
"-", // T
|
||||||
|
"..-", // U
|
||||||
|
"...-", // V
|
||||||
|
".--", // W
|
||||||
|
"-..-", // X
|
||||||
|
"-.--", // Y
|
||||||
|
"--.." // Z
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* morse_digits[] = {
|
||||||
|
"-----", // 0
|
||||||
|
".----", // 1
|
||||||
|
"..---", // 2
|
||||||
|
"...--", // 3
|
||||||
|
"....-", // 4
|
||||||
|
".....", // 5
|
||||||
|
"-....", // 6
|
||||||
|
"--...", // 7
|
||||||
|
"---..", // 8
|
||||||
|
"----." // 9
|
||||||
|
};
|
||||||
|
|
||||||
|
void to_morse(const char* input, char* output) {
|
||||||
|
int i = 0;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while (input[i] != '\0') {
|
||||||
|
char c = input[i];
|
||||||
|
|
||||||
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
const char* morse_code = morse_alphabet[c - 'a'];
|
||||||
|
int j = 0;
|
||||||
|
while (morse_code[j] != '\0') {
|
||||||
|
output[pos++] = morse_code[j++];
|
||||||
|
}
|
||||||
|
} else if (c >= 'A' && c <= 'Z') {
|
||||||
|
const char* morse_code = morse_alphabet[c - 'A'];
|
||||||
|
int j = 0;
|
||||||
|
while (morse_code[j] != '\0') {
|
||||||
|
output[pos++] = morse_code[j++];
|
||||||
|
}
|
||||||
|
} else if (c >= '0' && c <= '9') {
|
||||||
|
const char* morse_code = morse_digits[c - '0'];
|
||||||
|
int j = 0;
|
||||||
|
while (morse_code[j] != '\0') {
|
||||||
|
output[pos++] = morse_code[j++];
|
||||||
|
}
|
||||||
|
} else if (c == ' ') {
|
||||||
|
output[pos++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
output[pos++] = ' ';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos > 0) {
|
||||||
|
output[pos - 1] = '\0';
|
||||||
|
} else {
|
||||||
|
output[pos] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void program_morse() {
|
||||||
|
char output[512];
|
||||||
|
char input_buffer[BUFFER_SIZE];
|
||||||
|
puts("String? ");
|
||||||
|
get_input(input_buffer, BUFFER_SIZE);
|
||||||
|
to_morse(input_buffer, output);
|
||||||
|
printf("\n%s\n", output);
|
||||||
|
}
|
||||||
|
|
||||||
6
src/programs/ciphers.h
Normal file
6
src/programs/ciphers.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef CIPHERS_H
|
||||||
|
#define CIPHERS_H
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 256
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -45,7 +45,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\n");
|
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panic
|
// Panic
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ void get_cpuid();
|
|||||||
void get_meminfo(unsigned int multiboot_info_address);
|
void get_meminfo(unsigned int multiboot_info_address);
|
||||||
void program_conway();
|
void program_conway();
|
||||||
|
|
||||||
|
// Ciphers
|
||||||
|
void program_rot13();
|
||||||
|
void program_morse();
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
void program_rainbow();
|
void program_rainbow();
|
||||||
void program_clear();
|
void program_clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user