- TTY driver
- VGA driver
- kernel's main function
- Makefiles

*NOTE*: iceOS not works at this stage.
This commit is contained in:
ice-bit 2019-07-03 18:12:57 +02:00
parent bb59c7532f
commit bec03e3d1b
13 changed files with 328 additions and 13 deletions

View File

@ -0,0 +1,10 @@
iso:
grub-mkrescue iso_root -o iceOS.iso
run:
qemu-system-x86_64 -cdrom iceOS.iso
clean:
rm -rf obj/ kernel/*.o kernel/cpu/*.o iso_root/boot/kernel.elf
rm -rf kernel/drivers/*.o kernel/libc/*.o
rm -rf PyramidKernel.iso bochslog.txt commands

30
build.sh Normal file → Executable file
View File

@ -0,0 +1,30 @@
# grub config file
mkdir -p iso_root/boot/grub/
cat iso_root/boot/grub/grub.cfg <<EOF
set timeout = 0
set default = 0
menuentry "iceOS" {
multiboot2 /boot/kernel.elf
boot
}
EOF
# CPU
mkdir -p obj/
make -C kernel/cpu
cp kernel/cpu*.o obj/
# Kernel
make -C kernel/
cp kernel/*.o obj/
# Drivers
make -C kernel/drivers/
cp kernel/drivers/*.o obj/
# Libc
make -C kernel/libc
cp kernel/libc/*.o obj/
i686-elf-ld -melf_i386 -nostdlib -O2 -T link.ld -o iso_root/boot/kernel.elf obj/*.o

View File

@ -0,0 +1,10 @@
OBJS = kernel_main.o
CC = i686-elf-gcc # cross-compiler
CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c
all:${OBJS}
%.o: %.c
$(CC) $(CFLAGS) $< -o $@

View File

@ -6,14 +6,14 @@
; https://github.com/ice-bit/iceOS ; ; https://github.com/ice-bit/iceOS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
global kernel_loader global kernel_load
extern main extern kernel_main
section .text section .text
kernel_loader: kernel_loader:
mov esp, kernel_stack + KERNEL_STACK_SZ ; Stack pointer mov esp, kernel_stack + KERNEL_STACK_SZ ; Stack pointer
push ebx push ebx
call main ; jump to kernel's main function call kernel_main ; jump to kernel's main function
.loop: .loop:
jmp .loop ; endless loop jmp .loop ; endless loop

10
kernel/drivers/Makefile Normal file
View File

@ -0,0 +1,10 @@
OBJS = tty.o
CC = i686-elf-gcc # cross-compiler
CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c
all:${OBJS}
%.o: %.c
$(CC) $(CFLAGS) $< -o $@

20
kernel/drivers/ports.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _PORTS_H
#define _PORTS_H
#include <stdint.h>
/* outb:
* Redirect data to port(high level interface for ports.asm)
* @param port: Output port to send data to.
* @param data: The actual data to send to port
*/
void outb(uint16_t port, uint8_t data);
/* inb:
* Fetch data from a port, return a char
* @param port: Input port to read data from.
*/
uint8_t inb(uint16_t port);
#endif

109
kernel/drivers/tty.c Normal file
View File

@ -0,0 +1,109 @@
#include "tty.h"
#include "../libc/string.h"
#include "ports.h"
#define VGA_PTR ((uint8_t*) VIDEO_MEM_ADDR) // Pointer to frame buffer
// Also define a 2 byte pointer because cells are 16 bits wide
#define UVGA_PTR ((uint16_t *)VIDEO_MEM_ADDR)
static uint32_t fb_col = 0; // X
static uint32_t fb_row = 0; // Y
void write_cell(int16_t i, int8_t c, uint8_t fg, uint8_t bg) {
uint8_t *fb = VGA_PTR;
fb[i*2] = c;
fb[i*2 + 1] = ((bg & 0x0F) << 4) | (fg | 0x0F);
}
void move_cursor(uint16_t pos) {
outb(VGA_CMD_PORT, VGA_HIGH_BYTE);
outb(VGA_DATA_PORT, ((pos >> 8) & 0x00FF));
outb(VGA_CMD_PORT, VGA_LOW_BYTE);
outb(VGA_DATA_PORT, pos & 0x00FF);
}
void cursor_adv() {
if(fb_col < VGA_WIDTH - 1)
fb_col--;
else
newline();
move_cursor(fb_col + (fb_row * VGA_WIDTH));
}
void cursor_prev() {
if(fb_col == 0) {
if(fb_row == 0)
return; // If first row do not do anything
fb_col = VGA_WIDTH - 1;
fb_row--;
} else
fb_col--;
move_cursor(fb_col + (fb_row * VGA_WIDTH));
}
void backspace() {
uint16_t pos;
uint8_t c = ' ';
fb_col--;
pos = fb_col + (fb_row * VGA_WIDTH);
write_cell(pos, c, WHITE, BLACK);
}
void kprint_c(uint8_t *buf, uint32_t len, uint8_t fg, uint8_t bg) {
uint16_t pos;
for(uint32_t i = 0; i < len; i++) {
uint8_t c = buf[i];
if(c == '\n' || c == '\r')
newline();
else if(c == '\t') {
pos = fb_col + (fb_row * VGA_WIDTH);
write_cell(pos, " ", fg, bg);
cursor_adv();
} else {
pos = fb_col + (fb_row * VGA_WIDTH);
write_cell(pos, c, fg, bg);
cursor_adv();
}
}
}
void kprint(uint8_t *buf) {
kprint_c(buf, strlen(buf), WHITE, BLACK);
}
void init_prompt() {
const uint8_t *prompt = "\nuser@iceOS-$";
kprint_c(prompt, strlen(prompt), GREEN, BLACK);
}
void clear_prompt() {
fb_col = 0;
fb_row = 0;
for(uint32_t i = 0; i < (VGA_WIDTH * VGA_HEIGHT); i++)
write_cell(i, ' ', WHITE, BLACK);
move_cursor(0);
}
void clear_row(uint8_t row) {
for(size_t i = 0; i < VGA_WIDTH; i++)
write_cell((row*VGA_WIDTH)+i, ' ', WHITE, BLACK);
}
void scroll() {
uint16_t *fb = UVGA_PTR;
memmove(fb, fb+VGA_WIDTH, VGA_WIDTH*2*(VGA_HEIGHT*2-1));
clear_row(VGA_HEIGHT - 1);
}
void newline() {
if(fb_row < VGA_HEIGHT - 1) // If there's at least one cell add it
fb_row++;
else // Otherwise scroll framebuffer
scroll();
fb_col = 0;
move_cursor(fb_col + (fb_row * VGA_WIDTH));
}

