commit 3b623972a8fd45b2b3b28daafd72d754a852a805
parent 2fa7e11f715aa20c8015d54678a4c034269e485f
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 26 May 2021 19:02:24 +0300
writing printf
Diffstat:
19 files changed, 275 insertions(+), 436 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-(c) 2021-Present Christos Margiolis <christos@christosmarg.xyz>
+(c) 2021-Present Christos Margiolis <christos@margiolis.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
diff --git a/Makefile b/Makefile
@@ -1,11 +1,11 @@
TGTDIR = build
all:
- cd boot && make install clean && cd ..
+ cd boot && make install clean && cd -
run:
qemu-system-i386 -hdd ${TGTDIR}/os.bin
clean:
rm -rf ${TGTDIR}
- cd boot && make clean && cd ..
+ cd boot && make clean && cd -
diff --git a/boot/Makefile b/boot/Makefile
@@ -4,15 +4,14 @@ BINDIR = ../build
CC = cc
ASM = nasm
LD = ld
-CFLAGS = -g -m32 -ffreestanding -Wall -Wextra -std=c99 -O2
+CFLAGS = -g -m32 -nostdlib -ffreestanding -Wall -Wextra -std=c99 -O2
LDFLAGS = -Ttext 0x1000 --oformat binary
BOOTFILE = boot.asm
BOOT_BIN = boot.bin
KERNEL_BIN = kernel.bin
SRC = *.c *.asm
-OBJ = loader.o \
- kmain.o \
+OBJ = kmain.o \
string.o \
tty.o \
idt.o \
@@ -49,4 +48,4 @@ install: all
clean:
rm -rf *.bin *.o
-.PHONY: options all install clean
+.PHONY: all options install clean
diff --git a/boot/boot.asm b/boot/boot.asm
@@ -34,7 +34,7 @@ _start:
a20_test:
pusha
- mov ax, [0x7dfe] ; 0x7c00 + 510. The magic number is there.
+ mov ax, [0x7c00 + 510] ; The magic number is there.
mov dx, ax
; We'll try to advance 1MB in memory. If the end result hasn't wrapped up
@@ -243,7 +243,7 @@ gdt_ptr:
GDT_CODESEG equ gdt_kernel_code - gdt
GDT_DATASEG equ gdt_kernel_data - gdt
-; Go into Protected Mode and set PAE Paging and the GDT.
+; Set up the GDT and go into Protected Mode.
pm_enter:
cli ; Disable BIOS interrupts.
lgdt [gdt_ptr] ; Load the GDT.
diff --git a/boot/extern.h b/boot/extern.h
@@ -1,12 +1,21 @@
#ifndef _KERNEL_EXTERN_H_
#define _KERNEL_EXTERN_H_
-#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
+#include "stdarg.h"
#include "io.h"
#include "tty.h"
#include "string.h"
+#define BUFSIZ 1024
+
+#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
+#define sizeof_field(s, f) (sizeof(((t *)0)->f))
+
+int vsprintf(char *, const char *, va_list);
+int sprintf(char *, const char *, ...);
+int printf(const char *, ...);
+
#endif /* _KERNEL_EXTERN_H_ */
diff --git a/boot/idt.c b/boot/idt.c
@@ -2,14 +2,14 @@
#include "idt.h"
#include "port.h"
-#define N_INT 256 /* There are 256 interrupts in total. */
-#define KERN_CODESEG 0x08 /* Kernel code segment. */
+#define N_INT 256
+#define KERN_CODESEG 0x08
static void idt_set_gate(uint8_t, uint32_t);
static struct idt_gate idt[N_INT];
static void *isr[16] = {NULL};
-/* Exception messages for the first 32 ISRs. */
+/* Exception messages for the first 32 interrupts. */
static const char *except[] = {
"Division By Zero Exception",
"Debug Exception",
@@ -60,8 +60,8 @@ void
idt_init(void)
{
struct idt_reg {
- uint16_t limit; /* Points at IDT[0]. */
- uint32_t base; /* Points at the end of the IDT. */
+ uint16_t limit; /* IDT size in bytes. */
+ uint32_t base; /* Points at `idt[0]`. */
} __attribute__((packed)) idtr;
(void)memset(&idt, 0, sizeof(idt));
@@ -134,7 +134,6 @@ idt_init(void)
/* https://wiki.osdev.org/Interrupt_Descriptor_Table#Location_and_Size */
idtr.base = (uint32_t)&idt;
idtr.limit = N_INT * sizeof(struct idt_gate) - 1;
- /* Load the IDT */
__asm__ __volatile__ ("lidtl (%0)" : : "r" (&idtr));
}
@@ -147,7 +146,7 @@ int_handler(struct reg *r)
* We'll call the handler only if the interrupt number is > 32,
* which means that we're dealing with an IRQ and not an exception.
*/
- if (r->intno >= 32 && (handler = isr[r->intno - 32]) != 0)
+ if (r->intno >= 32 && (handler = isr[r->intno - 32]) != NULL)
handler(r);
/* Entries below index 32 in the IDT are exceptions, we need to hang. */
else if (r->intno < 32) {
diff --git a/boot/idt.h b/boot/idt.h
@@ -10,14 +10,14 @@ struct idt_gate {
uint16_t off_hi;
} __attribute__((packed));
-/* This will be populated by int_common_stub. */
+/* This will be populated by `int_common_stub` in `int.asm`. */
struct reg {
- /* Segment registers. Will be popped last. */
+ /* Will be popped last. */
uint32_t gs;
uint32_t fs;
uint32_t es;
uint32_t ds;
- /* General purpose registers. Pushed by `pusha`. */
+ /* Pushed by `pusha`. */
uint32_t edi;
uint32_t esi;
uint32_t ebp;
@@ -29,7 +29,7 @@ struct reg {
/* Interrupt info. Pushed by `push byte`. */
uint32_t intno;
uint32_t err;
- /* Pushed by the processor. */
+ /* Pushed by the CPU. */
uint32_t eip;
uint32_t cs;
uint32_t eflags;
@@ -37,63 +37,63 @@ struct reg {
uint32_t ss;
};
-/* `kernel_main` calls this. */
-extern void idt_init(void);
+/* Called by `kmain`. */
+void idt_init(void);
-/* Called by drivers */
-extern void int_handler(struct reg *);
-extern void int_add_handler(uint8_t, void (*)(struct reg *));
+/* Called by drivers. */
+void int_handler(struct reg *);
+void int_add_handler(uint8_t, void (*)(struct reg *));
/* The first 32 interrupts are reserved for exceptions. */
-extern void ex0(void);
-extern void ex1(void);
-extern void ex2(void);
-extern void ex3(void);
-extern void ex4(void);
-extern void ex5(void);
-extern void ex6(void);
-extern void ex7(void);
-extern void ex8(void);
-extern void ex9(void);
-extern void ex10(void);
-extern void ex11(void);
-extern void ex12(void);
-extern void ex13(void);
-extern void ex14(void);
-extern void ex15(void);
-extern void ex16(void);
-extern void ex17(void);
-extern void ex18(void);
-extern void ex19(void);
-extern void ex20(void);
-extern void ex21(void);
-extern void ex22(void);
-extern void ex23(void);
-extern void ex24(void);
-extern void ex25(void);
-extern void ex26(void);
-extern void ex27(void);
-extern void ex28(void);
-extern void ex29(void);
-extern void ex30(void);
-extern void ex31(void);
+void ex0(void);
+void ex1(void);
+void ex2(void);
+void ex3(void);
+void ex4(void);
+void ex5(void);
+void ex6(void);
+void ex7(void);
+void ex8(void);
+void ex9(void);
+void ex10(void);
+void ex11(void);
+void ex12(void);
+void ex13(void);
+void ex14(void);
+void ex15(void);
+void ex16(void);
+void ex17(void);
+void ex18(void);
+void ex19(void);
+void ex20(void);
+void ex21(void);
+void ex22(void);
+void ex23(void);
+void ex24(void);
+void ex25(void);
+void ex26(void);
+void ex27(void);
+void ex28(void);
+void ex29(void);
+void ex30(void);
+void ex31(void);
/* IRQs */
-extern void irq0(void);
-extern void irq1(void);
-extern void irq2(void);
-extern void irq3(void);
-extern void irq4(void);
-extern void irq5(void);
-extern void irq6(void);
-extern void irq7(void);
-extern void irq8(void);
-extern void irq9(void);
-extern void irq10(void);
-extern void irq11(void);
-extern void irq12(void);
-extern void irq13(void);
-extern void irq14(void);
-extern void irq15(void);
+void irq0(void);
+void irq1(void);
+void irq2(void);
+void irq3(void);
+void irq4(void);
+void irq5(void);
+void irq6(void);
+void irq7(void);
+void irq8(void);
+void irq9(void);
+void irq10(void);
+void irq11(void);
+void irq12(void);
+void irq13(void);
+void irq14(void);
+void irq15(void);
#endif /* _KERNEL_IDT_H_ */
diff --git a/boot/int.asm b/boot/int.asm
@@ -1,7 +1,7 @@
-; C functions defined in `idt.h`.
+; Defined in `idt.h`.
[extern int_handler]
-; ISRs
+; Exceptions
global ex0
global ex1
global ex2
@@ -53,339 +53,70 @@ global irq13
global irq14
global irq15
-; ================== EXCEPTIONS ======================
-
-; 0 - Division By Zero
-ex0:
- cli
- push byte 0
- push byte 0
- jmp int_common_stub
-
-; 1 - Debug
-ex1:
- cli
- push byte 0
- push byte 1
- jmp int_common_stub
-
-; 2 - Non Maskable Interrupt
-ex2:
- cli
- push byte 0
- push byte 2
- jmp int_common_stub
-
-; 3 - Breakpoint
-ex3:
- cli
- push byte 0
- push byte 3
- jmp int_common_stub
-
-; 4 - Into Detected Overflow
-ex4:
- cli
- push byte 0
- push byte 4
- jmp int_common_stub
-
-; 5 - Out of Bounds
-ex5:
- cli
- push byte 0
- push byte 5
- jmp int_common_stub
-
-; 6 - Invalid Opcode
-ex6:
- cli
- push byte 0
- push byte 6
- jmp int_common_stub
-
-; 7 - No Coprocessor
-ex7:
- cli
- push byte 0
- push byte 7
- jmp int_common_stub
-
-; 8 - Double Fault (with error code)
-ex8:
- cli
- push byte 8
- jmp int_common_stub
-
-; 9 - Coprocessor Segment Overrrun
-ex9:
- cli
- push byte 0
- push byte 9
- jmp int_common_stub
-
-; 10 - Bad TSS (with error code)
-ex10:
- cli
- push byte 10
- jmp int_common_stub
-
-; 11 - Segment Not Present (with error code)
-ex11:
- cli
- push byte 11
- jmp int_common_stub
-
-; 12 - Stack Fault (with error code)
-ex12:
- cli
- push byte 12
- jmp int_common_stub
-
-; 13 - General Protection Fault (with error code)
-ex13:
- cli
- push byte 13
- jmp int_common_stub
-
-; 14 - Page Fault (with error code)
-ex14:
- cli
- push byte 14
- jmp int_common_stub
-
-; 15 - Unkown Interrupt
-ex15:
- cli
- push byte 0
- push byte 15
- jmp int_common_stub
-
-; 16 - Coprocessor Fault
-ex16:
- cli
- push byte 0
- push byte 16
- jmp int_common_stub
-
-; 17 - Alignment Check (486+)
-ex17:
- cli
- push byte 0
- push byte 17
- jmp int_common_stub
-
-; 18 - Machine Check (Pentium/586+)
-ex18:
- cli
- push byte 0
- push byte 18
- jmp int_common_stub
-
-; 19 - Reserved
-ex19:
- cli
- push byte 0
- push byte 19
- jmp int_common_stub
-
-; 20 - Reserved
-ex20:
- cli
- push byte 0
- push byte 20
- jmp int_common_stub
-
-; 21 - Reserved
-ex21:
- cli
- push byte 0
- push byte 21
- jmp int_common_stub
-
-; 22 - Reserved
-ex22:
- cli
- push byte 0
- push byte 22
- jmp int_common_stub
-
-; 23 - Reserved
-ex23:
- cli
- push byte 0
- push byte 23
- jmp int_common_stub
-
-; 24 - Reserved
-ex24:
- cli
- push byte 0
- push byte 24
- jmp int_common_stub
-
-; 25 - Reserved
-ex25:
- cli
- push byte 0
- push byte 25
- jmp int_common_stub
-
-; 26 - Reserved
-ex26:
- cli
- push byte 0
- push byte 26
- jmp int_common_stub
-
-; 27 - Reserved
-ex27:
- cli
- push byte 0
- push byte 27
- jmp int_common_stub
-
-; 28 - Reserved
-ex28:
- cli
- push byte 0
- push byte 28
- jmp int_common_stub
-
-; 29 - Reserved
-ex29:
- cli
- push byte 0
- push byte 29
- jmp int_common_stub
-
-; 30 - Reserved
-ex30:
- cli
- push byte 0
- push byte 30
- jmp int_common_stub
-
-; 31 - Reserved
-ex31:
- cli
- push byte 0
- push byte 31
- jmp int_common_stub
-
-; ================== IRQ ======================
-
-; 32 - Programmable Interrupt Timer
-irq0:
- cli
- push byte 0
- push byte 32
- jmp int_common_stub
-
-; 33 - Keyboard
-irq1:
- cli
- push byte 0
- push byte 33
- jmp int_common_stub
-
-; 34 Cascade (used internally by the two PICs, never raised)
-irq2:
- cli
- push byte 0
- push byte 34
- jmp int_common_stub
-
-; 35 - COM2 (if enabled)
-irq3:
- cli
- push byte 0
- push byte 35
- jmp int_common_stub
-
-; 36 - COM1 (if enabled)
-irq4:
- cli
- push byte 0
- push byte 36
- jmp int_common_stub
-
-; 37 - LPT2 (if enabled)
-irq5:
- cli
- push byte 0
- push byte 37
- jmp int_common_stub
-
-; 38 - Floppy Disk
-irq6:
- cli
- push byte 0
- push byte 38
- jmp int_common_stub
-
-; 39 - LPT1
-irq7:
- cli
- push byte 0
- push byte 39
- jmp int_common_stub
-
-; 40 - CMOS real-time clock (if enabled)
-irq8:
- cli
- push byte 0
- push byte 40
- jmp int_common_stub
-
-; 41 - Peripherals / Legacy SCSI / NIC
-irq9:
- cli
- push byte 0
- push byte 41
- jmp int_common_stub
-
-; 42 - Peripherals / SCSI / NIC
-irq10:
- cli
- push byte 0
- push byte 42
- jmp int_common_stub
-
-; 43 - Peripherals / SCSI / NIC
-irq11:
- cli
- push byte 0
- push byte 43
- jmp int_common_stub
-
-; 44 - PS2 Mouse
-irq12:
- cli
- push byte 0
- push byte 44
- jmp int_common_stub
-
-; 45 - FPU / Coprocessor / Inter-processor
-irq13:
- cli
- push byte 0
- push byte 45
- jmp int_common_stub
-
-; 46 - Primary ATA Hard Disk
-irq14:
- cli
- push byte 0
- push byte 46
- jmp int_common_stub
-
-; 47 - Secondary ATA Hard Disk
-irq15:
- cli
- push byte 0
- push byte 47
- jmp int_common_stub
+%macro intdef_noerr 1
+ cli
+ push byte 0
+ push byte %1
+ jmp int_common_stub
+%endmacro
+
+%macro intdef_err 1
+ cli
+ push byte 0
+ push byte %1
+ jmp int_common_stub
+%endmacro
+
+; Exceptions
+ex0: intdef_noerr 0 ; Division By Zero
+ex1: intdef_noerr 1 ; Debug
+ex2: intdef_noerr 2 ; Non Maskable Interrupt
+ex3: intdef_noerr 3 ; Breakpoint
+ex4: intdef_noerr 4 ; Into Detected Overflow
+ex5: intdef_noerr 5 ; Out of Bounds
+ex6: intdef_noerr 6 ; Invalid Opcode
+ex7: intdef_noerr 7 ; No Coprocessor
+ex8: intdef_err 8 ; Double Fault (with error code)
+ex9: intdef_noerr 9 ; Coprocessor Segment Overrrun
+ex10: intdef_err 10 ; Bad TSS (with error code)
+ex11: intdef_err 11 ; Segment Not Present (with error code)
+ex12: intdef_err 12 ; Stack Fault (with error code)
+ex13: intdef_err 13 ; General Protection Fault (with error code)
+ex14: intdef_err 14 ; Page Fault (with error code)
+ex15: intdef_noerr 15 ; Unkown Interrupt
+ex16: intdef_noerr 16 ; Coprocessor Fault
+ex17: intdef_noerr 17 ; Alignment Check (486+)
+ex18: intdef_noerr 18 ; Machine Check (Pentium/586+)
+ex19: intdef_noerr 19 ; Reserved
+ex20: intdef_noerr 20 ; Reserved
+ex21: intdef_noerr 21 ; Reserved
+ex22: intdef_noerr 22 ; Reserved
+ex23: intdef_noerr 23 ; Reserved
+ex24: intdef_noerr 24 ; Reserved
+ex25: intdef_noerr 25 ; Reserved
+ex26: intdef_noerr 26 ; Reserved
+ex27: intdef_noerr 27 ; Reserved
+ex28: intdef_noerr 28 ; Reserved
+ex29: intdef_noerr 29 ; Reserved
+ex30: intdef_noerr 30 ; Reserved
+ex31: intdef_noerr 31 ; Reserved
+; IRQs
+irq0: intdef_noerr 32 ; Programmable Interrupt Timer
+irq1: intdef_noerr 33 ; Keyboard
+irq2: intdef_noerr 34 ; Cascade (used internally by the two PICs, never raised)
+irq3: intdef_noerr 35 ; COM2 (if enabled)
+irq4: intdef_noerr 36 ; COM1 (if enabled)
+irq5: intdef_noerr 37 ; LPT2 (if enabled)
+irq6: intdef_noerr 38 ; Floppy Disk
+irq7: intdef_noerr 39 ; LPT1
+irq8: intdef_noerr 40 ; CMOS real-time clock (if enabled)
+irq9: intdef_noerr 41 ; Peripherals / Legacy SCSI / NIC
+irq10: intdef_noerr 42 ; Peripherals / SCSI / NIC
+irq11: intdef_noerr 43 ; Peripherals / SCSI / NIC
+irq12: intdef_noerr 44 ; PS2 Mouse
+irq13: intdef_noerr 45 ; FPU / Coprocessor / Inter-processor
+irq14: intdef_noerr 46 ; Primary ATA Hard Disk
+irq15: intdef_noerr 47 ; Secondary ATA Hard Disk
; Save the processor state, call the C interrupt handler and restore the
; stack frame.
diff --git a/boot/kbd.c b/boot/kbd.c
@@ -54,10 +54,6 @@ kbd_callback(struct reg *r)
(void)r;
}
-/*
- * Send `kbd_callback` to the `irq_routines` array to be called
- * for IRQ 1.
- */
void
kbd_init(void)
{
diff --git a/boot/kbd.h b/boot/kbd.h
@@ -3,6 +3,6 @@
#include "extern.h"
-extern void kbd_init(void);
+void kbd_init(void);
#endif /* _KERNEL_KBD_H_ */
diff --git a/boot/kmain.c b/boot/kmain.c
@@ -10,7 +10,7 @@ kmain(void)
idt_init();
timer_init(50);
kbd_init();
- /* Enable interrupts so that the handlers can work now. */
__asm__ __volatile__ ("sti");
- __asm__ __volatile__ ("hlt");
+
+ for (;;);
}
diff --git a/boot/loader.asm b/boot/loader.asm
@@ -1,6 +0,0 @@
-[bits 32]
-[extern kmain]
-
-_start:
- call kmain
- jmp $
diff --git a/boot/printf.c b/boot/printf.c
@@ -0,0 +1,88 @@
+#include "extern.h"
+
+static char *
+itoa(int n, char *buf, int base)
+{
+ (void)n;
+ (void)base;
+
+ return buf;
+}
+
+int
+vsprintf(char *buf, const char *fmt, va_list args)
+{
+ char *str, *s;
+ int base, i, n;
+
+ for (str = buf; *fmt != '\0'; fmt++) {
+ base = 10;
+ if (*fmt != '%') {
+ *str++ = *fmt;
+ continue;
+ }
+ if (*fmt == '%') {
+ switch (*(++fmt)) {
+ case 'c':
+ *str++ = (unsigned char)va_arg(args, int);
+ continue;
+ case 's':
+ s = va_arg(args, char *);
+ n = strlen(s);
+ for (i = 0; i < n; i++)
+ *str++ = *s++;
+ continue;
+ case 'p':
+ continue;
+ case 'd': /* FALLTHROUGH */
+ case 'i':
+ n = va_arg(args, int);
+ break;
+ case 'u':
+ n = va_arg(args, unsigned int);
+ break;
+ case 'o':
+ base = 8;
+ break;
+ case 'X':
+ base = 16;
+ break;
+ case '%':
+ *str++ = '%';
+ continue;
+ }
+ str = itoa(n, str, base);
+ }
+ }
+ *str = '\0';
+
+ return str - buf;
+}
+
+int
+sprintf(char *buf, const char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(buf, fmt, args);
+ va_end(args);
+
+ return n;
+}
+
+int
+printf(const char *fmt, ...)
+{
+ char buf[BUFSIZ];
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(buf, fmt, args);
+ va_end(args);
+ tty_write(buf);
+
+ return n;
+}
diff --git a/boot/stdarg.h b/boot/stdarg.h
@@ -0,0 +1,14 @@
+#ifndef _KERNEL_STDARG_H
+#define _KERNEL_STDARG_H
+
+#ifndef _VA_LIST_DECLARED
+#define _VA_LIST_DECLARED
+typedef __va_list va_list;
+#endif /* _VA_LIST_DECLARED */
+
+#define va_start(ap, last) __builtin_va_start((ap), (last))
+#define va_arg(ap, type) __builtin_va_arg((ap), type)
+#define va_copy(dest, src) __builtin_va_copy((dest), (src))
+#define va_end(ap) __builtin_va_end(ap)
+
+#endif /* _KERNEL_STDARG_H */
diff --git a/boot/string.c b/boot/string.c
@@ -8,7 +8,6 @@ memset(void *dst, int v, size_t len)
dst0 = dst;
while (len--)
*dst0++ = v;
-
return dst;
}
@@ -23,7 +22,6 @@ memcpy(void *dst, const void *src, size_t len)
while (len--)
*dst0++ = *src0++;
-
return dst;
}
diff --git a/boot/string.h b/boot/string.h
@@ -3,9 +3,9 @@
#include <stddef.h>
-extern void *memset(void *, int, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern size_t strlen(const char *);
-extern int strcmp(const char *, const char *);
+void *memset(void *, int, size_t);
+void *memcpy(void *, const void *, size_t);
+size_t strlen(const char *);
+int strcmp(const char *, const char *);
#endif /* _KERNEL_STRING_H_ */
diff --git a/boot/timer.h b/boot/timer.h
@@ -1,6 +1,6 @@
#ifndef _KERNEL_TIMER_H_
#define _KERNEL_TIMER_H_
-extern void timer_init(uint32_t);
+void timer_init(uint32_t);
#endif /* _KERNEL_TIMER_H_ */
diff --git a/boot/tty.h b/boot/tty.h
@@ -36,12 +36,12 @@ enum vga_color {
VGA_WHITE,
};
-extern void tty_clear(void);
-extern void tty_putc(char);
-extern void tty_write(const char *);
-extern void tty_curs_enable(uint8_t, uint8_t);
-extern void tty_curs_disable(void);
-extern void tty_curs_setpos(int, int);
-extern uint16_t tty_curs_getpos(void);
+void tty_clear(void);
+void tty_putc(char);
+void tty_write(const char *);
+void tty_curs_enable(uint8_t, uint8_t);
+void tty_curs_disable(void);
+void tty_curs_setpos(int, int);
+uint16_t tty_curs_getpos(void);
#endif /* _KERNEL_TTY_H_ */
diff --git a/hier b/hier
@@ -0,0 +1,11 @@
+/bin/
+ boot/
+/dev/
+/sys/
+ include/
+ dev/
+ kernel/
+ sys/
+ lib/
+ src/
+/usr