Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cde6bb4522 | ||
|
|
9992f84fdb | ||
|
|
8e51ab357e | ||
|
|
942b4fa88e | ||
|
|
2893e75ad1 | ||
|
|
0646536f35 | ||
|
|
75d120efcd | ||
|
|
d10e00835c | ||
|
|
fbd4fa6089 | ||
|
|
a915ac15a1 | ||
|
|
a03bb42790 | ||
|
|
0146613ce7 | ||
|
|
b3ee5f5dc9 | ||
|
|
f4f7a37554 | ||
|
|
7089ddd052 | ||
|
|
a029218acd | ||
|
|
6d0c9ac62b | ||
|
|
f1a9f84f24 | ||
|
|
f8eb658c33 | ||
|
|
52a92a5358 | ||
|
|
98d3d346c2 | ||
|
|
1ebed970c8 | ||
|
|
6ce5264b43 | ||
|
|
a2a7ab52a1 | ||
|
|
ca001598fc | ||
|
|
2f562758ad | ||
|
|
cd705589de | ||
|
|
7e551dbfae | ||
|
|
7b65e4ed01 | ||
|
|
ef88100c1f | ||
|
|
6e162fc365 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,8 +1,7 @@
|
||||
*.o
|
||||
bochslog.txt
|
||||
build/
|
||||
kernel.elf
|
||||
os.iso
|
||||
blankos.iso
|
||||
real/
|
||||
iso/
|
||||
i386-elf-7.5.0-Linux-x86_64/
|
||||
i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
|
||||
103
README.md
103
README.md
@@ -1,84 +1,35 @@
|
||||

|
||||