60
kernel/drivers/tty.h Normal file
View File

@ -0,0 +1,60 @@
/**************************************
* iceOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
#ifndef _TTY_H_
#define _TTY_H_
#include <stdint.h>
// VGA colors
enum TTY_COLORS {
BLACK, // 0
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHT_GREY,
DARK_GREY,
LIGHT_BLUE,
LIGHT_GREEN,
LIGHT_CYAN,
LIGHT_RED,
LIGHT_MAGENTA,
LIGHT_BROWN,
WHITE // 15
};
/* Framebuffer properties */
#define VIDEO_MEM_ADDR 0x000B8000 // frame buffer address
#define VGA_WIDTH 80
#define VGA_HEIGHT 25
/* VGA I/O ports */
#define VGA_CMD_PORT 0x3D4
#define VGA_DATA_PORT 0x3D5
/* VGA I/O ports commands */
#define VGA_HIGH_BYTE 14
#define VGA_LOW_BYTE 15
/* Kernel's VGA API */
void write_cell(int16_t i, int8_t c, uint8_t fg, uint8_t bg);
void move_cursor(uint16_t pos);
void cursor_adv();
void backspace();
void kprint_c(uint8_t *buf, uint32_t len, uint8_t fg, uint8_t bg);
void kprint(uint8_t *buf);
void init_prompt();
void clear_prompt();
void clear_row(uint8_t row);
void scroll(); // Scroll one row
void newline();
#endif

View File

@ -0,0 +1,9 @@
#include "drivers/tty.h"
#include "libc/stdio.h"
void kernel_main() {
clear_prompt();
init_prompt();
puts("Hello World!");
}

10
kernel/libc/Makefile Normal file
View File

@ -0,0 +1,10 @@
OBJS = stdio.o string.o
CC = i686-elf-gcc # cross-compiler
CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c
all:${OBJS}
%.o: %.c
$(CC) $(CFLAGS) $< -o $@

View File

@ -1,7 +1,6 @@
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
#include "drivers/shell.h" #include "../drivers/tty.h"
int printf(const char *format, ...) { int printf(const char *format, ...) {
char buf[20],c,*s; char buf[20],c,*s;
@ -20,32 +19,36 @@ int printf(const char *format, ...) {
case 'i': case 'i':
val = va_arg(ap, int); val = va_arg(ap, int);
itoa(val, buf, 10); itoa(val, buf, 10);
printk(buf); kprint(buf);
break; break;
case 'x': case 'x':
uval = va_arg(ap, uint32_t); uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 16); uitoa(uval, buf, 16);
printk(buf); kprint(buf);
break; break;
case 'd': case 'd':
uval = va_arg(ap, uint32_t); uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 10); uitoa(uval, buf, 10);
printk(buf); kprint(buf);
break; break;
case 'c': case 'c':
s = va_arg(ap, char*); s = va_arg(ap, char*);
printk_c(&c, 1); kprint_c(&c, 1, WHITE, BLACK);
break; break;
case 's': case 's':
s = va_arg(ap, char*); s = va_arg(ap, char*);
printk(s); kprint(s);
break; break;
default: default:
printk_c((char*)format+1, 1); kprint_c((char*)format+1, 1, WHITE, BLACK);
} }
} else } else
printk_c((char*)format+1, 1); kprint_c((char*)format+1, 1, WHITE, BLACK);
} }
va_end(ap); va_end(ap);
return 0; return 0;
} }
void puts(int8_t *buf) {
printf("%s\n", buf);
}

View File

@ -1,10 +1,19 @@
/**************************************
* iceOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
#ifndef _STDIO_H_ #ifndef _STDIO_H_
#define _STDIO_H #define _STDIO_H_
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
int printf(const char *format, ...); int printf(const char *format, ...);
void puts(uint8_t *buf);
#endif #endif

35
link.ld
View File

@ -0,0 +1,35 @@
ENTRY(kernel_load)
. = 0x00100000;
SECTIONS {
.boot ALIGN (0x1000):
{
*(.multiboot)
}
.text ALIGN (0x1000):
{
*(.text)
}
.rodata ALIGN (0x1000):
{
*(.rodata*)
}
.data ALIGN (0x1000):
{
*(.data)
}
.bss ALIGN (0x1000):
{
*(COMMON)
*(.bss)
}
}
end = .;