diff --git a/23-fixes/README.md b/23-fixes/README.md index c27f74d..2f2f477 100644 --- a/23-fixes/README.md +++ b/23-fixes/README.md @@ -16,13 +16,9 @@ We add `-ffreestanding` when compiling `.o` files, which includes `kernel_entry Before, we disabled libgcc (not libc) through the use of `-nostdlib` and we didn't re-enable it for linking. Since this is tricky, we'll delete `-nostdlib` +`-nostdinc` was also pased to gcc, but we will need it for step 3. -2. Not setting a stack ----------------------- - - - -3. kernel.c `main()` function +2. kernel.c `main()` function ----------------------------- Modify `kernel/kernel.c` and change `main()` to `kernel_main()` since gcc recognizes "main" as @@ -33,8 +29,16 @@ Change `boot/kernel_entry.asm` to point to the new name accordingly. To fix the `i386-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000` warning message, add a `global _start;` and define the `_start:` label in `boot/kernel_entry.asm`. -4. Reinvented datatypes + +3. Reinvented datatypes ----------------------- + +It looks like it was a bad idea to define non-standard data types like `u32` and such, since +C99 introduces standard fixed-width data types like `uint32_t` + +We need to include `` which works even in `-ffreestanding` (but requires stdlibs) +and use those data types instead of our own, then delete them on `type.h` + to provide size\_t diff --git a/23-fixes/cpu/idt.c b/23-fixes/cpu/idt.c index f904a00..ee08cca 100644 --- a/23-fixes/cpu/idt.c +++ b/23-fixes/cpu/idt.c @@ -1,6 +1,7 @@ #include "idt.h" +#include "type.h" -void set_idt_gate(int n, u32 handler) { +void set_idt_gate(int n, uint32_t handler) { idt[n].low_offset = low_16(handler); idt[n].sel = KERNEL_CS; idt[n].always0 = 0; @@ -9,7 +10,7 @@ void set_idt_gate(int n, u32 handler) { } void set_idt() { - idt_reg.base = (u32) &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)); diff --git a/23-fixes/cpu/idt.h b/23-fixes/cpu/idt.h index 7d47ebd..094a5db 100644 --- a/23-fixes/cpu/idt.h +++ b/23-fixes/cpu/idt.h @@ -1,30 +1,30 @@ #ifndef IDT_H #define IDT_H -#include "type.h" +#include /* Segment selectors */ #define KERNEL_CS 0x08 /* How every interrupt gate (handler) is defined */ typedef struct { - u16 low_offset; /* Lower 16 bits of handler function address */ - u16 sel; /* Kernel segment selector */ - u8 always0; + uint16_t low_offset; /* Lower 16 bits of handler function address */ + uint16_t sel; /* Kernel segment selector */ + uint8_t always0; /* First byte * Bit 7: "Interrupt is present" * Bits 6-5: Privilege level of caller (0=kernel..3=user) * Bit 4: Set to 0 for interrupt gates * Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */ - u8 flags; - u16 high_offset; /* Higher 16 bits of handler function address */ + uint8_t flags; + uint16_t high_offset; /* Higher 16 bits of handler function address */ } __attribute__((packed)) idt_gate_t ; /* A pointer to the array of interrupt handlers. * Assembly instruction 'lidt' will read it */ typedef struct { - u16 limit; - u32 base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) idt_register_t; #define IDT_ENTRIES 256 @@ -33,7 +33,7 @@ idt_register_t idt_reg; /* Functions implemented in idt.c */ -void set_idt_gate(int n, u32 handler); +void set_idt_gate(int n, uint32_t handler); void set_idt(); #endif diff --git a/23-fixes/cpu/isr.c b/23-fixes/cpu/isr.c index c46a1d8..6e43fb2 100644 --- a/23-fixes/cpu/isr.c +++ b/23-fixes/cpu/isr.c @@ -11,38 +11,38 @@ isr_t interrupt_handlers[256]; /* Can't do this with a loop because we need the address * of the function names */ void isr_install() { - set_idt_gate(0, (u32)isr0); - set_idt_gate(1, (u32)isr1); - set_idt_gate(2, (u32)isr2); - set_idt_gate(3, (u32)isr3); - set_idt_gate(4, (u32)isr4); - set_idt_gate(5, (u32)isr5); - set_idt_gate(6, (u32)isr6); - set_idt_gate(7, (u32)isr7); - set_idt_gate(8, (u32)isr8); - set_idt_gate(9, (u32)isr9); - set_idt_gate(10, (u32)isr10); - set_idt_gate(11, (u32)isr11); - set_idt_gate(12, (u32)isr12); - set_idt_gate(13, (u32)isr13); - set_idt_gate(14, (u32)isr14); - set_idt_gate(15, (u32)isr15); - set_idt_gate(16, (u32)isr16); - set_idt_gate(17, (u32)isr17); - set_idt_gate(18, (u32)isr18); - set_idt_gate(19, (u32)isr19); - set_idt_gate(20, (u32)isr20); - set_idt_gate(21, (u32)isr21); - set_idt_gate(22, (u32)isr22); - set_idt_gate(23, (u32)isr23); - set_idt_gate(24, (u32)isr24); - set_idt_gate(25, (u32)isr25); - set_idt_gate(26, (u32)isr26); - set_idt_gate(27, (u32)isr27); - set_idt_gate(28, (u32)isr28); - set_idt_gate(29, (u32)isr29); - set_idt_gate(30, (u32)isr30); - set_idt_gate(31, (u32)isr31); + set_idt_gate(0, (uint32_t)isr0); + set_idt_gate(1, (uint32_t)isr1); + set_idt_gate(2, (uint32_t)isr2); + set_idt_gate(3, (uint32_t)isr3); + set_idt_gate(4, (uint32_t)isr4); + set_idt_gate(5, (uint32_t)isr5); + set_idt_gate(6, (uint32_t)isr6); + set_idt_gate(7, (uint32_t)isr7); + set_idt_gate(8, (uint32_t)isr8); + set_idt_gate(9, (uint32_t)isr9); + set_idt_gate(10, (uint32_t)isr10); + set_idt_gate(11, (uint32_t)isr11); + set_idt_gate(12, (uint32_t)isr12); + set_idt_gate(13, (uint32_t)isr13); + set_idt_gate(14, (uint32_t)isr14); + set_idt_gate(15, (uint32_t)isr15); + set_idt_gate(16, (uint32_t)isr16); + set_idt_gate(17, (uint32_t)isr17); + set_idt_gate(18, (uint32_t)isr18); + set_idt_gate(19, (uint32_t)isr19); + set_idt_gate(20, (uint32_t)isr20); + set_idt_gate(21, (uint32_t)isr21); + set_idt_gate(22, (uint32_t)isr22); + set_idt_gate(23, (uint32_t)isr23); + set_idt_gate(24, (uint32_t)isr24); + set_idt_gate(25, (uint32_t)isr25); + set_idt_gate(26, (uint32_t)isr26); + set_idt_gate(27, (uint32_t)isr27); + set_idt_gate(28, (uint32_t)isr28); + set_idt_gate(29, (uint32_t)isr29); + set_idt_gate(30, (uint32_t)isr30); + set_idt_gate(31, (uint32_t)isr31); // Remap the PIC port_byte_out(0x20, 0x11); @@ -57,22 +57,22 @@ void isr_install() { port_byte_out(0xA1, 0x0); // Install the IRQs - set_idt_gate(32, (u32)irq0); - set_idt_gate(33, (u32)irq1); - set_idt_gate(34, (u32)irq2); - set_idt_gate(35, (u32)irq3); - set_idt_gate(36, (u32)irq4); - set_idt_gate(37, (u32)irq5); - set_idt_gate(38, (u32)irq6); - set_idt_gate(39, (u32)irq7); - set_idt_gate(40, (u32)irq8); - set_idt_gate(41, (u32)irq9); - set_idt_gate(42, (u32)irq10); - set_idt_gate(43, (u32)irq11); - set_idt_gate(44, (u32)irq12); - set_idt_gate(45, (u32)irq13); - set_idt_gate(46, (u32)irq14); - set_idt_gate(47, (u32)irq15); + set_idt_gate(32, (uint32_t)irq0); + set_idt_gate(33, (uint32_t)irq1); + set_idt_gate(34, (uint32_t)irq2); + set_idt_gate(35, (uint32_t)irq3); + set_idt_gate(36, (uint32_t)irq4); + set_idt_gate(37, (uint32_t)irq5); + set_idt_gate(38, (uint32_t)irq6); + set_idt_gate(39, (uint32_t)irq7); + set_idt_gate(40, (uint32_t)irq8); + set_idt_gate(41, (uint32_t)irq9); + set_idt_gate(42, (uint32_t)irq10); + set_idt_gate(43, (uint32_t)irq11); + set_idt_gate(44, (uint32_t)irq12); + set_idt_gate(45, (uint32_t)irq13); + set_idt_gate(46, (uint32_t)irq14); + set_idt_gate(47, (uint32_t)irq15); set_idt(); // Load with ASM } @@ -126,7 +126,7 @@ void isr_handler(registers_t r) { kprint("\n"); } -void register_interrupt_handler(u8 n, isr_t handler) { +void register_interrupt_handler(uint8_t n, isr_t handler) { interrupt_handlers[n] = handler; } diff --git a/23-fixes/cpu/isr.h b/23-fixes/cpu/isr.h index 2f7496d..6ef6789 100644 --- a/23-fixes/cpu/isr.h +++ b/23-fixes/cpu/isr.h @@ -1,7 +1,7 @@ #ifndef ISR_H #define ISR_H -#include "type.h" +#include /* ISRs reserved for CPU exceptions */ extern void isr0(); @@ -73,10 +73,10 @@ extern void irq15(); /* Struct which aggregates many registers */ typedef struct { - u32 ds; /* Data segment selector */ - u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ - u32 int_no, err_code; /* Interrupt number and error code (if applicable) */ - u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ + uint32_t ds; /* Data segment selector */ + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ + uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */ + uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ } registers_t; void isr_install(); @@ -84,6 +84,6 @@ void isr_handler(registers_t r); void irq_install(); typedef void (*isr_t)(registers_t); -void register_interrupt_handler(u8 n, isr_t handler); +void register_interrupt_handler(uint8_t n, isr_t handler); #endif diff --git a/23-fixes/cpu/ports.c b/23-fixes/cpu/ports.c index f015689..5dde2be 100644 --- a/23-fixes/cpu/ports.c +++ b/23-fixes/cpu/ports.c @@ -3,8 +3,8 @@ /** * Read a byte from the specified port */ -u8 port_byte_in (u16 port) { - u8 result; +uint8_t port_byte_in (uint16_t port) { + uint8_t result; /* Inline assembler syntax * !! Notice how the source and destination registers are switched from NASM !! * @@ -17,7 +17,7 @@ u8 port_byte_in (u16 port) { return result; } -void port_byte_out (u16 port, u8 data) { +void port_byte_out (uint16_t port, uint8_t data) { /* Notice how here both registers are mapped to C variables and * nothing is returned, thus, no equals '=' in the asm syntax * However we see a comma since there are two variables in the input area @@ -26,12 +26,12 @@ void port_byte_out (u16 port, u8 data) { __asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port)); } -u16 port_word_in (u16 port) { - u16 result; +uint16_t port_word_in (uint16_t port) { + uint16_t result; __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); return result; } -void port_word_out (u16 port, u16 data) { +void port_word_out (uint16_t port, uint16_t data) { __asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port)); } diff --git a/23-fixes/cpu/ports.h b/23-fixes/cpu/ports.h index c8c819d..f4d18ca 100644 --- a/23-fixes/cpu/ports.h +++ b/23-fixes/cpu/ports.h @@ -1,11 +1,11 @@ #ifndef PORTS_H #define PORTS_H -#include "../cpu/type.h" +#include -unsigned char port_byte_in (u16 port); -void port_byte_out (u16 port, u8 data); -unsigned short port_word_in (u16 port); -void port_word_out (u16 port, u16 data); +unsigned char port_byte_in (uint16_t port); +void port_byte_out (uint16_t port, uint8_t data); +unsigned short port_word_in (uint16_t port); +void port_word_out (uint16_t port, uint16_t data); #endif diff --git a/23-fixes/cpu/timer.c b/23-fixes/cpu/timer.c index 0be49db..2203463 100644 --- a/23-fixes/cpu/timer.c +++ b/23-fixes/cpu/timer.c @@ -3,21 +3,21 @@ #include "ports.h" #include "../libc/function.h" -u32 tick = 0; +uint32_t tick = 0; static void timer_callback(registers_t regs) { tick++; UNUSED(regs); } -void init_timer(u32 freq) { +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 */ - u32 divisor = 1193180 / freq; - u8 low = (u8)(divisor & 0xFF); - u8 high = (u8)( (divisor >> 8) & 0xFF); + uint32_t divisor = 1193180 / freq; + uint8_t low = (uint8_t)(divisor & 0xFF); + uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF); /* Send the command */ port_byte_out(0x43, 0x36); /* Command port */ port_byte_out(0x40, low); diff --git a/23-fixes/cpu/timer.h b/23-fixes/cpu/timer.h index a1445a5..4e00930 100644 --- a/23-fixes/cpu/timer.h +++ b/23-fixes/cpu/timer.h @@ -1,8 +1,8 @@ #ifndef TIMER_H #define TIMER_H -#include "type.h" +#include -void init_timer(u32 freq); +void init_timer(uint32_t freq); #endif diff --git a/23-fixes/cpu/type.h b/23-fixes/cpu/type.h index e2d230a..5ed31fe 100644 --- a/23-fixes/cpu/type.h +++ b/23-fixes/cpu/type.h @@ -1,16 +1,9 @@ #ifndef TYPE_H #define TYPE_H -/* Instead of using 'chars' to allocate non-character bytes, - * we will use these new type with no semantic meaning */ -typedef unsigned int u32; -typedef int s32; -typedef unsigned short u16; -typedef short s16; -typedef unsigned char u8; -typedef char s8; +#include -#define low_16(address) (u16)((address) & 0xFFFF) -#define high_16(address) (u16)(((address) >> 16) & 0xFFFF) +#define low_16(address) (uint16_t)((address) & 0xFFFF) +#define high_16(address) (uint16_t)(((address) >> 16) & 0xFFFF) #endif diff --git a/23-fixes/drivers/keyboard.c b/23-fixes/drivers/keyboard.c index 6f40ac6..31461f2 100644 --- a/23-fixes/drivers/keyboard.c +++ b/23-fixes/drivers/keyboard.c @@ -5,6 +5,7 @@ #include "../libc/string.h" #include "../libc/function.h" #include "../kernel/kernel.h" +#include #define BACKSPACE 0x0E #define ENTER 0x1C @@ -26,7 +27,7 @@ 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 */ - u8 scancode = port_byte_in(0x60); + uint8_t scancode = port_byte_in(0x60); if (scancode > SC_MAX) return; if (scancode == BACKSPACE) { diff --git a/23-fixes/drivers/keyboard.h b/23-fixes/drivers/keyboard.h index a371b34..7726a3c 100644 --- a/23-fixes/drivers/keyboard.h +++ b/23-fixes/drivers/keyboard.h @@ -1,3 +1 @@ -#include "../cpu/type.h" - void init_keyboard(); diff --git a/23-fixes/drivers/screen.c b/23-fixes/drivers/screen.c index e955688..1aed626 100644 --- a/23-fixes/drivers/screen.c +++ b/23-fixes/drivers/screen.c @@ -1,6 +1,7 @@ #include "screen.h" #include "../cpu/ports.h" #include "../libc/mem.h" +#include /* Declaration of private functions */ int get_cursor_offset(); @@ -65,7 +66,7 @@ void kprint_backspace() { * Sets the video cursor to the returned offset */ int print_char(char c, int col, int row, char attr) { - u8 *vidmem = (u8*) VIDEO_ADDRESS; + uint8_t *vidmem = (uint8_t*) VIDEO_ADDRESS; if (!attr) attr = WHITE_ON_BLACK; /* Error control: print a red 'E' if the coords aren't right */ @@ -95,12 +96,12 @@ int print_char(char c, int col, int row, char attr) { if (offset >= MAX_ROWS * MAX_COLS * 2) { int i; for (i = 1; i < MAX_ROWS; i++) - memory_copy((u8*)(get_offset(0, i) + VIDEO_ADDRESS), - (u8*)(get_offset(0, i-1) + VIDEO_ADDRESS), + 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) + (u8*) VIDEO_ADDRESS); + char *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; @@ -126,15 +127,15 @@ void set_cursor_offset(int offset) { /* Similar to get_cursor_offset, but instead of reading we write data */ offset /= 2; port_byte_out(REG_SCREEN_CTRL, 14); - port_byte_out(REG_SCREEN_DATA, (u8)(offset >> 8)); + port_byte_out(REG_SCREEN_DATA, (uint8_t)(offset >> 8)); port_byte_out(REG_SCREEN_CTRL, 15); - port_byte_out(REG_SCREEN_DATA, (u8)(offset & 0xff)); + port_byte_out(REG_SCREEN_DATA, (uint8_t)(offset & 0xff)); } void clear_screen() { int screen_size = MAX_COLS * MAX_ROWS; int i; - u8 *screen = (u8*) VIDEO_ADDRESS; + uint8_t *screen = (uint8_t*) VIDEO_ADDRESS; for (i = 0; i < screen_size; i++) { screen[i*2] = ' '; diff --git a/23-fixes/drivers/screen.h b/23-fixes/drivers/screen.h index 4cba7bb..17313c6 100644 --- a/23-fixes/drivers/screen.h +++ b/23-fixes/drivers/screen.h @@ -1,8 +1,6 @@ #ifndef SCREEN_H #define SCREEN_H -#include "../cpu/type.h" - #define VIDEO_ADDRESS 0xb8000 #define MAX_ROWS 25 #define MAX_COLS 80 diff --git a/23-fixes/kernel/kernel.c b/23-fixes/kernel/kernel.c index 064b87a..9d44cd2 100644 --- a/23-fixes/kernel/kernel.c +++ b/23-fixes/kernel/kernel.c @@ -3,6 +3,7 @@ #include "kernel.h" #include "../libc/string.h" #include "../libc/mem.h" +#include void kernel_main() { isr_install(); @@ -18,8 +19,8 @@ void user_input(char *input) { asm volatile("hlt"); } else if (strcmp(input, "PAGE") == 0) { /* Lesson 22: Code to test kmalloc, the rest is unchanged */ - u32 phys_addr; - u32 page = kmalloc(1000, 1, &phys_addr); + uint32_t phys_addr; + uint32_t page = kmalloc(1000, 1, &phys_addr); char page_str[16] = ""; hex_to_ascii(page, page_str); char phys_str[16] = ""; diff --git a/23-fixes/libc/mem.c b/23-fixes/libc/mem.c index 90f5f70..86dc869 100644 --- a/23-fixes/libc/mem.c +++ b/23-fixes/libc/mem.c @@ -1,24 +1,24 @@ #include "mem.h" -void memory_copy(u8 *source, u8 *dest, int nbytes) { +void memory_copy(uint8_t *source, uint8_t *dest, int nbytes) { int i; for (i = 0; i < nbytes; i++) { *(dest + i) = *(source + i); } } -void memory_set(u8 *dest, u8 val, u32 len) { - u8 *temp = (u8 *)dest; +void memory_set(uint8_t *dest, uint8_t val, uint32_t len) { + uint8_t *temp = (uint8_t *)dest; for ( ; len != 0; len--) *temp++ = val; } /* This should be computed at link time, but a hardcoded * value is fine for now. Remember that our kernel starts * at 0x1000 as defined on the Makefile */ -u32 free_mem_addr = 0x10000; +uint32_t free_mem_addr = 0x10000; /* Implementation is just a pointer to some free memory which * keeps growing */ -u32 kmalloc(u32 size, int align, u32 *phys_addr) { +uint32_t kmalloc(uint32_t size, int align, uint32_t *phys_addr) { /* Pages are aligned to 4K, or 0x1000 */ if (align == 1 && (free_mem_addr & 0xFFFFF000)) { free_mem_addr &= 0xFFFFF000; @@ -27,7 +27,7 @@ u32 kmalloc(u32 size, int align, u32 *phys_addr) { /* Save also the physical address */ if (phys_addr) *phys_addr = free_mem_addr; - u32 ret = free_mem_addr; + uint32_t ret = free_mem_addr; free_mem_addr += size; /* Remember to increment the pointer */ return ret; } diff --git a/23-fixes/libc/mem.h b/23-fixes/libc/mem.h index 297ca6e..11e3c7e 100644 --- a/23-fixes/libc/mem.h +++ b/23-fixes/libc/mem.h @@ -1,12 +1,12 @@ #ifndef MEM_H #define MEM_H -#include "../cpu/type.h" +#include -void memory_copy(u8 *source, u8 *dest, int nbytes); -void memory_set(u8 *dest, u8 val, u32 len); +void memory_copy(uint8_t *source, uint8_t *dest, int nbytes); +void memory_set(uint8_t *dest, uint8_t val, uint32_t len); /* At this stage there is no 'free' implemented. */ -u32 kmalloc(u32 size, int align, u32 *phys_addr); +uint32_t kmalloc(uint32_t size, int align, uint32_t *phys_addr); #endif diff --git a/23-fixes/libc/string.c b/23-fixes/libc/string.c index 9b8a6d3..688f4a5 100644 --- a/23-fixes/libc/string.c +++ b/23-fixes/libc/string.c @@ -1,5 +1,5 @@ #include "string.h" -#include "../cpu/type.h" +#include /** * K&R implementation @@ -23,7 +23,7 @@ void hex_to_ascii(int n, char str[]) { append(str, 'x'); char zeros = 0; - s32 tmp; + int32_t tmp; int i; for (i = 28; i > 0; i -= 4) { tmp = (n >> i) & 0xF;