|
||||
|
||||
# BlankOS
|
||||
|
||||
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.
|
||||
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.
|
||||
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
|
||||
|
||||
- Serial port driver (output & debug)
|
||||
- Framebuffer driver (output)
|
||||
- PS/2 Keyboard and PIC driver (input)
|
||||
- PIT (system clock/timer) driver
|
||||
- Working IDT, GDT, ISRs, and IRQs
|
||||
- Kernel panicking (exception handling)
|
||||
- A kernel-space shell
|
||||
- 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:
|
||||
Download the latest BlankOS disk image from the "Releases" tab, and start it using the QEMU emulator:
|
||||
|
||||
```
|
||||
qemu-system-i386 blankOS-i386-0.3.45.iso
|
||||
qemu-system-i386 blankOS-i386-0.3.55.iso
|
||||
```
|
||||
|
||||
Alternatively, burn the image on a USB stick and use it on a machine. (see section "Real Hardware"). *Note that the ISO images provided in the "Releases" tab are already real-hardware capable; no need to do anything except burning the image on a USB stick and running it on your machine.*
|
||||
> [!NOTE]
|
||||
> Know that the latest release is not always up-to-date with the source code. To get the most up-to-date version, instead build from source as shown below.
|
||||
|
||||
## Building from source
|
||||
|
||||
### Dependencies
|
||||
|
||||
For Debian-based distros:
|
||||
```
|
||||
sudo apt install gcc nasm make bochs
|
||||
```
|
||||
|
||||
Then change `display-library` to `sdl2` in the `bochsrc.txt` file.
|
||||
|
||||
For Arch-based distros:
|
||||
```
|
||||
sudo pacman -S nasm gcc make
|
||||
git clone https://aur.archlinux.org/bochs.git
|
||||
```
|
||||
|
||||
Then follow [these](https://bbs.archlinux.org/viewtopic.php?id=178479) instructions to compile Bochs with X support. Alternatively you can use Bochs with SDL but you'll have to change the `bochsrc.txt` file accordingly.
|
||||
|
||||
### Cross Compiler
|
||||
|
||||
A cross-compiler is needed to build the system. More info on why [here](https://wiki.osdev.org/GCC_Cross-Compiler). In order for the build to work, you will need to download the i386-elf toolchain from [here](https://newos.org/toolchains/i386-elf-7.5.0-Linux-x86_64.tar.xz) and extract the root folder into the BlankOS root folder, or build it by youself if you're not lazy like me.
|
||||
|
||||
Why didn't I use one sooner? Can't tell. Maybe I was too lazy. This is actually problematic because I wasn't able to use some libraries and I had to put in a bunch of weird compilation flags. It's better like this.
|
||||
|
||||
To clone and build, do:
|
||||
|
||||
```
|
||||
git clone https://github.com/xamidev/blankos
|
||||
make toolchain
|
||||
make
|
||||
make run
|
||||
```
|
||||
|
||||
This will start a new Bochs debugger instance. To proceed with the kernel execution, you will have to type `c` in the shell spawning Bochs. Serial output will be saved under the `com1.out` file, this way you can debug the kernel by viewing its log messages. To quit, type `q`.
|
||||
You can try out QEMU too.
|
||||
The `toolchain` target will download the appropriate cross-compiling tools, and the `run` target will make a disk image for emulation or real hardware testing. *Some operations require root access. Always audit the code yourself before running anything as root!*
|
||||
|
||||
## Running on real hardware
|
||||
|
||||
To run the OS on real hardware, you'll first need to have a BIOS-compatible computer. Some of the new laptops with graphical "BIOSes" only support UEFI now. So make sure to get a computer that can boot into BIOS mode, **not UEFI mode**. Then, switch the boot mode to "Legacy" in your BIOS utility.
|
||||
|
||||
Then, use the Makefile target `real` to build a "real"-capable ISO disk image. The image will have GRUB2 installed on it, using the `grub-mkrescue` utility (make sure to install it before) which is dependent on `xorriso` (install it too).
|
||||
|
||||
Once the ISO file is generated, you can write it on a disk using this command:
|
||||
|
||||
The OS is now both UEFI and BIOS compatible! Burn your image file onto a USB stick:
|
||||
```
|
||||
sudo dd bs=4M if=blankos.iso of=/dev/sdX status=progress oflag=sync
|
||||
```
|
||||
@@ -86,17 +37,9 @@ 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
|
||||
## Documentation
|
||||
|
||||
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. You'll learn how to use the system and how to contribute to it.
|
||||
|
||||
### Next Steps?
|
||||
|
||||
Next steps for this project will be:
|
||||
|
||||
- User programs
|
||||
- Completing the kernel libc
|
||||
- Filesystem support
|
||||
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)*
|
||||
|
||||
### Resources
|
||||
|
||||
@@ -106,7 +49,27 @@ Next steps for this project will be:
|
||||
- a great book named *Operating Systems: From 0 to 1*, by Tu, Do Hoang
|
||||
- the Intel [64 and IA-32 Architectures Software Developer Manuals](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)
|
||||
- [Bran's Kernel Development Tutorial](http://www.osdever.net/bkerndev/index.php)
|
||||
- Ralf Brown's Interrupt List
|
||||
- the [little book about OS development](https://littleosbook.github.io/) by Erik Helin and Adam Renberg
|
||||
|
||||
### ⚠️ Disclaimer
|
||||
### Features / Roadmap
|
||||
|
||||
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!
|
||||
- [X] Booting with GRUB
|
||||
- [X] Common basic structures (IDT, GDT, ISRs, IRQs)
|
||||
- [X] Common drivers (framebuffer, keyboard, serial, timer)
|
||||
- [X] Kernel-space utilities (shell, simple programs)
|
||||
- [ ] Filesystem (FAT32 or VFS ramdisk)
|
||||
- [ ] Changing the default VGA font
|
||||
- [X] Paging/Page Frame Allocation
|
||||
- [ ] TCP/IP Network stack
|
||||
- [ ] Getting to Ring-3 (userspace)
|
||||
- [ ] Multitasking (via round robin scheduling)
|
||||
- [ ] Advanced/other drivers (video, SB16, RTC, Ethernet)
|
||||
- [X] UEFI support
|
||||
- [ ] ELF parsing
|
||||
- [ ] System calls
|
||||
- [ ] GUI
|
||||
- [ ] 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.
|
||||
|
||||
10
bochsrc.txt
10
bochsrc.txt
@@ -1,10 +0,0 @@
|
||||
megs: 32
|
||||
display_library: x
|
||||
romimage: file=/usr/share/bochs/BIOS-bochs-legacy
|
||||
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
|
||||
ata0-master: type=cdrom, path=os.iso, status=inserted
|
||||
boot: cdrom
|
||||
log: bochslog.txt
|
||||
clock: sync=realtime, time0=local
|
||||
cpu: count=1, ips=1000000
|
||||
com1: enabled=1, mode=file, dev=com1.out
|
||||
@@ -14,6 +14,19 @@ The source code is available in folder `src`. You will find subfolders correspon
|
||||
|
||||
No system calls are available, as the OS runs in kernel-space.
|
||||
|
||||
## Debugging the kernel (QEMU w/ GDB)
|
||||
|
||||
```
|
||||
make debug
|
||||
```
|
||||
|
||||
In another shell:
|
||||
|
||||
```
|
||||
gdb kernel.elf
|
||||
(gdb) target remote localhost:1234
|
||||
```
|
||||
|
||||
## Making programs for the OS
|
||||
|
||||
### Step 1 - Making the program and the entry point
|
||||
@@ -2,6 +2,25 @@
|
||||
|
||||
## Getting started
|
||||
|
||||
First, let me introduce you some features of this project.
|
||||
|
||||
## Features
|
||||
|
||||
- Serial port driver (output & debug)
|
||||
- Framebuffer driver (output)
|
||||
- PS/2 Keyboard and PIC driver (input)
|
||||
- PIT (system clock/timer) driver
|
||||
- Working IDT, GDT, ISRs, and IRQs
|
||||
- Kernel panicking (exception handling)
|
||||
- A kernel-space shell
|
||||
- Cool color output!!
|
||||
- Some small working kernel-space programs, such as...
|
||||
- A brainfuck interpreter
|
||||
- An arithmetic calculator
|
||||
- ROT13 and Morse cipher programs
|
||||
- Conway's Game of Life
|
||||
- And some more...
|
||||
|
||||
### Installation and emulation/execution
|
||||
|
||||
Please refer to the relevant sections in the project `README.md` available in the root folder.
|
||||
@@ -24,11 +43,19 @@ Triggers a kernel panic by trying to divide four by zero.
|
||||
|
||||
#### `words`
|
||||
|
||||
Prints ten random words using an arbitrary dictionary that you can expand in `src/programs/words.c`.
|
||||
Prints random words using an arbitrary dictionary that you can expand in `src/programs/words.c`.
|
||||
|
||||
Options:
|
||||
- `<nothing>` will default amount of words to 10
|
||||
- `<integer>` will set the amount of words to that number
|
||||
|
||||
#### `primes`
|
||||
|
||||
Computes prime numbers up to `PRIMES_MAX`, defined in `src/programs/primes.c`.
|
||||
Computes prime numbers.
|
||||
|
||||
Options:
|
||||
- `<nothing>` will default to `PRIMES_MAX` (a million)
|
||||
- `<integer>` will compute primes up to that number
|
||||
|
||||
#### `rainbow`
|
||||
|
||||
@@ -59,7 +86,7 @@ The classic echo command, that outputs your input.
|
||||
Outputs information about the current system (CPU and RAM).
|
||||
|
||||
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.
|
||||
|
||||
#### `conway`
|
||||
@@ -78,3 +105,7 @@ Encode a string using the rot13 cipher.
|
||||
#### `morse`
|
||||
|
||||
Convert a string to its morse equivalent.
|
||||
|
||||
#### `cowsay`
|
||||
|
||||
Makes a cow speak!
|
||||
4
grub.cfg
4
grub.cfg
@@ -1,4 +1,6 @@
|
||||
menuentry "Blank OS" {
|
||||
multiboot /boot/kernel.elf
|
||||
insmod all_video
|
||||
set gfxpayload=1024x768x32
|
||||
multiboot2 /boot/kernel.elf
|
||||
boot
|
||||
}
|
||||
|
||||
BIN
include/fonts/UniCyr_8x16.psf
Normal file
BIN
include/fonts/UniCyr_8x16.psf
Normal file
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
default=0
|
||||
timeout=0
|
||||
|
||||
title os
|
||||
kernel /boot/kernel.elf
|
||||
Binary file not shown.
Binary file not shown.
17
link.ld
17
link.ld
@@ -1,30 +1,31 @@
|
||||
ENTRY(loader)
|
||||
|
||||
SECTIONS {
|
||||
/* Address to load at; 1MB */
|
||||
/* Address to load at; 2MB */
|
||||
|
||||
. = 0x00100000;
|
||||
/*. = 2M;*/
|
||||
|
||||
.__mbHeader : {
|
||||
*(.__mbHeader)
|
||||
.multiboot_header ALIGN(4K) : {
|
||||
*(.multiboot_header)
|
||||
}
|
||||
|
||||
/* Align relevant sections at 4KB */
|
||||
|
||||
.text ALIGN (0x1000) :
|
||||
.text ALIGN (4K) :
|
||||
{
|
||||
*(.text)
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data ALIGN (0x1000) :
|
||||
.data ALIGN (4K) :
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss ALIGN (0x1000) :
|
||||
.bss ALIGN (4K) :
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
end = .; _end = .; __end = .;
|
||||
}
|
||||
|
||||
54
makefile
54
makefile
@@ -1,5 +1,5 @@
|
||||
CC = i386-elf-7.5.0-Linux-x86_64/bin/i386-elf-gcc
|
||||
CFLAGS = -Wall -Wextra -Wno-builtin-declaration-mismatch -c -I src/
|
||||
CFLAGS = -ffreestanding -g -Wall -Wextra -Wno-builtin-declaration-mismatch -c -I src/
|
||||
LDFLAGS = -T link.ld -melf_i386
|
||||
AS = nasm
|
||||
ASFLAGS = -f elf
|
||||
@@ -9,6 +9,8 @@ KERNEL_DIR = $(SRC_DIR)/kernel
|
||||
LIBC_DIR = $(SRC_DIR)/libc
|
||||
PROGRAMS_DIR = $(SRC_DIR)/programs
|
||||
DRIVERS_DIR = $(SRC_DIR)/drivers
|
||||
INCLUDE_DIR = include
|
||||
FONTS_DIR = $(INCLUDE_DIR)/fonts
|
||||
OBJ_DIR = build
|
||||
|
||||
C_SOURCES = $(wildcard $(KERNEL_DIR)/*.c) $(wildcard $(LIBC_DIR)/*.c) $(wildcard $(PROGRAMS_DIR)/*.c) $(wildcard $(DRIVERS_DIR)/*.c)
|
||||
@@ -16,14 +18,20 @@ ASM_SOURCES = $(wildcard $(KERNEL_DIR)/*.s) $(wildcard $(LIBC_DIR)/*.s) $(wildca
|
||||
|
||||
OBJECTS = $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(C_SOURCES:.c=.o) $(ASM_SOURCES:.s=.o))
|
||||
|
||||
TOOLCHAIN_SRC = https://newos.org/toolchains/i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
TOOLCHAIN_FILE = i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
|
||||
FONT_OBJ = $(OBJ_DIR)/fonts/UniCyr_8x16.o
|
||||
FONT_SRC = $(FONTS_DIR)/UniCyr_8x16.psf
|
||||
|
||||
all: $(OBJ_DIR) kernel.elf
|
||||
|
||||
$(OBJ_DIR):
|
||||
mkdir -p $(OBJ_DIR)
|
||||
mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/programs $(OBJ_DIR)/drivers
|
||||
mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/programs $(OBJ_DIR)/drivers $(OBJ_DIR)/fonts
|
||||
|
||||
kernel.elf: $(OBJECTS)
|
||||
ld $(LDFLAGS) $(OBJECTS) -o kernel.elf
|
||||
kernel.elf: $(OBJECTS) $(FONT_OBJ)
|
||||
ld $(LDFLAGS) $(OBJECTS) $(FONT_OBJ) -o kernel.elf
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
@@ -31,28 +39,28 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s
|
||||
$(AS) $(ASFLAGS) $< -o $@
|
||||
|
||||
os.iso: kernel.elf
|
||||
$(FONT_OBJ): $(FONT_SRC) | $(OBJ_DIR)/fonts
|
||||
objcopy -O elf32-i386 -B i386 -I binary $(FONT_SRC) $(FONT_OBJ)
|
||||
|
||||
$(OBJ_DIR)/fonts:
|
||||
mkdir -p $(OBJ_DIR)/fonts
|
||||
|
||||
toolchain:
|
||||
wget $(TOOLCHAIN_SRC)
|
||||
tar xf $(TOOLCHAIN_FILE)
|
||||
|
||||
iso: kernel.elf
|
||||
mkdir -p iso/boot/grub
|
||||
cp kernel.elf iso/boot/kernel.elf
|
||||
genisoimage -R \
|
||||
-b boot/grub/stage2_eltorito \
|
||||
-no-emul-boot \
|
||||
-boot-load-size 4 \
|
||||
-A os \
|
||||
-input-charset utf8 \
|
||||
-quiet \
|
||||
-boot-info-table \
|
||||
-o os.iso \
|
||||
iso
|
||||
cp grub.cfg iso/boot/grub/grub.cfg
|
||||
grub-mkrescue iso -o blankos.iso
|
||||
|
||||
real: kernel.elf
|
||||
mkdir -p real/boot/grub
|
||||
cp kernel.elf real/boot/kernel.elf
|
||||
cp grub.cfg real/boot/grub/grub.cfg
|
||||
grub-mkrescue real -o blankos.iso
|
||||
run: iso
|
||||
qemu-system-i386 -drive file=blankos.iso,format=raw
|
||||
|
||||
run: os.iso
|
||||
bochs -f bochsrc.txt -q
|
||||
debug:
|
||||
qemu-system-i386 -s -S -drive file=blankos.iso,format=raw
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR) kernel.elf os.iso blankos.iso real
|
||||
rm -rf $(OBJ_DIR) kernel.elf blankos.iso $(TOOLCHAIN_FILE)
|
||||
|
||||
|
||||
62
src/drivers/ata.c
Normal file
62
src/drivers/ata.c
Normal file
@@ -0,0 +1,62 @@
|
||||
// ATA PIO driver implementation
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../kernel/io.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "ata.h"
|
||||
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint16_t result;
|
||||
asm volatile("inw %1, %0" : "=a"(result) : "dN"(port));
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void outw(uint16_t port, uint16_t data) {
|
||||
asm volatile("outw %1, %0" : : "dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
void ata_wait_bsy() {
|
||||
while (inb(ATA_PRIMARY_IO + ATA_REG_STATUS) & ATA_SR_BSY);
|
||||
}
|
||||
|
||||
void ata_wait_drq() {
|
||||
while (!(inb(ATA_PRIMARY_IO + ATA_REG_STATUS) & ATA_SR_DRQ));
|
||||
}
|
||||
|
||||
void ata_select_drive(uint8_t drive) {
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_HDDEVSEL, 0xE0 | (drive << 4));
|
||||
}
|
||||
|
||||
void ata_read_sector(uint32_t lba, uint8_t* buffer) {
|
||||
ata_wait_bsy();
|
||||
ata_select_drive(0);
|
||||
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_SECCOUNT0, 1);
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_LBA0, (uint8_t)lba);
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_LBA1, (uint8_t)(lba >> 8));
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_LBA2, (uint8_t)(lba >> 16));
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_HDDEVSEL, 0xE0 | ((lba >> 24) & 0x0F));
|
||||
|
||||
outb(ATA_PRIMARY_IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
|
||||
|
||||
ata_wait_bsy();
|
||||
ata_wait_drq();
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
((uint16_t*)buffer)[i] = inw(ATA_PRIMARY_IO + ATA_REG_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
// Works only w/o paging
|
||||
void test_read_sector() {
|
||||
uint8_t buffer[512];
|
||||
ata_read_sector(0, buffer);
|
||||
|
||||
for (int i = 0; i < 512; i++) {
|
||||
if (i%25==0) puts("\n");
|
||||
printf("%02x ", buffer[i]);
|
||||
}
|
||||
}
|
||||
35
src/drivers/ata.h
Normal file
35
src/drivers/ata.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// ATA PIO driver implementation header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef ATA_H
|
||||
#define ATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATA_PRIMARY_IO 0x1F0
|
||||
#define ATA_PRIMARY_CTRL 0x3F6
|
||||
#define ATA_CMD_READ_PIO 0x20
|
||||
#define ATA_CMD_WRITE_PIO 0x30
|
||||
#define ATA_IDENTIFY 0xEC
|
||||
|
||||
#define ATA_REG_DATA 0x00
|
||||
#define ATA_REG_ERROR 0x01
|
||||
#define ATA_REG_SECCOUNT0 0x02
|
||||
#define ATA_REG_LBA0 0x03
|
||||
#define ATA_REG_LBA1 0x04
|
||||
#define ATA_REG_LBA2 0x05
|
||||
#define ATA_REG_HDDEVSEL 0x06
|
||||
#define ATA_REG_COMMAND 0x07
|
||||
#define ATA_REG_STATUS 0x07
|
||||
|
||||
#define ATA_SR_BSY 0x80
|
||||
#define ATA_SR_DRDY 0x40
|
||||
#define ATA_SR_DRQ 0x08
|
||||
#define ATA_SR_ERR 0x01
|
||||
|
||||
void ata_read_sector(uint32_t lba, uint8_t* buffer);
|
||||
void test_read_sector();
|
||||
|
||||
#endif
|
||||
91
src/drivers/framebuffer.c
Normal file
91
src/drivers/framebuffer.c
Normal file
@@ -0,0 +1,91 @@
|
||||
// Framebuffer driver
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "framebuffer.h"
|
||||
#include "serial.h"
|
||||
#include "../kernel/system.h"
|
||||
|
||||
extern char* framebuffer;
|
||||
|
||||
void putpixel(uint32_t* fb, int pitch, int bpp, int x, int y, uint32_t color)
|
||||
{
|
||||
if (bpp == 32) {
|
||||
uint32_t* pixel_addr = (uint32_t*)((uint8_t*)fb + y * pitch + x *(bpp / 8));
|
||||
*pixel_addr = color;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_char(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
PSF_font *font = (PSF_font*)&_binary_include_fonts_UniCyr_8x16_psf_start;
|
||||
int bytesperline=(font->width+7)/8;
|
||||
if (unicode != NULL) {
|
||||
c = unicode[c];
|
||||
}
|
||||
|
||||
unsigned char* glyph = (unsigned char*)&_binary_include_fonts_UniCyr_8x16_psf_start + font->headersize + (c>0&&c<font->numglyph?c:0)*font->bytesperglyph;
|
||||
|
||||
int offs =
|
||||
(cy * font->height * scanline) +
|
||||
(cx * (font->width) * sizeof(PIXEL));
|
||||
|
||||
unsigned int x, y;
|
||||
int line, mask;
|
||||
|
||||
for (y=0; y<font->height; y++)
|
||||
{
|
||||
line=offs;
|
||||
mask=1<<(font->width-1);
|
||||
|
||||
for (x=0; x<font->width; x++)
|
||||
{
|
||||
*((PIXEL*)(framebuffer + line)) = *((unsigned int*)glyph) & mask ? fg : bg;
|
||||
mask >>= 1;
|
||||
line += sizeof(PIXEL);
|
||||
}
|
||||
|
||||
glyph += bytesperline;
|
||||
offs += scanline;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll()
|
||||
{
|
||||
serial_printf(3, "Scrolling...\r");
|
||||
uint32_t bg_color = 0x00000000;
|
||||
PSF_font *font = (PSF_font*)&_binary_include_fonts_UniCyr_8x16_psf_start;
|
||||
|
||||
int line_size = font->height * scanline;
|
||||
int framebuffer_size = scanline * font->height * (1080/font->height);
|
||||
|
||||
// Erasing first line
|
||||
for (uint32_t y=0; y<font->height; y++)
|
||||
{
|
||||
for (uint32_t x=0; x<scanline/sizeof(PIXEL); x++)
|
||||
{
|
||||
*((PIXEL*)(framebuffer + y * scanline + x * sizeof(PIXEL))) = bg_color;
|
||||
}
|
||||
}
|
||||
|
||||
// Moving all lines up by 1 line
|
||||
for (int y=1; y<(framebuffer_size/line_size); y++)
|
||||
{
|
||||
void* src = framebuffer + y*line_size;
|
||||
void* dst = framebuffer + (y-1)*line_size;
|
||||
memmove(dst, src, line_size);
|
||||
}
|
||||
|
||||
// Erasing last line
|
||||
int last_line_start = (framebuffer_size/line_size-1) * line_size;
|
||||
for (uint32_t y=0; y<font->height; y++)
|
||||
{
|
||||
for (uint32_t x=0; x<scanline/sizeof(PIXEL); x++)
|
||||
{
|
||||
*((PIXEL*)(framebuffer + last_line_start + y * scanline + x * sizeof(PIXEL))) = bg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
src/drivers/framebuffer.h
Normal file
42
src/drivers/framebuffer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Framebuffer driver header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern int scanline;
|
||||
extern char _binary_include_fonts_UniCyr_8x16_psf_start;
|
||||
uint16_t* unicode;
|
||||
|
||||
#define PIXEL uint32_t
|
||||
|
||||
#define PSF1_FONT_MAGIC 0x0436
|
||||
|
||||
typedef struct {
|
||||
uint16_t magic; // Magic bytes for identification.
|
||||
uint8_t fontMode; // PSF font mode.
|
||||
uint8_t characterSize; // PSF character size.
|
||||
} PSF1_Header;
|
||||
|
||||
#define PSF_FONT_MAGIC 0x864ab572
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic; /* magic bytes to identify PSF */
|
||||
uint32_t version; /* zero */
|
||||
uint32_t headersize; /* offset of bitmaps in file, 32 */
|
||||
uint32_t flags; /* 0 if there's no unicode table */
|
||||
uint32_t numglyph; /* number of glyphs */
|
||||
uint32_t bytesperglyph; /* size of each glyph */
|
||||
uint32_t height; /* height in pixels */
|
||||
uint32_t width; /* width in pixels */
|
||||
} PSF_font;
|
||||
|
||||
void putpixel(uint32_t* fb, int pitch, int bpp, int x, int y, uint32_t color);
|
||||
void draw_char(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg);
|
||||
void scroll();
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,12 @@
|
||||
// Keyboard driver
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/io.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
|
||||
#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
|
||||
#include "kb.h"
|
||||
|
||||
unsigned char kbdus[128] =
|
||||
{
|
||||
@@ -130,6 +129,7 @@ void keyboard_handler()
|
||||
void keyboard_install()
|
||||
{
|
||||
irq_install_handler(1, keyboard_handler);
|
||||
printf("[keyboard] installed irq handler\n");
|
||||
}
|
||||
|
||||
char keyboard_getchar()
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
// Keyboard driver header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef KB_H
|
||||
#define KB_H
|
||||
|
||||
#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
|
||||
|
||||
char keyboard_getchar();
|
||||
|
||||
#endif
|
||||
|
||||
64
src/drivers/rtc.c
Normal file
64
src/drivers/rtc.c
Normal file
@@ -0,0 +1,64 @@
|
||||
// Real-time clock driver implementation for better PRNG
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rtc.h"
|
||||
#include "../kernel/io.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
uint8_t rtc_read_register(uint8_t reg)
|
||||
{
|
||||
outb(0x70, reg);
|
||||
return inb(0x71);
|
||||
}
|
||||
|
||||
uint8_t bcd_to_bin(uint8_t bcd)
|
||||
{
|
||||
return ((bcd/16)*10) + (bcd%16);
|
||||
}
|
||||
|
||||
int rtc_is_updating()
|
||||
{
|
||||
outb(0x70, 0x0A);
|
||||
return (inb(0x71) & 0x80);
|
||||
}
|
||||
|
||||
void rtc_read_time(rtc_time_t *time)
|
||||
{
|
||||
while (rtc_is_updating());
|
||||
|
||||
time->seconds = rtc_read_register(0x00);
|
||||
time->minutes = rtc_read_register(0x02);
|
||||
time->hours = rtc_read_register(0x04);
|
||||
time->day = rtc_read_register(0x06);
|
||||
time->month = rtc_read_register(0x07);
|
||||
time->year = rtc_read_register(0x08);
|
||||
|
||||
outb(0x70, 0x0B);
|
||||
uint8_t registerB = inb(0x71);
|
||||
|
||||
if (!(registerB & 0x04))
|
||||
{
|
||||
time->seconds = bcd_to_bin(time->seconds);
|
||||
time->minutes = bcd_to_bin(time->minutes);
|
||||
time->hours = bcd_to_bin(time->hours);
|
||||
time->day = bcd_to_bin(time->day);
|
||||
time->month = bcd_to_bin(time->month);
|
||||
time->year = bcd_to_bin(time->year);
|
||||
}
|
||||
}
|
||||
|
||||
void print_time(const rtc_time_t *time)
|
||||
{
|
||||
printf("%02d/%02d/%02d %02d:%02d:%02d\n", time->day, time->month, time->year, time->hours, time->minutes, time->seconds);
|
||||
}
|
||||
|
||||
long time_seed()
|
||||
{
|
||||
rtc_time_t* time = {0};
|
||||
rtc_read_time(time);
|
||||
|
||||
return time->day + time->month + time->year + time->hours + time->minutes + time->seconds;
|
||||
}
|
||||
23
src/drivers/rtc.h
Normal file
23
src/drivers/rtc.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Real-time clock driver implementation header for better PRNG
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef RTC_H
|
||||
#define RTC_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t seconds;
|
||||
uint8_t minutes;
|
||||
uint8_t hours;
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint8_t year;
|
||||
} rtc_time_t;
|
||||
|
||||
void rtc_read_time(rtc_time_t *time);
|
||||
long time_seed();
|
||||
void print_time(const rtc_time_t *time);
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,8 @@
|
||||
// Serial I/O driver
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/io.h"
|
||||
#include "serial.h"
|
||||
#include "../libc/stdio.h"
|
||||
@@ -20,6 +25,7 @@ int init_serial()
|
||||
}
|
||||
|
||||
outb(PORT+4, 0x0F);
|
||||
puts("[serial] initialized i/o on port COM1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -276,6 +282,5 @@ void serial_printf(int errlevel, const char* fmt, ...)
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
serial_puts("\n");
|
||||
serial_puts("\r\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#ifndef INCLUDE_SERIAL_H
|
||||
#define INCLUDE_SERIAL_H
|
||||
// Serial I/O driver header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef SERIAL_H
|
||||
#define SERIAL_H
|
||||
|
||||
#define PORT 0x3f8 //COM1
|
||||
|
||||
@@ -9,4 +14,5 @@ void write_serial(const char a);
|
||||
void serial_puts(const char* str);
|
||||
void log(const char* str, const int errlevel);
|
||||
void serial_printf(int errlevel, const char* fmt, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Programmable Interval Timer channel 0 driver
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
@@ -6,11 +11,18 @@ volatile unsigned long global_ticks = 0;
|
||||
void timer_handler()
|
||||
{
|
||||
global_ticks++;
|
||||
if (global_ticks % 20 == 0)
|
||||
{
|
||||
draw_cursor(white);
|
||||
} else if (global_ticks % 20 == 10) {
|
||||
erase_cursor();
|
||||
}
|
||||
}
|
||||
|
||||
void timer_install()
|
||||
{
|
||||
irq_install_handler(0, timer_handler);
|
||||
printf("[timer] initialized, starting g_ticks...\n");
|
||||
}
|
||||
|
||||
void delay(int ticks)
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
// Global descriptor table setup
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "gdt.h"
|
||||
|
||||
struct gdt_entry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
struct gdt_entry gdt[3];
|
||||
struct gdt_ptr gp;
|
||||
@@ -41,8 +31,14 @@ void gdt_install()
|
||||
|
||||
gdt_set_gate(0, 0, 0, 0, 0);
|
||||
|
||||
// Ring 0 code + data
|
||||
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
// Ring 3
|
||||
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
gdt_flush();
|
||||
printf("[kernel] GDT gates set (ring 0 and 3), gdt=0x%x\n", &gdt);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
// Global descriptor table setup header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef GDT_H
|
||||
#define GDT_H
|
||||
|
||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
struct gdt_entry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
void gdt_install();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
// Interrupt descriptor table setup
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "idt.h"
|
||||
#include "system.h"
|
||||
|
||||
struct idt_entry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
struct idt_entry idt[256];
|
||||
struct idt_ptr idtp;
|
||||
@@ -39,4 +30,5 @@ void idt_install()
|
||||
memset(&idt, 0, sizeof(struct idt_entry)*256);
|
||||
|
||||
idt_load();
|
||||
printf("[kernel] loaded IDT at idt=0x%x\n", &idt);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,27 @@
|
||||
// Interrupt descriptor table setup header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
struct idt_entry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
void idt_install();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#ifndef INCLUDE_IO_H
|
||||
#define INCLUDE_IO_H
|
||||
// Raw CPU port I/O kernel module header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdint.h"
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void outb(unsigned short port, unsigned char data);
|
||||
unsigned char inb(unsigned short port);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
; Raw CPU port I/O kernel module
|
||||
; Author: xamidev
|
||||
; Licensed under the Unlicense. See the repo below.
|
||||
; https://github.com/xamidev/blankos
|
||||
|
||||
global outb
|
||||
|
||||
outb:
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
// Interrupt Requests setup
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "system.h"
|
||||
#include "io.h"
|
||||
#include "idt.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
extern void irq0();
|
||||
extern void irq1();
|
||||
@@ -69,6 +75,7 @@ void irq_install()
|
||||
idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
|
||||
idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
|
||||
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
|
||||
printf("[kernel] installed irq 0-15\n");
|
||||
}
|
||||
|
||||
void irq_handler(struct regs *r)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Interrupt service routines setup
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "idt.h"
|
||||
@@ -37,7 +42,6 @@ extern void isr31();
|
||||
|
||||
void isr_install()
|
||||
{
|
||||
|
||||
idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
|
||||
idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
|
||||
idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
|
||||
@@ -70,6 +74,7 @@ void isr_install()
|
||||
idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
|
||||
idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
|
||||
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
|
||||
printf("[kernel] set ISRs 0-31\n");
|
||||
}
|
||||
|
||||
char *exception_messages[] =
|
||||
@@ -115,4 +120,3 @@ void fault_handler(struct regs *r)
|
||||
for (;;);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
46
src/kernel/kheap.c
Normal file
46
src/kernel/kheap.c
Normal file
@@ -0,0 +1,46 @@
|
||||
// Kernel heap management
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "kheap.h"
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint32_t end;
|
||||
uint32_t placement_address = (uint32_t)&end;
|
||||
|
||||
uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys)
|
||||
{
|
||||
if (align == 1 && (placement_address & 0x00000FFF))
|
||||
{
|
||||
placement_address &= 0xFFFFF000;
|
||||
placement_address += 0x1000;
|
||||
}
|
||||
if (phys)
|
||||
{
|
||||
*phys = placement_address;
|
||||
}
|
||||
uint32_t tmp = placement_address;
|
||||
placement_address += sz;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32_t kmalloc_a(uint32_t sz)
|
||||
{
|
||||
return kmalloc_int(sz, 1, 0);
|
||||
}
|
||||
|
||||
uint32_t kmalloc_p(uint32_t sz, uint32_t *phys)
|
||||
{
|
||||
return kmalloc_int(sz, 0, phys);
|
||||
}
|
||||
|
||||
uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys)
|
||||
{
|
||||
return kmalloc_int(sz, 1, phys);
|
||||
}
|
||||
|
||||
uint32_t kmalloc(uint32_t sz)
|
||||
{
|
||||
return kmalloc_int(sz, 0, 0);
|
||||
}
|
||||
16
src/kernel/kheap.h
Normal file
16
src/kernel/kheap.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Kernel heap management header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef KHEAP_H
|
||||
#define KHEAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t kmalloc_a(uint32_t sz);
|
||||
uint32_t kmalloc_p(uint32_t sz, uint32_t *phys);
|
||||
uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys);
|
||||
uint32_t kmalloc(uint32_t sz);
|
||||
|
||||
#endif
|
||||
@@ -1,45 +1,74 @@
|
||||
// Kernel entry point
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../drivers/serial.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "system.h"
|
||||
//#include <stdarg.h>
|
||||
#include "paging.h"
|
||||
#include "../drivers/ata.h"
|
||||
#include <stdint.h>
|
||||
#include "../drivers/framebuffer.h"
|
||||
#include "kmain.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.55 --------------------------------\n\n";
|
||||
|
||||
unsigned int g_multiboot_info_address;
|
||||
|
||||
void kmain(unsigned int multiboot_info_address)
|
||||
void kmain(multiboot2_info *mb_info)
|
||||
{
|
||||
g_multiboot_info_address = multiboot_info_address;
|
||||
multiboot2_tag_framebuffer *fb_info = NULL;
|
||||
|
||||
uint8_t *tags = mb_info->tags;
|
||||
while (1) {
|
||||
uint32_t tag_type = *((uint32_t*) tags);
|
||||
uint32_t tag_size = *((uint32_t*) (tags + 4));
|
||||
|
||||
if (tag_type == 0) break;
|
||||
if (tag_type == 8) {
|
||||
fb_info = (multiboot2_tag_framebuffer*) tags;
|
||||
}
|
||||
|
||||
tags += ((tag_size + 7) & ~7);
|
||||
}
|
||||
|
||||
serial_printf(3, "Framebuffer Address: 0x%x", fb_info->framebuffer_addr);
|
||||
serial_printf(3, "Framebuffer Width: %u", fb_info->framebuffer_width);
|
||||
serial_printf(3, "Framebuffer Height: %u", fb_info->framebuffer_height);
|
||||
serial_printf(3, "Framebuffer Pitch: %u", fb_info->framebuffer_pitch);
|
||||
serial_printf(3, "Framebuffer BPP: %u", fb_info->framebuffer_bpp);
|
||||
|
||||
if (fb_info) {
|
||||
framebuffer = (uint32_t *)(uintptr_t) fb_info->framebuffer_addr;
|
||||
|
||||
uint32_t width = fb_info->framebuffer_width;
|
||||
uint32_t height = fb_info->framebuffer_height;
|
||||
uint32_t bpp = fb_info->framebuffer_bpp;
|
||||
|
||||
//8x16 font, not padded
|
||||
VGA_WIDTH = width/8;
|
||||
VGA_HEIGHT = height/16;
|
||||
serial_printf(3, "VGA_WIDTH=%d, VGA_HEIGHT=%d", VGA_WIDTH, VGA_HEIGHT);
|
||||
scanline = width * (bpp/8);
|
||||
}
|
||||
|
||||
printf("[kernel] multiboot2 info at 0x%x, size=%u\n", mb_info, mb_info->total_size);
|
||||
printf("[kernel] framebuffer discovered at 0x%x\n", fb_info->framebuffer_addr);
|
||||
printf("[kernel] fb0: width=%u, height=%u, pitch=%u, bpp=%u\n", fb_info->framebuffer_width, fb_info->framebuffer_height, fb_info->framebuffer_pitch, fb_info->framebuffer_bpp);
|
||||
|
||||
init_serial();
|
||||
log("serial connection established\n", 3);
|
||||
gdt_install();
|
||||
log("initialized GDT entries\n", 2);
|
||||
idt_install();
|
||||
log("initialized IDT\n", 2);
|
||||
isr_install();
|
||||
log("initialized ISRs\n", 2);
|
||||
irq_install();
|
||||
__asm__ __volatile__("sti");
|
||||
log("initialized IRQs\n", 2),
|
||||
|
||||
clear();
|
||||
colorputs(ascii_title, 10);
|
||||
colorputs(" by @xamidev - star the repo for a cookie!\n\n", 14);
|
||||
//init_paging();
|
||||
//test_read_sector();
|
||||
//uint32_t *ptr = (uint32_t*)0xA0000000;
|
||||
//uint32_t do_page_fault = *ptr;
|
||||
|
||||
timer_install();
|
||||
serial_printf(2, "%d\tinitialized timer handler", global_ticks);
|
||||
keyboard_install();
|
||||
serial_printf(2, "%d\tinitialized keyboard handler", global_ticks);
|
||||
printf("[kernel] spawning shell...\n");
|
||||
shell_install();
|
||||
serial_printf(2, "%d\tstarted system shell", global_ticks);
|
||||
}
|
||||
|
||||
36
src/kernel/kmain.h
Normal file
36
src/kernel/kmain.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Kernel entry point header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef KMAIN_H
|
||||
#define KMAIN_H
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint64_t framebuffer_addr;
|
||||
uint32_t framebuffer_pitch;
|
||||
uint32_t framebuffer_width;
|
||||
uint32_t framebuffer_height;
|
||||
uint8_t framebuffer_bpp;
|
||||
uint8_t framebuffer_type;
|
||||
uint16_t reserved;
|
||||
} multiboot2_tag_framebuffer;
|
||||
|
||||
typedef struct {
|
||||
uint32_t total_size;
|
||||
uint32_t reserved;
|
||||
uint8_t tags[0];
|
||||
} multiboot2_info;
|
||||
|
||||
unsigned int g_multiboot_info_address;
|
||||
|
||||
uint32_t* framebuffer;
|
||||
int scanline;
|
||||
|
||||
// in characters, not pixels
|
||||
uint32_t VGA_WIDTH;
|
||||
uint32_t VGA_HEIGHT;
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,54 @@
|
||||
; Kernel loader assembly stub and multiboot2 header
|
||||
; Author: xamidev
|
||||
; Licensed under the Unlicense. See the repo below.
|
||||
; https://github.com/xamidev/blankos
|
||||
|
||||
global loader
|
||||
|
||||
section .__mbHeader
|
||||
section .multiboot_header
|
||||
|
||||
align 0x4
|
||||
section .text:
|
||||
align 8
|
||||
|
||||
MAGIC_NUMBER equ 0x1BADB002 ; multiboot magic
|
||||
FLAGS equ 0x0
|
||||
CHECKSUM equ -MAGIC_NUMBER
|
||||
KERNEL_STACK_SIZE equ 4096
|
||||
; ASM macros
|
||||
|
||||
dd MAGIC_NUMBER
|
||||
MAGIC_NUMBER equ 0xe85250d6 ; multiboot2 magic
|
||||
FLAGS equ 0x0 ; 32-bit protected mode for i386
|
||||
HEADER_LEN equ 44 ; Tags=2+2+4+4+4+4+2+2+4=28
|
||||
CHECKSUM equ -(MAGIC_NUMBER + FLAGS + HEADER_LEN)
|
||||
|
||||
; Multiboot 2 header, according to specification (16bytes)
|
||||
|
||||
dd MAGIC_NUMBER ; dd = 4 bytes = 32bits = u32
|
||||
dd FLAGS
|
||||
dd HEADER_LEN
|
||||
dd CHECKSUM
|
||||
|
||||
; Tags? (28bytes)
|
||||
|
||||
; Tag 1 : set graphics mode (only recommended, can be overriden by GRUB)
|
||||
|
||||
dw 5 ; 2
|
||||
dw 0 ; 2
|
||||
dd 20 ; 4
|
||||
dd 1920 ; 4
|
||||
dd 1080 ; 4
|
||||
dd 32 ; 4
|
||||
|
||||
; End of tags
|
||||
|
||||
dw 0 ; 2
|
||||
;dw 0 ; 2
|
||||
dd 8 ; 4
|
||||
|
||||
; End of Multiboot 2 header
|
||||
|
||||
section .text:
|
||||
|
||||
KERNEL_STACK_SIZE equ 4096
|
||||
extern kmain
|
||||
|
||||
loader:
|
||||
cli
|
||||
; mov eax, 0xCAFEBABE
|
||||
; push dword 42
|
||||
push ebx
|
||||
call kmain
|
||||
|
||||
@@ -49,225 +78,55 @@ idt_load:
|
||||
lidt [idtp]
|
||||
ret
|
||||
|
||||
global isr0
|
||||
global isr1
|
||||
global isr2
|
||||
global isr3
|
||||
global isr4
|
||||
global isr5
|
||||
global isr6
|
||||
global isr7
|
||||
global isr8
|
||||
global isr9
|
||||
global isr10
|
||||
global isr11
|
||||
global isr12
|
||||
global isr13
|
||||
global isr14
|
||||
global isr15
|
||||
global isr16
|
||||
global isr17
|
||||
global isr18
|
||||
global isr19
|
||||
global isr20
|
||||
global isr21
|
||||
global isr22
|
||||
global isr23
|
||||
global isr24
|
||||
global isr25
|
||||
global isr26
|
||||
global isr27
|
||||
global isr28
|
||||
global isr29
|
||||
global isr30
|
||||
global isr31
|
||||
|
||||
; Interrupt service routine exceptions
|
||||
isr0:
|
||||
%macro ISR_NOERRCODE 1
|
||||
global isr%1
|
||||
isr%1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 0
|
||||
push byte %1
|
||||
jmp isr_common_stub
|
||||
%endmacro
|
||||
|
||||
isr1:
|
||||
%macro ISR_ERRCODE 1
|
||||
global isr%1
|
||||
isr%1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
push byte %1
|
||||
jmp isr_common_stub
|
||||
%endmacro
|
||||
|
||||
isr2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
|
||||
isr3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
|
||||
isr4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
|
||||
isr5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
|
||||
isr6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
|
||||
isr7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
|
||||
isr8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
|
||||
isr9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
|
||||
isr10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
|
||||
isr11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
|
||||
isr12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
|
||||
isr13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
|
||||
isr14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
|
||||
isr15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
|
||||
isr16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
|
||||
isr17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
|
||||
isr18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
|
||||
isr19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
|
||||
isr20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
|
||||
isr21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
|
||||
isr22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
|
||||
isr23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
|
||||
isr24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
|
||||
isr25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
|
||||
isr26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
|
||||
isr27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
|
||||
isr28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
|
||||
isr29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
|
||||
isr30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
|
||||
isr31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
ISR_NOERRCODE 0
|
||||
ISR_NOERRCODE 1
|
||||
ISR_NOERRCODE 2
|
||||
ISR_NOERRCODE 3
|
||||
ISR_NOERRCODE 4
|
||||
ISR_NOERRCODE 5
|
||||
ISR_NOERRCODE 6
|
||||
ISR_NOERRCODE 7
|
||||
ISR_ERRCODE 8
|
||||
ISR_NOERRCODE 9
|
||||
ISR_ERRCODE 10
|
||||
ISR_ERRCODE 11
|
||||
ISR_ERRCODE 12
|
||||
ISR_ERRCODE 13
|
||||
ISR_ERRCODE 14
|
||||
ISR_NOERRCODE 15
|
||||
ISR_NOERRCODE 16
|
||||
ISR_NOERRCODE 17
|
||||
ISR_NOERRCODE 18
|
||||
ISR_NOERRCODE 19
|
||||
ISR_NOERRCODE 20
|
||||
ISR_NOERRCODE 21
|
||||
ISR_NOERRCODE 22
|
||||
ISR_NOERRCODE 23
|
||||
ISR_NOERRCODE 24
|
||||
ISR_NOERRCODE 25
|
||||
ISR_NOERRCODE 26
|
||||
ISR_NOERRCODE 27
|
||||
ISR_NOERRCODE 28
|
||||
ISR_NOERRCODE 29
|
||||
ISR_NOERRCODE 30
|
||||
ISR_NOERRCODE 31
|
||||
|
||||
extern fault_handler
|
||||
|
||||
@@ -295,118 +154,31 @@ isr_common_stub:
|
||||
add esp, 8
|
||||
iret
|
||||
|
||||
global irq0
|
||||
global irq1
|
||||
global irq2
|
||||
global irq3
|
||||
global irq4
|
||||
global irq5
|
||||
global irq6
|
||||
global irq7
|
||||
global irq8
|
||||
global irq9
|
||||
global irq10
|
||||
global irq11
|
||||
global irq12
|
||||
global irq13
|
||||
global irq14
|
||||
global irq15
|
||||
|
||||
irq0:
|
||||
%macro IRQ 2
|
||||
global irq%1
|
||||
irq%1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32
|
||||
push byte %2
|
||||
jmp irq_common_stub
|
||||
%endmacro
|
||||
|
||||
irq1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
irq2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
irq3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
irq4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
irq5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
irq6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
irq7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
irq8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
|
||||
irq9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
irq10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
irq11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
irq12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
irq13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
irq14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
irq15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
IRQ 0, 32
|
||||
IRQ 1, 33
|
||||
IRQ 2, 34
|
||||
IRQ 3, 35
|
||||
IRQ 4, 36
|
||||
IRQ 5, 37
|
||||
IRQ 6, 38
|
||||
IRQ 7, 39
|
||||
IRQ 8, 40
|
||||
IRQ 9, 41
|
||||
IRQ 10, 42
|
||||
IRQ 11, 43
|
||||
IRQ 12, 44
|
||||
IRQ 13, 45
|
||||
IRQ 14, 46
|
||||
IRQ 15, 47
|
||||
|
||||
extern irq_handler
|
||||
|
||||
|
||||
151
src/kernel/paging.c
Normal file
151
src/kernel/paging.c
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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();
|
||||
}
|
||||
43
src/kernel/paging.h
Normal file
43
src/kernel/paging.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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
|
||||
@@ -1,13 +1,46 @@
|
||||
// Basic shell and commands kernel module
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../programs/programs.h"
|
||||
#include "../libc/stdint.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include <stdint.h>
|
||||
#include "../drivers/rtc.h"
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
#define MAX_COMMANDS 16
|
||||
#define MAX_ARGS 64
|
||||
|
||||
// Splash screen: esthetic stuff.
|
||||
|
||||
char* motd[] =
|
||||
{
|
||||
"Now in 2D!",
|
||||
"Supercalifragilisticexpialidocious!",
|
||||
"Tylko jedno w glowie mam!",
|
||||
};
|
||||
int motd_size = sizeof(motd)/sizeof(motd[0]);
|
||||
|
||||
void splash()
|
||||
{
|
||||
int random = randint(time_seed());
|
||||
char* motd_pick = motd[random%motd_size];
|
||||
cowsay(motd_pick, red, black);
|
||||
colorputs(" blankOS 0.3.86-alpha", red, black);
|
||||
puts("\n");
|
||||
|
||||
|
||||
puts(" Time: ");
|
||||
rtc_time_t time;
|
||||
rtc_read_time(&time);
|
||||
print_time(&time);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
typedef void (*command_func_t)(int argc, char *argv[]);
|
||||
|
||||
typedef struct
|
||||
@@ -54,6 +87,8 @@ int parse_input(char* input, char* argv[], int max_args)
|
||||
|
||||
void shell_install()
|
||||
{
|
||||
splash();
|
||||
|
||||
register_command("help", program_help);
|
||||
register_command("panic", program_panic);
|
||||
register_command("words", program_words);
|
||||
@@ -68,12 +103,19 @@ void shell_install()
|
||||
register_command("conway", program_conway);
|
||||
register_command("rot13", program_rot13);
|
||||
register_command("morse", program_morse);
|
||||
register_command("cowsay", program_cowsay);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
char* argv[MAX_ARGS];
|
||||
colorputs("blankos> ", 9);
|
||||
|
||||
// Prompt
|
||||
colorputs("root", blue, black);
|
||||
colorputs("@", white, black);
|
||||
colorputs("blankos", green, black);
|
||||
colorputs("~$ ", white, black);
|
||||
|
||||
get_input(input_buffer, BUFFER_SIZE);
|
||||
puts("\n");
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// System information kernel module
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// System information kernel module header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef SYSINFO_H
|
||||
#define SYSINFO_H
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
// System utilities and routines kernel module
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "system.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void *memset(void *dest, char val, size_t count)
|
||||
{
|
||||
@@ -6,3 +12,29 @@ void *memset(void *dest, char val, size_t count)
|
||||
for(; count != 0; count--) *temp++ = val;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove(void* dest, const void* src, size_t n)
|
||||
{
|
||||
unsigned char* d = (unsigned char*)dest;
|
||||
const unsigned char* s = (const unsigned char*)src;
|
||||
|
||||
if (d < s)
|
||||
{
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
d[i] = s[i];
|
||||
}
|
||||
} else {
|
||||
for (size_t i=n; i>0; i--)
|
||||
{
|
||||
d[i-1] = s[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void panic()
|
||||
{
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
// System utilities and routines kernel module header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int size_t;
|
||||
#define NULL ((void*)0)
|
||||
|
||||
void *memset(void *dest, char val, size_t count);
|
||||
void *memmove(void* dest, const void* src, size_t n);
|
||||
|
||||
struct regs
|
||||
{
|
||||
@@ -13,6 +22,7 @@ struct regs
|
||||
unsigned int eip, cs, eflags, useresp, ss;
|
||||
};
|
||||
|
||||
void panic();
|
||||
void isr_install();
|
||||
void irq_install();
|
||||
void irq_install_handler(int irq, void (*handler)(struct regs *r));
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
// Cryptography routines for blankos/libc
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "crypto.h"
|
||||
#include "../libc/stdint.h"
|
||||
#include <stdint.h>
|
||||
|
||||
int lcg(int seed)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// Cryptography routines for blankos/libc header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#define RAND_MAX 1024
|
||||
|
||||
#include "../libc/stdint.h"
|
||||
#include <stdint.h>
|
||||
|
||||
int lcg(int seed);
|
||||
int randint(int seed);
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// Ctype implementation for blankos/libc
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "stdint.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool isdigit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
|
||||
bool isspace(char c)
|
||||
{
|
||||
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// Ctype implementation for blankos/libc header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CTYPE_H
|
||||
#define CTYPE_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
bool isdigit(char c);
|
||||
bool isspace(char c);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef INCLUDE_STDINT_H
|
||||
#define INCLUDE_STDINT_H
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef signed long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
|
||||
typedef signed long long int int64_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
|
||||
typedef uint8_t bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
#endif
|
||||
211
src/libc/stdio.c
211
src/libc/stdio.c
@@ -1,33 +1,50 @@
|
||||
// Standard input/output implementation for blankos/libc
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/io.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "stdint.h"
|
||||
#include <stdint.h>
|
||||
#include "../kernel/system.h"
|
||||
#include "../drivers/framebuffer.h"
|
||||
#include "../drivers/serial.h"
|
||||
|
||||
char* fb = (char *) 0x000B8000;
|
||||
const unsigned VGA_WIDTH = 80;
|
||||
const unsigned VGA_HEIGHT = 25;
|
||||
const unsigned int COLOR = 0x7;
|
||||
extern uint32_t* framebuffer;
|
||||
extern uint32_t VGA_WIDTH;
|
||||
extern uint32_t VGA_HEIGHT;
|
||||
unsigned int VGA_X = 0, VGA_Y = 0;
|
||||
extern int scanline;
|
||||
|
||||
void draw_cursor(uint32_t color)
|
||||
{
|
||||
for (int y=12; y<CURSOR_HEIGHT; y++)
|
||||
{
|
||||
for (int x=0; x<CURSOR_WIDTH; x++)
|
||||
{
|
||||
putpixel(framebuffer, scanline, 32, VGA_X * CURSOR_WIDTH + x, VGA_Y * CURSOR_HEIGHT + y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void erase_cursor()
|
||||
{
|
||||
draw_cursor(black);
|
||||
}
|
||||
|
||||
void move_cursor(int x, int y)
|
||||
{
|
||||
unsigned short pos = y*VGA_WIDTH+x;
|
||||
|
||||
outb(FB_CMD_PORT, FB_HIGH_BYTE_CMD);
|
||||
outb(FB_DATA_PORT, ((pos >> 8) & 0x00FF));
|
||||
outb(FB_CMD_PORT, FB_LOW_BYTE_CMD);
|
||||
outb(FB_DATA_PORT, pos & 0x00FF);
|
||||
erase_cursor();
|
||||
VGA_X = x;
|
||||
VGA_Y = y;
|
||||
draw_cursor(white);
|
||||
}
|
||||
|
||||
void putchar(int x, int y, char c)
|
||||
// stdio wrapper for draw_char in graphics mode
|
||||
void putchar(unsigned short int c, int x, int y, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
fb[2*(y*VGA_WIDTH+x)] = c;
|
||||
}
|
||||
|
||||
void putcolor(int x, int y, unsigned int color)
|
||||
{
|
||||
fb[2*(y*VGA_WIDTH+x)+1] = color;
|
||||
draw_char(c, x, y, fg, bg);
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
@@ -36,55 +53,15 @@ void clear(void)
|
||||
{
|
||||
for (unsigned int x=0; x<VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y, '\0');
|
||||
putcolor(x, y, COLOR);
|
||||
putchar(' ', x, y, black, black);
|
||||
}
|
||||
}
|
||||
VGA_X = 0;
|
||||
VGA_Y = 0;
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
char getchar(int x, int y)
|
||||
{
|
||||
return fb[2*(y*VGA_WIDTH+x)];
|
||||
}
|
||||
|
||||
unsigned int getcolor(int x, int y)
|
||||
{
|
||||
return fb[2*(y*VGA_WIDTH+x)+1];
|
||||
}
|
||||
|
||||
void scroll(int lines)
|
||||
{
|
||||
if (lines <= 0 || (unsigned int)lines >= VGA_HEIGHT) return;
|
||||
|
||||
for (unsigned int y = 0; y < VGA_HEIGHT-lines; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y, getchar(x, y+lines));
|
||||
putcolor(x, y, getcolor(x, y+lines));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int y = VGA_HEIGHT-lines; y<VGA_HEIGHT; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y, ' ');
|
||||
putcolor(x, y, COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
VGA_Y -= lines;
|
||||
if ((int)VGA_Y < 0) {
|
||||
VGA_Y = 0;
|
||||
}
|
||||
move_cursor(0, 0);
|
||||
}
|
||||
|
||||
void putc(char c)
|
||||
{
|
||||
erase_cursor();
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
@@ -110,10 +87,10 @@ void putc(char c)
|
||||
VGA_Y--;
|
||||
VGA_X = VGA_WIDTH-1;
|
||||
}
|
||||
putchar(VGA_X, VGA_Y, ' ');
|
||||
putchar(' ', VGA_X, VGA_Y, white, black);
|
||||
break;
|
||||
default:
|
||||
putchar(VGA_X, VGA_Y, c);
|
||||
putchar(c, VGA_X, VGA_Y, white, black);
|
||||
VGA_X++;
|
||||
break;
|
||||
}
|
||||
@@ -123,13 +100,19 @@ void putc(char c)
|
||||
VGA_Y++;
|
||||
VGA_X = 0;
|
||||
}
|
||||
if (VGA_Y >= VGA_HEIGHT) scroll(1);
|
||||
if (VGA_Y >= VGA_HEIGHT)
|
||||
{
|
||||
serial_printf(3, "VGA_Y=%d, VGA_HEIGHT=%d: Scrolling...\r", VGA_Y, VGA_HEIGHT);
|
||||
scroll();
|
||||
VGA_Y = VGA_HEIGHT - 1;
|
||||
}
|
||||
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
void colorputc(char c, unsigned int color)
|
||||
void colorputc(char c, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
erase_cursor();
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
@@ -143,8 +126,7 @@ void colorputc(char c, unsigned int color)
|
||||
VGA_X += 4;
|
||||
break;
|
||||
default:
|
||||
putchar(VGA_X, VGA_Y, c);
|
||||
putcolor(VGA_X, VGA_Y, color);
|
||||
putchar(c, VGA_X, VGA_Y, fg, bg);
|
||||
VGA_X++;
|
||||
break;
|
||||
}
|
||||
@@ -154,7 +136,14 @@ void colorputc(char c, unsigned int color)
|
||||
VGA_Y++;
|
||||
VGA_X = 0;
|
||||
}
|
||||
if (VGA_Y >= VGA_HEIGHT) scroll(1);
|
||||
|
||||
if (VGA_Y >= VGA_HEIGHT)
|
||||
{
|
||||
serial_printf(3, "VGA_Y=%d, VGA_HEIGHT=%d: Scrolling...\r", VGA_Y, VGA_HEIGHT);
|
||||
scroll();
|
||||
VGA_Y = VGA_HEIGHT - 1;
|
||||
}
|
||||
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
@@ -167,11 +156,11 @@ void puts(const char* str)
|
||||
}
|
||||
}
|
||||
|
||||
void colorputs(const char* str, unsigned int color)
|
||||
void colorputs(const char* str, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
colorputc(*str, color);
|
||||
colorputc(*str, fg, bg);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
@@ -226,22 +215,39 @@ void printf(const char* fmt, ...)
|
||||
int length = PRINTF_LENGTH_START;
|
||||
int radix = 10;
|
||||
bool sign = false;
|
||||
int width = 0;
|
||||
char pad_char = ' ';
|
||||
|
||||
argp++;
|
||||
while (*fmt)
|
||||
{
|
||||
switch(state) {
|
||||
switch (state)
|
||||
{
|
||||
case PRINTF_STATE_START:
|
||||
if (*fmt == '%')
|
||||
{
|
||||
state = PRINTF_STATE_LENGTH;
|
||||
width = 0;
|
||||
pad_char = ' ';
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
putc(*fmt);
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTF_STATE_LENGTH:
|
||||
if (*fmt == 'h')
|
||||
if (*fmt == '0')
|
||||
{
|
||||
pad_char = '0';
|
||||
state = PRINTF_STATE_WIDTH;
|
||||
}
|
||||
else if (*fmt >= '1' && *fmt <= '9')
|
||||
{
|
||||
width = *fmt - '0';
|
||||
state = PRINTF_STATE_WIDTH;
|
||||
}
|
||||
else if (*fmt == 'h')
|
||||
{
|
||||
length = PRINTF_LENGTH_SHORT;
|
||||
state = PRINTF_STATE_SHORT;
|
||||
@@ -251,30 +257,47 @@ void printf(const char* fmt, ...)
|
||||
length = PRINTF_LENGTH_LONG;
|
||||
state = PRINTF_STATE_LONG;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTF_STATE_WIDTH:
|
||||
if (*fmt >= '0' && *fmt <= '9')
|
||||
{
|
||||
width = width * 10 + (*fmt - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTF_STATE_SHORT:
|
||||
if (*fmt == 'h')
|
||||
{
|
||||
length = PRINTF_LENGTH_SHORT_SHORT;
|
||||
state = PRINTF_STATE_SPEC;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTF_STATE_LONG:
|
||||
if (*fmt == 'l')
|
||||
{
|
||||
length = PRINTF_LENGTH_LONG_LONG;
|
||||
state = PRINTF_STATE_SPEC;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTF_STATE_SPEC:
|
||||
PRINTF_STATE_SPEC_:
|
||||
switch (*fmt)
|
||||
@@ -294,33 +317,32 @@ void printf(const char* fmt, ...)
|
||||
case 'i':
|
||||
radix = 10;
|
||||
sign = true;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
argp = printf_number(argp, length, sign, radix, width, pad_char);
|
||||
break;
|
||||
case 'u':
|
||||
radix = 10;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
argp = printf_number(argp, length, sign, radix, width, pad_char);
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
case 'p':
|
||||
radix = 16;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
argp = printf_number(argp, length, sign, radix, width, pad_char);
|
||||
break;
|
||||
case 'o':
|
||||
radix = 8;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
argp = printf_number(argp, length, sign, radix, width, pad_char);
|
||||
break;
|
||||
case 'f': {
|
||||
// Handle floating-point numbers
|
||||
double* dargp = (double*)argp;
|
||||
double d = *(double*)dargp;
|
||||
char buffer[64];
|
||||
dtostrf(d, buffer, 6); // Default precision: 6
|
||||
dtostrf(d, buffer, 6);
|
||||
puts(buffer);
|
||||
argp += 2; // Incrementing by 2 to move past the double argument
|
||||
argp += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -330,6 +352,8 @@ void printf(const char* fmt, ...)
|
||||
length = PRINTF_LENGTH_START;
|
||||
radix = 10;
|
||||
sign = false;
|
||||
width = 0;
|
||||
pad_char = ' ';
|
||||
break;
|
||||
}
|
||||
fmt++;
|
||||
@@ -338,7 +362,7 @@ void printf(const char* fmt, ...)
|
||||
|
||||
const char charset[] = "0123456789abcdef";
|
||||
|
||||
int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
int* printf_number(int* argp, int length, bool sign, int radix, int width, char pad_char)
|
||||
{
|
||||
char buffer[32];
|
||||
unsigned long long number;
|
||||
@@ -360,7 +384,8 @@ int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
}
|
||||
number = (unsigned long long)n;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
number = *(unsigned int*)argp;
|
||||
}
|
||||
argp++;
|
||||
@@ -376,7 +401,8 @@ int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
}
|
||||
number = (unsigned long long)n;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
number = *(unsigned long int*)argp;
|
||||
}
|
||||
argp += 2;
|
||||
@@ -392,14 +418,16 @@ int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
}
|
||||
number = (unsigned long long)n;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
number = *(unsigned long long int*)argp;
|
||||
}
|
||||
argp += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
uint32_t rem;
|
||||
x86_div64_32(number, radix, &number, &rem);
|
||||
buffer[pos++] = charset[rem];
|
||||
@@ -410,6 +438,13 @@ int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
buffer[pos++] = '-';
|
||||
}
|
||||
|
||||
int padding = width - pos;
|
||||
|
||||
while (padding-- > 0)
|
||||
{
|
||||
putc(pad_char);
|
||||
}
|
||||
|
||||
while (--pos >= 0)
|
||||
{
|
||||
putc(buffer[pos]);
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#ifndef INCLUDE_STDIO_H
|
||||
#define INCLUDE_STDIO_H
|
||||
// Standard input/output implementation for blankos/libc header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "stdint.h"
|
||||
#ifndef STDIO_H
|
||||
#define STDIO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define FB_GREEN 2
|
||||
#define FB_DARK_GREY 8
|
||||
@@ -11,23 +17,29 @@
|
||||
#define FB_HIGH_BYTE_CMD 14
|
||||
#define FB_LOW_BYTE_CMD 15
|
||||
|
||||
#define CURSOR_WIDTH 8
|
||||
#define CURSOR_HEIGHT 16
|
||||
|
||||
void draw_cursor(uint32_t color);
|
||||
void erase_cursor();
|
||||
|
||||
void move_cursor(int x, int y);
|
||||
void putchar(int x, int y, char c);
|
||||
void putchar(unsigned short int c, int x, int y, uint32_t fg, uint32_t bg);
|
||||
void puts(const char* str);
|
||||
void colorputs(const char* str, unsigned int color);
|
||||
void clear(void);
|
||||
void colorputs(const char* str, uint32_t fg, uint32_t bg);
|
||||
void putcolor(int x, int y, unsigned int color);
|
||||
char getchar(int x, int y);
|
||||
unsigned int getcolor(int x, int y);
|
||||
void scroll(int lines);
|
||||
void putc(char c);
|
||||
void colorputc(char c, unsigned int color);
|
||||
void colorputc(char c, uint32_t fg, uint32_t bg);
|
||||
|
||||
#define PRINTF_STATE_START 0
|
||||
#define PRINTF_STATE_LENGTH 1
|
||||
#define PRINTF_STATE_SHORT 2
|
||||
#define PRINTF_STATE_LONG 3
|
||||
#define PRINTF_STATE_SPEC 4
|
||||
#define PRINTF_STATE_WIDTH 5
|
||||
|
||||
#define PRINTF_LENGTH_START 0
|
||||
#define PRINTF_LENGTH_SHORT_SHORT 1
|
||||
@@ -36,10 +48,20 @@ void colorputc(char c, unsigned int color);
|
||||
#define PRINTF_LENGTH_LONG_LONG 4
|
||||
|
||||
void printf(const char* fmt, ...);
|
||||
int* printf_number(int* argp, int length, bool sign, int radix);
|
||||
int* printf_number(int* argp, int length, bool sign, int radix, int width, char pad_char);
|
||||
int getch();
|
||||
void get_input(char *buffer, int size);
|
||||
|
||||
void dtostrf(double val, char *buffer, int precision);
|
||||
|
||||
enum Colors
|
||||
{
|
||||
// AARRGGBB?
|
||||
white = 0xFFFFFFFF,
|
||||
black = 0x00000000,
|
||||
red = 0x00FF0000,
|
||||
green = 0x0000FF00,
|
||||
blue = 0x000000FF,
|
||||
yellow = 0x00FFFF00,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
#include "stdint.h"
|
||||
// String operations implementation for blankos/libc
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../kernel/system.h"
|
||||
|
||||
int strlen(const char* str)
|
||||
{
|
||||
@@ -68,3 +74,32 @@ char* strtok(char* str, const char* delimiter)
|
||||
|
||||
return token_start;
|
||||
}
|
||||
|
||||
int atoi(char* str)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (int i=0; str[i] != '\0'; i++)
|
||||
{
|
||||
result = result*10 + str[i] - '0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void strcat(char* dest, const char* src)
|
||||
{
|
||||
while (*dest)
|
||||
{
|
||||
dest++;
|
||||
}
|
||||
|
||||
while (*src)
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#ifndef INCLUDE_STRING_H
|
||||
#define INCLUDE_STRING_H
|
||||
// String operations implementation for blankos/libc header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef STRING_H
|
||||
#define STRING_H
|
||||
|
||||
int strlen(const char* str);
|
||||
int strcmp(const char* str1, const char* str2);
|
||||
char* strtok(char* str, const char* delimiter);
|
||||
int atoi(char* str);
|
||||
void strcat(char* dest, const char* src);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// Simple brainfuck interpreter program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
// Cipher programs
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "ciphers.h"
|
||||
#include "../libc/string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void rot13(char* input, char* output)
|
||||
{
|
||||
@@ -32,9 +39,6 @@ void program_rot13()
|
||||
printf("\n%s\n", output);
|
||||
}
|
||||
|
||||
#include "../libc/string.h"
|
||||
#include "../libc/stdint.h"
|
||||
|
||||
const char* morse_alphabet[] = {
|
||||
".-", // A
|
||||
"-...", // B
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Cipher programs header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CIPHERS_H
|
||||
#define CIPHERS_H
|
||||
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
// Conway's Game of Life program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "conway.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include "../libc/stdint.h"
|
||||
#include <stdint.h>
|
||||
#include "../drivers/serial.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
void print_grid(const unsigned char grid[X][Y])
|
||||
{
|
||||
clear();
|
||||
for (int i=0; i<X; i++)
|
||||
{
|
||||
for (int j=0; j<Y; j++)
|
||||
{
|
||||
//(grid[i][j] == LIVE) ? putc(42) : putc(32);
|
||||
if (grid[i][j] == LIVE) {
|
||||
serial_printf(3, "alive");
|
||||
colorputc(32, 120);
|
||||
putc(35);
|
||||
} else {
|
||||
putc(32);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// Conway's Game of Life program header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CONWAY_H
|
||||
#define CONWAY_H
|
||||
|
||||
#define X 25
|
||||
#define Y 80
|
||||
#define X 66
|
||||
#define Y 240
|
||||
|
||||
#define GENERATIONS 100
|
||||
#define DEAD 0
|
||||
|
||||
72
src/programs/cowsay.c
Normal file
72
src/programs/cowsay.c
Normal file
@@ -0,0 +1,72 @@
|
||||
// Cowsay-like program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
#define MAX_MSG_LEN 128
|
||||
|
||||
const char* cow =
|
||||
" \\ ^__^\n"
|
||||
" \\ (oo)\\_______\n"
|
||||
" (__)\\ )\\/\\\n"
|
||||
" ||----w |\n"
|
||||
" || ||\n";
|
||||
|
||||
void print_bubble(const char* message)
|
||||
{
|
||||
int len = strlen(message);
|
||||
puts(" ");
|
||||
for (int i=0; i<len+2; i++)
|
||||
{
|
||||
puts("_");
|
||||
}
|
||||
puts("\n");
|
||||
|
||||
printf("< %s >\n", message);
|
||||
|
||||
puts(" ");
|
||||
for (int i=0; i<len+2; i++)
|
||||
{
|
||||
puts("-");
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void cowsay(char* msg, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
print_bubble(msg);
|
||||
colorputs(cow, fg, bg);
|
||||
}
|
||||
|
||||
void program_cowsay(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <message>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char message[MAX_MSG_LEN];
|
||||
message[0] = '\0';
|
||||
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
if (strlen(message) + strlen(argv[i]) + 1 < MAX_MSG_LEN)
|
||||
{
|
||||
strcat(message, argv[i]);
|
||||
if (i < argc-1)
|
||||
{
|
||||
strcat(message, " ");
|
||||
}
|
||||
} else {
|
||||
puts("Too long message.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
print_bubble(message);
|
||||
printf("%s", cow);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
// Math expression lexer and parser
|
||||
// Basic math expression lexer and parser program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdint.h"
|
||||
#include <stdint.h>
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/ctype.h"
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
// Miscellaneous small programs
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../drivers/framebuffer.h"
|
||||
|
||||
// Print a rainbow colorful text for testing
|
||||
|
||||
@@ -18,7 +22,7 @@ void program_rainbow()
|
||||
|
||||
for (int i=0; i<COLORS; i++)
|
||||
{
|
||||
colorputs(input_buffer, i);
|
||||
//colorputs(input_buffer, i);
|
||||
puts("\n");
|
||||
}
|
||||
}
|
||||
@@ -29,7 +33,7 @@ void program_rainbow()
|
||||
|
||||
void program_clear()
|
||||
{
|
||||
for (int i=0; i<ROWS; i++) scroll(1);
|
||||
clear();
|
||||
}
|
||||
|
||||
// Get uptime in ticks
|
||||
@@ -37,7 +41,7 @@ void program_clear()
|
||||
void program_uptime()
|
||||
{
|
||||
int ticks = uptime();
|
||||
double seconds = ticks/18.2065; // PIC channel 0 freq
|
||||
double seconds = ticks/18.2065; // PIT channel 0 freq
|
||||
printf("%d ticks\t%f seconds\n", ticks, seconds);
|
||||
}
|
||||
|
||||
@@ -45,7 +49,7 @@ void program_uptime()
|
||||
|
||||
void program_help()
|
||||
{
|
||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\n");
|
||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay\n");
|
||||
}
|
||||
|
||||
// Panic
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#include "../libc/stdint.h"
|
||||
// Prime number computation program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
#define PRIMES_MAX 1000000
|
||||
|
||||
@@ -11,15 +17,25 @@ bool isPrime(int n)
|
||||
return true;
|
||||
}
|
||||
|
||||
void program_primes()
|
||||
void program_primes(int argc, char* argv[])
|
||||
{
|
||||
for (long long x=0; x<PRIMES_MAX; x++)
|
||||
int primes_max;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
primes_max = PRIMES_MAX;
|
||||
} else if (argc == 2)
|
||||
{
|
||||
primes_max = atoi(argv[1]);
|
||||
}
|
||||
|
||||
for (long long x=0; x<primes_max; x++)
|
||||
{
|
||||
if (isPrime(x))
|
||||
{
|
||||
printf("%d ", x);
|
||||
}
|
||||
delay(2);
|
||||
delay(1);
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Global program entry points header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef PROGRAMS_H
|
||||
#define PROGRAMS_H
|
||||
|
||||
@@ -10,6 +15,8 @@ void program_sysinfo();
|
||||
void get_cpuid();
|
||||
void get_meminfo(unsigned int multiboot_info_address);
|
||||
void program_conway();
|
||||
void program_cowsay();
|
||||
void cowsay(); // Splash screen
|
||||
|
||||
// Ciphers
|
||||
void program_rot13();
|
||||
@@ -22,4 +29,5 @@ void program_uptime();
|
||||
void program_panic();
|
||||
void program_help();
|
||||
void program_echo();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// System information program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/sysinfo.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
@@ -1,46 +1,211 @@
|
||||
// Pseudo-random word generation program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
// Small dictionary
|
||||
|
||||
char* words[] =
|
||||
{
|
||||
// A
|
||||
"I", "us", "they", "my",
|
||||
"a", "an", "is", "are", "for", "while", "not", "none", "yes", "no",
|
||||
"absolutely", "addition", "additive", "afternoon", "architect", "ask",
|
||||
"be", "blindfold", "brilliant", "boy", "brilliant", "bring", "buddy",
|
||||
"ability", "above", "absence", "academy", "account", "achieve", "acquire",
|
||||
"adapt", "admit", "adventure", "affection", "agenda", "agreement", "airport",
|
||||
"alert", "alibi", "alive", "allow", "almond", "alphabet", "always",
|
||||
|
||||
// B
|
||||
"be", "blindfold", "brilliant", "boy", "bring", "buddy",
|
||||
"balance", "bamboo", "band", "banjo", "bank", "banner", "barrel",
|
||||
"basic", "battery", "beach", "beacon", "beard", "behavior", "believe",
|
||||
"belt", "benefit", "berry", "bicycle", "bingo", "biology", "birthday",
|
||||
"biscuit", "bitter", "blanket", "blizzard", "blossom", "blueprint", "board",
|
||||
|
||||
// C
|
||||
"career", "caterpillar", "change", "cheeky", "chop",
|
||||
"cabin", "cactus", "camera", "candle", "candy", "canoe", "canvas",
|
||||
"capital", "captain", "caravan", "carbon", "carpet", "cartoon", "castle",
|
||||
"casual", "catalog", "catch", "category", "celebrate", "ceremony", "certain",
|
||||
"chain", "chair", "chamber", "charge", "charity", "cheese", "chef",
|
||||
|
||||
// D
|
||||
"decide", "demonstrate", "draw", "druggist",
|
||||
"daisy", "dance", "danger", "daring", "database", "debate", "decade",
|
||||
"decline", "decorate", "decrease", "dedicate", "defeat", "defend", "define",
|
||||
"degree", "delight", "delivery", "demand", "dentist", "deny", "depart",
|
||||
"depth", "describe", "deserve", "desire", "destroy", "develop", "device",
|
||||
|
||||
// E
|
||||
"eagle", "ear", "effort", "evening",
|
||||
"early", "earn", "earth", "ease", "east", "easy", "echo",
|
||||
"eclipse", "economy", "edge", "edit", "educate", "effect", "effort",
|
||||
"egg", "eight", "either", "elder", "elect", "elegant", "element",
|
||||
"elephant", "elevator", "elite", "embark", "embrace", "emerge", "emotion",
|
||||
|
||||
// F
|
||||
"fabric", "famous", "fuse",
|
||||
"face", "factor", "fail", "fair", "fall", "false", "fame",
|
||||
"family", "fancy", "fantasy", "farewell", "farm", "fashion", "fast",
|
||||
"fault", "favor", "feather", "feature", "federal", "feedback", "feeling",
|
||||
"female", "fence", "festival", "fever", "fiber", "fiction", "field",
|
||||
|
||||
// G
|
||||
"generation", "generous", "girl", "gypsy", "grip",
|
||||
"gallery", "game", "garage", "garden", "garlic", "gas", "gate",
|
||||
"gather", "general", "genius", "gentle", "genuine", "geography", "gesture",
|
||||
"ghost", "giant", "gift", "giggle", "ginger", "giraffe", "glance",
|
||||
"glass", "globe", "glory", "glove", "glue", "goal", "gold",
|
||||
|
||||
// H
|
||||
"habit", "handsome", "helmet", "help", "horror",
|
||||
"hair", "half", "hammer", "hand", "handle", "hang", "happen",
|
||||
"harbor", "hard", "harm", "harvest", "hat", "hate", "have",
|
||||
"head", "health", "heart", "heat", "heaven", "heavy", "hedge",
|
||||
"height", "hello", "heritage", "hero", "hesitate", "hidden", "high",
|
||||
|
||||
// I
|
||||
"insist", "inventor", "itself", "ivory",
|
||||
"ice", "idea", "ideal", "identify", "ignore", "ill", "image",
|
||||
"imagine", "impact", "import", "impress", "improve", "impulse", "inch",
|
||||
"include", "income", "increase", "index", "industry", "infant", "inform",
|
||||
"insect", "inside", "inspire", "install", "instead", "insult", "intact",
|
||||
|
||||
// J
|
||||
"jog", "joint", "joke", "judge",
|
||||
"jacket", "jaguar", "jail", "jam", "january", "jar", "jazz",
|
||||
"jealous", "jeans", "jelly", "jewel", "job", "join", "journey",
|
||||
"joy", "judge", "juice", "jump", "jungle", "junior", "justice",
|
||||
"just", "justify", "juggle", "juice", "jumper", "junction", "jury",
|
||||
|
||||
// K
|
||||
"karate", "kebab", "kitchen",
|
||||
"kangaroo", "keen", "keep", "kettle", "key", "keyboard", "kick",
|
||||
"kid", "kidney", "king", "kiss", "kite", "knee", "knife",
|
||||
"knit", "knock", "knot", "know", "knowledge", "koala", "kudos",
|
||||
"keen", "kernel", "kit", "kitten", "knack", "knight", "knock",
|
||||
|
||||
// L
|
||||
"lamb", "lawnmower", "left", "lock",
|
||||
"label", "labor", "lace", "ladder", "lady", "lake", "lamp",
|
||||
"land", "language", "large", "laser", "last", "later", "laugh",
|
||||
"launch", "law", "layer", "lead", "leaf", "learn", "least",
|
||||
"leather", "leave", "lecture", "legal", "legend", "lemon", "length",
|
||||
|
||||
// M
|
||||
"math", "medicine", "most",
|
||||
"machine", "magnet", "mail", "main", "major", "make", "male",
|
||||
"manage", "mango", "manner", "manual", "map", "marble", "march",
|
||||
"mark", "market", "marriage", "master", "match", "material", "matter",
|
||||
"maximum", "mayor", "meal", "mean", "measure", "media", "memory",
|
||||
|
||||
// N
|
||||
"noodles", "nowadays", "nowhere",
|
||||
"nail", "name", "narrow", "nation", "native", "nature", "navy",
|
||||
"near", "neat", "necessary", "neck", "need", "negative", "neglect",
|
||||
"neither", "nerve", "nest", "net", "network", "neutral", "never",
|
||||
"new", "news", "next", "nice", "night", "noble", "noise",
|
||||
|
||||
// O
|
||||
"ocean", "older", "ounce",
|
||||
"object", "observe", "obtain", "occasion", "occupy", "occur", "ocean",
|
||||
"offer", "office", "often", "oil", "old", "olive", "olympic",
|
||||
"omit", "once", "one", "onion", "online", "only", "open",
|
||||
"opera", "opinion", "oppose", "option", "orange", "orbit", "order",
|
||||
|
||||
// P
|
||||
"part", "pathetic", "pastime",
|
||||
"pace", "package", "page", "pain", "paint", "pair", "palm",
|
||||
"panel", "panic", "paper", "parent", "park", "part", "party",
|
||||
"pass", "path", "patient", "pattern", "pause", "peace", "peak",
|
||||
"pen", "pencil", "people", "pepper", "perfect", "perform", "permit",
|
||||
|
||||
// Q
|
||||
"quite", "quits", "quotation",
|
||||
"quality", "quantity", "quarter", "queen", "query", "quest", "quick",
|
||||
"quiet", "quilt", "quit", "quote", "quiz", "quota", "quiver",
|
||||
"quirky", "quaint", "quake", "qualification", "qualify", "quark", "quartz",
|
||||
"queue", "quench", "question", "quote", "quiver", "quorum", "quote",
|
||||
|
||||
// R
|
||||
"race", "raise", "reality",
|
||||
"rabbit", "race", "radio", "rain", "raise", "random", "range",
|
||||
"rapid", "rare", "rate", "rather", "ratio", "reach", "react",
|
||||
"read", "ready", "real", "reason", "rebel", "recall", "receive",
|
||||
"recipe", "record", "recover", "reduce", "refer", "reflect", "reform",
|
||||
|
||||
// S
|
||||
"safe", "scare", "screen",
|
||||
"sack", "sail", "salad", "salt", "same", "sample", "sand",
|
||||
"save", "scale", "scan", "scar", "scene", "school", "science",
|
||||
"score", "scratch", "scream", "screen", "script", "search", "season",
|
||||
"seat", "second", "secret", "section", "secure", "see", "seed",
|
||||
|
||||
// T
|
||||
"taught", "temple", "that", "this",
|
||||
"table", "tackle", "tail", "take", "tale", "talent", "talk",
|
||||
"tank", "tape", "target", "task", "taste", "tax", "teach",
|
||||
"team", "tear", "technology", "telephone", "television", "temperature", "tend",
|
||||
"tennis", "tent", "term", "test", "text", "thank", "theory",
|
||||
|
||||
// U
|
||||
"unable", "unkind", "usual",
|
||||
"umbrella", "unable", "uncle", "under", "undo", "unfair", "unfold",
|
||||
"union", "unique", "unit", "universe", "unknown", "unless", "unlike",
|
||||
"unlock", "until", "unusual", "update", "upgrade", "upon", "upper",
|
||||
"upset", "urban", "urge", "use", "usual", "utility", "utter",
|
||||
|
||||
// V
|
||||
"velvet", "vivid", "vote",
|
||||
"vacuum", "valid", "valley", "value", "vampire", "van", "vase",
|
||||
"vast", "vault", "vector", "vehicle", "velvet", "vendor", "venture",
|
||||
"verb", "verify", "version", "vessel", "veteran", "veto", "vibrate",
|
||||
"victory", "video", "view", "village", "violin", "virtue", "virus",
|
||||
|
||||
// W
|
||||
"we", "warm", "watch",
|
||||
"wage", "wait", "walk", "wall", "wander", "want", "war",
|
||||
"wash", "waste", "watch", "water", "wave", "way", "wealth",
|
||||
"weapon", "wear", "weather", "weave", "wedding", "week", "weight",
|
||||
"welcome", "well", "west", "wheel", "when", "whisper", "white",
|
||||
|
||||
// X
|
||||
"xylophone",
|
||||
"xenon", "xenophobia", "xerox", "xmas", "x-ray", "xylophone", "xylem",
|
||||
|
||||
// Y
|
||||
"yolk", "young", "your",
|
||||
"yard", "yarn", "year", "yell", "yellow", "yes", "yesterday",
|
||||
"yet", "yield", "yogurt", "yoke", "youth", "yawn", "yearn",
|
||||
"yacht", "yummy", "yogurt", "yoga", "yardstick", "yonder", "yummy",
|
||||
|
||||
// Z
|
||||
"zebra", "zodiac", "zucchini",
|
||||
"zero", "zone", "zoo", "zoom", "zeal", "zip", "zigzag",
|
||||
"zenith", "zest", "zipper", "zombie", "zonal", "zinc", "zephyr"
|
||||
};
|
||||
|
||||
int words_size = sizeof(words)/sizeof(words[0]);
|
||||
|
||||
// Generates 5 random words
|
||||
void program_words()
|
||||
// Generates random words
|
||||
void program_words(int argc, char* argv[])
|
||||
{
|
||||
for (int i=0; i<10; i++)
|
||||
int amount;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
amount = 10;
|
||||
} else if (argc == 2)
|
||||
{
|
||||
amount = atoi(argv[1]);
|
||||
}
|
||||
|
||||
for (int i=0; i<amount; i++)
|
||||
{
|
||||
int random = randint(global_ticks);
|
||||
char* word = words[random%words_size];
|
||||
|
||||
BIN
stage2_eltorito
BIN
stage2_eltorito
Binary file not shown.
Reference in New Issue
Block a user