Add: morse, rot13, and more docs

This commit is contained in:
xamidev
2024-08-11 11:05:38 +02:00
parent 00b131fa72
commit 5ca49cefd0
10 changed files with 221 additions and 8 deletions

View File

@@ -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.
### System calls
No system calls are available, as the OS runs in kernel-space.
## 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.

View File

@@ -2,7 +2,7 @@
# 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!
## 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!!
- 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
Download the latest BlankOS ISO image from the "Releases" tab, and emulate it directly using the QEMU emulator:

View File

@@ -56,7 +56,11 @@ The classic echo command, that outputs your input.
#### `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`
@@ -66,3 +70,11 @@ Options:
- `<nothing>` will spawn a random soup of cells
- `-g` will spawn a classic glider
- `-l` will spawn a lightweight spaceship
#### `rot13`
Encode a string using the rot13 cipher.
#### `morse`
Convert a string to its morse equivalent.

BIN
com1.out

Binary file not shown.

Binary file not shown.

View File

@@ -66,6 +66,8 @@ void shell_install()
register_command("echo", program_echo);
register_command("sysinfo", program_sysinfo);
register_command("conway", program_conway);
register_command("rot13", program_rot13);
register_command("morse", program_morse);
for (;;)
{

128
src/programs/ciphers.c Normal file
View 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
View File

@@ -0,0 +1,6 @@
#ifndef CIPHERS_H
#define CIPHERS_H
#define BUFFER_SIZE 256
#endif

View File

@@ -45,7 +45,7 @@ void program_uptime()
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

View File

@@ -11,6 +11,10 @@ void get_cpuid();
void get_meminfo(unsigned int multiboot_info_address);
void program_conway();
// Ciphers
void program_rot13();
void program_morse();
// Misc
void program_rainbow();
void program_clear();