Skip to content

Commit

Permalink
feat(stdio): add the printf function to the kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
towca authored and Marcin Kościelnicki committed Jul 2, 2018
1 parent 7596688 commit 67f5205
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
all: kernel loader

OBJS := main.o gdt.o page.o
OBJS := main.o gdt.o page.o stdio.o

kernel: kernel.lds kernel.o $(OBJS)
ld -Tkernel.lds kernel.o -o kernel $(OBJS)
Expand Down
17 changes: 8 additions & 9 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "msr.h"
#include "page.h"
#include "io.h"
#include "stdio.h"

char hello[] = "Hello, C world!";

void *memset(void *s, int c, size_t n) {
Expand Down Expand Up @@ -81,15 +83,7 @@ void sys_print(unsigned x, unsigned y, uint16_t *chars, unsigned n) {
}

void sys_setcursor(unsigned x, unsigned y) {
if (x >= 80)
return;
if (y >= 25)
return;
unsigned addr = x + y * 80;
outb(0x3d4, 0xe);
outb(0x3d5, addr >> 8);
outb(0x3d4, 0xf);
outb(0x3d5, addr);
setcursor(x, y);
}

int kbd_getbyte(void) {
Expand Down Expand Up @@ -167,6 +161,11 @@ __asm__(
extern void user_prog;

void main() {
clrscr();
for (int i = 97; i < 127; i++) {
printf("printf demo: char=%c, dec=%d, hex=%x, str comment = %s\n", i, i, i, "\"no comment\"");
}

init_gdt();
init_pg();
// ELF loader start
Expand Down
1 change: 0 additions & 1 deletion prog

This file was deleted.

Binary file added prog
Binary file not shown.
156 changes: 156 additions & 0 deletions stdio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#include <stdarg.h>
#include <stdint.h>
#include "stdio.h"
#include "io.h"


#define VGA_WRITE_START 0xffff8000000b8000ull
#define DEFAULT_FORCOLOR 0x0d
#define DEFAULT_BACKCOLOR 0x0f
#define WIDTH 80
#define HEIGHT 25


uint16_t screen[WIDTH * HEIGHT];
int cur_x = 0;
int cur_y = 0;


static void writec(char c, unsigned x, unsigned y, uint8_t forecolor, uint8_t backcolor) {
uint16_t colors = (backcolor << 4) | (forecolor & 0x0F);
uint16_t write_arg = c | colors << 8;
unsigned pos = y * WIDTH + x;
screen[pos] = write_arg;
((uint16_t*)VGA_WRITE_START)[pos] = screen[pos];
}

void setcursor(unsigned x, unsigned y) {
if (x >= WIDTH)
return;
if (y >= HEIGHT)
return;
unsigned addr = x + y * 80;
outb(0x3d4, 0xe);
outb(0x3d5, addr >> 8);
outb(0x3d4, 0xf);
outb(0x3d5, addr);
}

static void scroll(void) {
for (unsigned y = 1; y < HEIGHT; y++) {
for (unsigned x = 0; x < WIDTH; x++) {
unsigned src_pos = y * WIDTH + x;
unsigned dst_pos = (y - 1) * WIDTH + x;
screen[dst_pos] = screen[src_pos];
((uint16_t*)VGA_WRITE_START)[dst_pos] = screen[dst_pos];
}
}

for (unsigned x = 0; x < WIDTH; x++) {
writec(' ', x, HEIGHT - 1, DEFAULT_FORCOLOR, DEFAULT_BACKCOLOR);
}
}

void clrscr(void) {
for (unsigned x = 0; x < WIDTH; x++) {
for (unsigned y = 0; y < HEIGHT; y++) {
writec(' ', x, y, DEFAULT_FORCOLOR, DEFAULT_BACKCOLOR);
}
}
setcursor(0, 0);
}

void putc(uint8_t c) {
if (c == '\n') {
cur_x = 0;
cur_y++;
}
else {
writec(c, cur_x, cur_y, DEFAULT_FORCOLOR, DEFAULT_BACKCOLOR);
cur_y = (cur_x + 1 == WIDTH) ? cur_y + 1 : cur_y;
cur_x = (cur_x + 1) % WIDTH;
}

if (cur_y == HEIGHT) {
scroll();
cur_y--;
}
setcursor(cur_x, cur_y);
}

static void print_char(char c) {
putc(c);
}

static void print_str(uint8_t* str) {
while (*str) {
putc(*str);
str++;
}
}

static void print_num(uint32_t num, uint8_t base) {
uint32_t tmp;
uint8_t i = 0;
uint8_t digits[8] = { 0 };

if (!num) {
putc('0');
return;
}

while (num) {
tmp = num;
num /= base;
digits[i] = "0123456789abcdef"[tmp - (num * base)];
i++;
}

for (int j = i - 1; j >= 0; j--) {
putc(digits[j]);
}
}

void printf(uint8_t* format, ...) {
va_list va;
va_start(va, format);
uint8_t c, b;
uint8_t* str;
uint32_t num;

while (*format) {
c = *format;
if (c != '%') {
putc(c);
}
else {
format++;
c = *format;

switch(c) {
case 'c':
b = (uint8_t) va_arg(va, uint32_t);
print_char(b);
break;
case 's':
str = va_arg(va, uint8_t*);
print_str(str);
break;
case 'd':
num = va_arg(va, uint32_t);
print_num(num, 10);
break;
case 'x':
num = va_arg(va, uint32_t);
putc('0');
putc('x');
print_num(num, 16);
break;
}
}

format++;
}

va_end(va);
}
9 changes: 9 additions & 0 deletions stdio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef STDIO_H
#define STDIO_H

void clrscr(void);
void setcursor(unsigned x, unsigned y);
void putc(uint8_t c);
void printf(uint8_t* format, ...);

#endif

0 comments on commit 67f5205

Please sign in to comment.