Add C89 Support

pull/187/head
Simon Chaykin 4 years ago
parent 7aff64740e
commit 647cc4fe6a

@ -4,10 +4,10 @@ HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h libc/*.h)
OBJ = ${C_SOURCES:.c=.o cpu/interrupt.o}
# Change this if your cross-compiler is somewhere else
CC = /usr/local/i386elfgcc/bin/i386-elf-gcc
GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb
CC = gcc -m32 -Wall -Wextra -pedantic-errors -std=c89
GDB = gdb
# -g: Use debugging symbols in gcc
CFLAGS = -g -ffreestanding -Wall -Wextra -fno-exceptions -m32
CFLAGS = -g -ffreestanding -Wall -Wextra -fno-exceptions -m32 -fno-pie
# First rule is run by default
os-image.bin: boot/bootsect.bin kernel.bin
@ -16,11 +16,11 @@ os-image.bin: boot/bootsect.bin kernel.bin
# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernel_entry.o ${OBJ}
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
@ld -melf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary
# Used for debugging purposes
kernel.elf: boot/kernel_entry.o ${OBJ}
i386-elf-ld -o $@ -Ttext 0x1000 $^
ld -melf_i386 -o $@ -Ttext 0x1000 $^
run: os-image.bin
qemu-system-i386 -fda os-image.bin

@ -13,5 +13,5 @@ void set_idt() {
idt_reg.base = (uint32_t) &idt;
idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
/* Don't make the mistake of loading &idt -- always load &idt_reg */
asm volatile("lidtl (%0)" : : "r" (&idt_reg));
__asm__ volatile("lidtl (%0)" : : "r" (&idt_reg));
}

