Added:
- TTY driver - VGA driver - kernel's main function - Makefiles *NOTE*: iceOS not works at this stage.
This commit is contained in:
parent
bb59c7532f
commit
bec03e3d1b
10
Makefile
10
Makefile
@ -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
30
build.sh
Normal file → Executable 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
|
@ -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 $@
|
@ -6,14 +6,14 @@
|
||||
; https://github.com/ice-bit/iceOS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
global kernel_loader
|
||||
extern main
|
||||
global kernel_load
|
||||
extern kernel_main
|
||||
|
||||
section .text
|
||||
kernel_loader:
|
||||
mov esp, kernel_stack + KERNEL_STACK_SZ ; Stack pointer
|
||||
push ebx
|
||||
call main ; jump to kernel's main function
|
||||
call kernel_main ; jump to kernel's main function
|
||||
.loop:
|
||||
jmp .loop ; endless loop
|
||||
|
||||
|
10
kernel/drivers/Makefile
Normal file
10
kernel/drivers/Makefile
Normal 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
20
kernel/drivers/ports.h
Normal 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
109
kernel/drivers/tty.c
Normal 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
60
kernel/drivers/tty.h
Normal 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
|
@ -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
10
kernel/libc/Makefile
Normal 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 $@
|
@ -1,7 +1,6 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "drivers/shell.h"
|
||||
|
||||
#include "../drivers/tty.h"
|
||||
|
||||
int printf(const char *format, ...) {
|
||||
char buf[20],c,*s;
|
||||
@ -20,32 +19,36 @@ int printf(const char *format, ...) {
|
||||
case 'i':
|
||||
val = va_arg(ap, int);
|
||||
itoa(val, buf, 10);
|
||||
printk(buf);
|
||||
kprint(buf);
|
||||
break;
|
||||
case 'x':
|
||||
uval = va_arg(ap, uint32_t);
|
||||
uitoa(uval, buf, 16);
|
||||
printk(buf);
|
||||
kprint(buf);
|
||||
break;
|
||||
case 'd':
|
||||
uval = va_arg(ap, uint32_t);
|
||||
uitoa(uval, buf, 10);
|
||||
printk(buf);
|
||||
kprint(buf);
|
||||
break;
|
||||
case 'c':
|
||||
s = va_arg(ap, char*);
|
||||
printk_c(&c, 1);
|
||||
kprint_c(&c, 1, WHITE, BLACK);
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(ap, char*);
|
||||
printk(s);
|
||||
kprint(s);
|
||||
break;
|
||||
default:
|
||||
printk_c((char*)format+1, 1);
|
||||
kprint_c((char*)format+1, 1, WHITE, BLACK);
|
||||
}
|
||||
} else
|
||||
printk_c((char*)format+1, 1);
|
||||
kprint_c((char*)format+1, 1, WHITE, BLACK);
|
||||
}
|
||||
va_end(ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void puts(int8_t *buf) {
|
||||
printf("%s\n", buf);
|
||||
}
|
@ -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_
|
||||
#define _STDIO_H
|
||||
#define _STDIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int printf(const char *format, ...);
|
||||
void puts(uint8_t *buf);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user