@ -44,7 +44,7 @@ void isr_install() {
set_idt_gate(30, (uint32_t)isr30);
set_idt_gate(31, (uint32_t)isr31);
// Remap the PIC
/* Remap the PIC */
port_byte_out(0x20, 0x11);
port_byte_out(0xA0, 0x11);
port_byte_out(0x21, 0x20);
@ -56,7 +56,7 @@ void isr_install() {
port_byte_out(0x21, 0x0);
port_byte_out(0xA1, 0x0);
// Install the IRQs
/* Install the IRQs */
set_idt_gate(32, (uint32_t)irq0);
set_idt_gate(33, (uint32_t)irq1);
set_idt_gate(34, (uint32_t)irq2);
@ -74,7 +74,7 @@ void isr_install() {
set_idt_gate(46, (uint32_t)irq14);
set_idt_gate(47, (uint32_t)irq15);
set_idt(); // Load with ASM
set_idt(); /* Load with ASM */
}
/* To print the message which defines every exception */
@ -117,8 +117,8 @@ char *exception_messages[] = {
};
void isr_handler(registers_t *r) {
kprint("received interrupt: ");
char s[3];
kprint("received interrupt: ");
int_to_ascii(r->int_no, s);
kprint(s);
kprint("\n");
@ -133,19 +133,20 @@ void register_interrupt_handler(uint8_t n, isr_t handler) {
void irq_handler(registers_t *r) {
/* After every interrupt we need to send an EOI to the PICs
* or they will not send another interrupt again */
isr_t handler;
if (r->int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */
port_byte_out(0x20, 0x20); /* master */
/* Handle the interrupt in a more modular way */
if (interrupt_handlers[r->int_no] != 0) {
isr_t handler = interrupt_handlers[r->int_no];
handler = interrupt_handlers[r->int_no];
handler(r);
}
}
void irq_install() {
/* Enable interruptions */
asm volatile("sti");
__asm__ volatile("sti");
/* IRQ0: timer */
init_timer(50);
/* IRQ1: keyboard */

@ -13,7 +13,7 @@ uint8_t port_byte_in (uint16_t port) {
*
* Inputs and outputs are separated by colons
*/
asm("in %%dx, %%al" : "=a" (result) : "d" (port));
__asm__ volatile("in %%dx, %%al" : "=a" (result) : "d" (port));
return result;
}
@ -23,15 +23,15 @@ void port_byte_out (uint16_t port, uint8_t data) {
* However we see a comma since there are two variables in the input area
* and none in the 'return' area
*/
asm volatile("out %%al, %%dx" : : "a" (data), "d" (port));
__asm__ volatile("out %%al, %%dx" : : "a" (data), "d" (port));
}
uint16_t port_word_in (uint16_t port) {
uint16_t result;
asm("in %%dx, %%ax" : "=a" (result) : "d" (port));
__asm__ volatile("in %%dx, %%ax" : "=a" (result) : "d" (port));
return result;
}
void port_word_out (uint16_t port, uint16_t data) {
asm volatile("out %%ax, %%dx" : : "a" (data), "d" (port));
__asm__ volatile("out %%ax, %%dx" : : "a" (data), "d" (port));
}

@ -11,13 +11,14 @@ static void timer_callback(registers_t *regs) {
}
void init_timer(uint32_t freq) {
/* Install the function we just wrote */
register_interrupt_handler(IRQ0, timer_callback);
/* Get the PIT value: hardware clock at 1193180 Hz */
uint32_t divisor = 1193180 / freq;
uint8_t low = (uint8_t)(divisor & 0xFF);
uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF);
/* Install the function we just wrote */
register_interrupt_handler(IRQ0, timer_callback);
/* Send the command */
port_byte_out(0x43, 0x36); /* Command port */
port_byte_out(0x40, low);

@ -28,7 +28,8 @@ const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6',
static void keyboard_callback(registers_t *regs) {
/* The PIC leaves us the scancode in port 0x60 */
uint8_t scancode = port_byte_in(0x60);
char letter;
char str[2];
if (scancode > SC_MAX) return;
if (scancode == BACKSPACE) {
backspace(key_buffer);
@ -38,9 +39,10 @@ static void keyboard_callback(registers_t *regs) {
user_input(key_buffer); /* kernel-controlled function */
key_buffer[0] = '\0';
} else {
char letter = sc_ascii[(int)scancode];
letter = sc_ascii[(int)scancode];
/* Remember that kprint only accepts char[] */
char str[2] = {letter, '\0'};
str[0] = letter;
str[1] = '\0';
append(key_buffer, letter);
kprint(str);
}

@ -21,7 +21,7 @@ int get_offset_col(int offset);
*/
void kprint_at(char *message, int col, int row) {
/* Set cursor if col/row are negative */
int offset;
int offset, i = 0;
if (col >= 0 && row >= 0)
offset = get_offset(col, row);
else {
@ -31,7 +31,6 @@ void kprint_at(char *message, int col, int row) {
}
/* Loop through message and print it */
int i = 0;
while (message[i] != 0) {
offset = print_char(message[i++], col, row, WHITE_ON_BLACK);
/* Compute row/col for next iteration */
@ -67,6 +66,9 @@ void kprint_backspace() {
*/
int print_char(char c, int col, int row, char attr) {
uint8_t *vidmem = (uint8_t*) VIDEO_ADDRESS;
int offset;
int i;
char *last_line;
if (!attr) attr = WHITE_ON_BLACK;
/* Error control: print a red 'E' if the coords aren't right */
@ -76,7 +78,6 @@ int print_char(char c, int col, int row, char attr) {
return get_offset(col, row);
}
int offset;
if (col >= 0 && row >= 0) offset = get_offset(col, row);
else offset = get_cursor_offset();
@ -94,14 +95,13 @@ int print_char(char c, int col, int row, char attr) {
/* Check if the offset is over screen size and scroll */
if (offset >= MAX_ROWS * MAX_COLS * 2) {
int i;
for (i = 1; i < MAX_ROWS; i++)
for (i = 1; i < MAX_ROWS; i++)
memory_copy((uint8_t*)(get_offset(0, i) + VIDEO_ADDRESS),
(uint8_t*)(get_offset(0, i-1) + VIDEO_ADDRESS),
MAX_COLS * 2);
/* Blank last line */
char *last_line = (char*) (get_offset(0, MAX_ROWS-1) + (uint8_t*) VIDEO_ADDRESS);
last_line = (char*) (get_offset(0, MAX_ROWS-1) + (uint8_t*) VIDEO_ADDRESS);
for (i = 0; i < MAX_COLS * 2; i++) last_line[i] = 0;
offset -= 2 * MAX_COLS;
@ -116,8 +116,9 @@ int get_cursor_offset() {
* 1. Ask for high byte of the cursor offset (data 14)
* 2. Ask for low byte (data 15)
*/
int offset;
port_byte_out(REG_SCREEN_CTRL, 14);
int offset = port_byte_in(REG_SCREEN_DATA) << 8; /* High byte: << 8 */
offset = port_byte_in(REG_SCREEN_DATA) << 8; /* High byte: << 8 */
port_byte_out(REG_SCREEN_CTRL, 15);
offset += port_byte_in(REG_SCREEN_DATA);
return offset * 2; /* Position * size of character cell */

@ -9,24 +9,25 @@ void kernel_main() {
isr_install();
irq_install();
asm("int $2");
asm("int $3");
__asm__ volatile("int $2");
__asm__ volatile("int $3");
kprint("Type something, it will go through the kernel\n"
"Type END to halt the CPU or PAGE to request a kmalloc()\n> ");
}
void user_input(char *input) {
char page_str[16] = "";
char phys_str[16] = "";
uint32_t phys_addr;
uint32_t page;
if (strcmp(input, "END") == 0) {
kprint("Stopping the CPU. Bye!\n");
asm volatile("hlt");
__asm__ volatile("hlt");
} else if (strcmp(input, "PAGE") == 0) {
/* Lesson 22: Code to test kmalloc, the rest is unchanged */
uint32_t phys_addr;
uint32_t page = kmalloc(1000, 1, &phys_addr);
char page_str[16] = "";
page = kmalloc(1000, 1, &phys_addr);
hex_to_ascii(page, page_str);
char phys_str[16] = "";
hex_to_ascii(phys_addr, phys_str);
kprint("Page: ");
kprint(page_str);

@ -19,6 +19,7 @@ uint32_t free_mem_addr = 0x10000;
/* Implementation is just a pointer to some free memory which
* keeps growing */
uint32_t kmalloc(size_t size, int align, uint32_t *phys_addr) {
uint32_t ret;
/* Pages are aligned to 4K, or 0x1000 */
if (align == 1 && (free_mem_addr & 0xFFFFF000)) {
free_mem_addr &= 0xFFFFF000;
@ -27,7 +28,7 @@ uint32_t kmalloc(size_t size, int align, uint32_t *phys_addr) {
/* Save also the physical address */
if (phys_addr) *phys_addr = free_mem_addr;
uint32_t ret = free_mem_addr;
ret = free_mem_addr;
free_mem_addr += size; /* Remember to increment the pointer */
return ret;
}

@ -19,12 +19,12 @@ void int_to_ascii(int n, char str[]) {
}
void hex_to_ascii(int n, char str[]) {
append(str, '0');
append(str, 'x');
char zeros = 0;
int32_t tmp;
int i;
append(str, '0');
append(str, 'x');
for (i = 28; i > 0; i -= 4) {
tmp = (n >> i) & 0xF;
if (tmp == 0 && zeros == 0) continue;

Loading…
Cancel
Save