From 7eb87bf3f3fa6226657a7106eb255cbfa97758d2 Mon Sep 17 00:00:00 2001 From: Miguel Date: Mon, 3 Sep 2018 15:18:16 +0200 Subject: big renaming --- Makefile | 1 + asm/asm_int.h | 40 ++++++++++++ asm/asm_int.s | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ asm/asm_pic.asm | 84 ++++++++++++++++++++++++ asm/asm_pic.h | 1 + asm/asm_pit.h | 25 ++++++++ asm/asm_pit.s | 40 ++++++++++++ asm/asm_start.h | 34 ++++++++++ asm/asm_start.s | 87 +++++++++++++++++++++++++ asm/asm_task.h | 1 + asm/asm_task.s | 114 +++++++++++++++++++++++++++++++++ asm/asm_usermode.h | 8 +++ asm/asm_usermode.s | 38 +++++++++++ asm/asm_x86.h | 100 +++++++++++++++++++++++++++++ asm/asm_x86.s | 134 ++++++++++++++++++++++++++++++++++++++ asm/int.h | 40 ------------ asm/int.s | 174 -------------------------------------------------- asm/pic.asm | 84 ------------------------ asm/pic.h | 1 - asm/pit.h | 25 -------- asm/pit.s | 40 ------------ asm/start.h | 34 ---------- asm/start.s | 87 ------------------------- asm/task.h | 1 - asm/task.s | 114 --------------------------------- asm/usermode.h | 8 --- asm/usermode.s | 38 ----------- asm/x86.h | 100 ----------------------------- asm/x86.s | 123 ----------------------------------- driver/keyboard.c | 2 +- driver/mouse.c | 2 +- driver/pci.c | 2 +- driver/serial.c | 2 +- driver/timer.c | 2 +- kernel/interrupts.c | 6 +- kernel/mp.c | 2 +- kernel/scheduler.c | 2 +- kernel/smp.c | 2 +- kernel/spinlock.c | 6 +- kernel/spinlock.h | 6 ++ kernel/vmem.c | 2 +- kernel/vmem.h | 2 +- linker.ld | 2 +- userspace/foolshell.c | 22 ++++--- 44 files changed, 916 insertions(+), 896 deletions(-) create mode 100644 asm/asm_int.h create mode 100644 asm/asm_int.s create mode 100644 asm/asm_pic.asm create mode 100644 asm/asm_pic.h create mode 100644 asm/asm_pit.h create mode 100644 asm/asm_pit.s create mode 100644 asm/asm_start.h create mode 100644 asm/asm_start.s create mode 100644 asm/asm_task.h create mode 100644 asm/asm_task.s create mode 100644 asm/asm_usermode.h create mode 100644 asm/asm_usermode.s create mode 100644 asm/asm_x86.h create mode 100644 asm/asm_x86.s delete mode 100644 asm/int.h delete mode 100644 asm/int.s delete mode 100644 asm/pic.asm delete mode 100644 asm/pic.h delete mode 100644 asm/pit.h delete mode 100644 asm/pit.s delete mode 100644 asm/start.h delete mode 100644 asm/start.s delete mode 100644 asm/task.h delete mode 100644 asm/task.s delete mode 100644 asm/usermode.h delete mode 100644 asm/usermode.s delete mode 100644 asm/x86.h delete mode 100644 asm/x86.s diff --git a/Makefile b/Makefile index d450745..42723ae 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ CFLAGS+=-nostdlib CFLAGS+=-O0 CFLAGS+=-I. CFLAGS+=-I/home/miguel/temp/foolos/usr/i686-foolos/include/ +CFLAGS+=-I./asm CFLAGS+=-gstabs #CFLAGS+=-fstack-protector-all diff --git a/asm/asm_int.h b/asm/asm_int.h new file mode 100644 index 0000000..4133fbf --- /dev/null +++ b/asm/asm_int.h @@ -0,0 +1,40 @@ +void int0(); +void int1(); +void int2(); +void int3(); +void int4(); +void int5(); +void int6(); +void int7(); +void int8(); +void int9(); +void int10(); +void int11(); +void int12(); +void int13(); +void int14(); +void int15(); + +void int128(); // syscalls +void int129(); // scheduler +void int255(); // unhandled + +void exc0(); +void exc1(); +void exc2(); +void exc3(); +void exc4(); +void exc5(); +void exc6(); +void exc7(); +void exc8(); +void exc9(); +void exc10(); +void exc11(); +void exc12(); +void exc13(); +void exc14(); +void exc15(); +void exc16(); +void exc17(); +void exc18(); diff --git a/asm/asm_int.s b/asm/asm_int.s new file mode 100644 index 0000000..566b646 --- /dev/null +++ b/asm/asm_int.s @@ -0,0 +1,174 @@ +.global int0 +.global int1 +.global int2 +.global int3 +.global int4 +.global int5 +.global int6 +.global int7 + +.global int8 +.global int9 +.global int10 +.global int11 +.global int12 +.global int13 +.global int14 +.global int15 + +.global int128 +.global int129 +.global int255 + +.global exc0 +.global exc1 +.global exc2 +.global exc3 +.global exc4 +.global exc5 +.global exc6 +.global exc7 +.global exc8 +.global exc9 +.global exc10 +.global exc11 +.global exc12 +.global exc13 +.global exc14 +.global exc15 +.global exc16 +.global exc17 +.global exc18 + +// nothing to ack +.macro ack0 +.endm + +// ack master +.macro ack1 + push %eax // persist + mov $0x20,%al + out %al,$0x20 + pop %eax // load original +.endm + +// ack master and servant +.macro ack2 + push %eax // persist + mov $0x20,%al + out %al,$0xa0 // slave + out %al,$0x20 // master + pop %eax // load original +.endm + +.macro intx ack num func + + /* + Once we arrived here the stack already contains 3x 32bit values, + which will be poped by 'iret' + + - eflags + - return code segment selector + - return instruction pointer + + There are two possiblities concerning our stack position: + + a) if the interrupt occured while kernel code was executed we are + on the same stack and have no clue about the stack alignment + + b) if the interrupt occured while user code was executed the + configured tss.esp0 was used, in this case we are at the start + of the esp0 stack. + */ + + \ack //acknowledge interrupt + //also remember that we will get new interrupts only + //after iret or reenabling themn explicitly! + + push $0x666 //make room for potential C functions 'return value'. + //we use eax already for esp (so we can context switch) + + push $0x0 //indicate if we want to return the value in ebx 0x0=NO + + pusha //Push all standard registers 8 regs x 4bytes/32bit + push %ds //Push data segment + push %es //etc... + push %fs + push %gs + + mov %esp,%eax // remember THIS stack position + + and $-16,%esp // padding to align stack on 16byte boundary before CALL + sub $8,%esp // ... + + push \num // pass in this interrupt number + push %eax // pass in original %esp (saved just few lines before) + call \func + mov %eax,%esp // use the %esp we got from c function + + pop %gs // pop everything back... + pop %fs // ... + pop %es + pop %ds + popa + + cmp $0x0,(%esp) + je skip\num + pop %ebx + pop %ebx + jmp ret\num + skip\num: + add $8,%esp // potentially set return value to eax to return to the caller + ret\num: + + iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack + +.endm + +.macro excx func + call \func + jmp . +.endm + +int0: intx ack1 $0 interrupt_handler +int1: intx ack1 $1 interrupt_handler +int2: intx ack1 $2 interrupt_handler +int3: intx ack1 $3 interrupt_handler +int4: intx ack1 $4 interrupt_handler +int5: intx ack1 $5 interrupt_handler +int6: intx ack1 $6 interrupt_handler +int7: intx ack1 $7 interrupt_handler + +int8: intx ack2 $8 interrupt_handler +int9: intx ack2 $9 interrupt_handler +int10: intx ack2 $10 interrupt_handler +int11: intx ack2 $11 interrupt_handler +int12: intx ack2 $12 interrupt_handler +int13: intx ack2 $13 interrupt_handler +int14: intx ack2 $14 interrupt_handler +int15: intx ack2 $15 interrupt_handler + +int128: intx ack0 $128 interrupt_handler +int129: intx ack0 $129 interrupt_handler + +int255: intx ack0 $255 interrupt_handler + +exc0: excx exception_handle_0 +exc1: excx exception_handle_1 +exc2: excx exception_handle_2 +exc3: excx exception_handle_3 +exc4: excx exception_handle_4 +exc5: excx exception_handle_5 +exc6: excx exception_handle_6 +exc7: excx exception_handle_7 +exc8: excx exception_handle_8 +exc9: excx exception_handle_9 +exc10: excx exception_handle_10 +exc11: excx exception_handle_11 +exc12: excx exception_handle_12 +exc13: excx exception_handle_13 +exc14: excx exception_handle_14 +exc15: excx exception_handle_15 +exc16: excx exception_handle_16 +exc17: excx exception_handle_17 +exc18: excx exception_handle_18 diff --git a/asm/asm_pic.asm b/asm/asm_pic.asm new file mode 100644 index 0000000..901f854 --- /dev/null +++ b/asm/asm_pic.asm @@ -0,0 +1,84 @@ +;************************************************************************ +; Map the 8259A PIC to use interrupts 32-47 within our interrupt table +;************************************************************************ + +[bits 32] + +global asm_pic_setup + +%define ICW_1 0x11 ; 00010001 binary. Enables initialization mode and we are sending ICW 4 + +%define PIC_1_CTRL 0x20 ; Primary PIC control register +%define PIC_2_CTRL 0xA0 ; Secondary PIC control register + +%define PIC_1_DATA 0x21 ; Primary PIC data register +%define PIC_2_DATA 0xA1 ; Secondary PIC data register + +%define IRQ_0 0x20 ; IRQs 0-7 mapped to use interrupts 0x20-0x27 +%define IRQ_8 0x28 ; IRQs 8-15 mapped to use interrupts 0x28-0x36 + +asm_pic_setup: + +; Send ICW 1 - Begin initialization ------------------------- + + ; Setup to initialize the primary PIC. Send ICW 1 + + mov al, ICW_1 + out PIC_1_CTRL, al + +; Send ICW 2 - Map IRQ base interrupt numbers --------------- + + ; Remember that we have 2 PICs. Because we are cascading with this second PIC, send ICW 1 to second PIC command register + + out PIC_2_CTRL, al + + ; send ICW 2 to primary PIC + + mov al, IRQ_0 + out PIC_1_DATA, al + + ; send ICW 2 to secondary controller + + mov al, IRQ_8 + out PIC_2_DATA, al + +; Send ICW 3 - Set the IR line to connect both PICs --------- + + ; Send ICW 3 to primary PIC + + mov al, 0x4 ; 0x04 => 0100, second bit (IR line 2) + out PIC_1_DATA, al ; write to data register of primary PIC + + ; Send ICW 3 to secondary PIC + + mov al, 0x2 ; 010=> IR line 2 + out PIC_2_DATA, al ; write to data register of secondary PIC + +; Send ICW 4 - Set x86 mode -------------------------------- + + mov al, 1 ; bit 0 enables 80x86 mode + + ; send ICW 4 to both primary and secondary PICs + + out PIC_1_DATA, al + out PIC_2_DATA, al + +; All done. Null out the data registers + + mov al, 0 + out PIC_1_DATA, al + out PIC_2_DATA, al + + ;mask +in al, 0x21 ; read in the primary PIC Interrupt Mask Register (IMR) +and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL +out 0x21, al ; write the value back into IMR + + +in al, 0xA1 ; read in the primary PIC Interrupt Mask Register (IMR) +and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL +out 0xA1, al ; write the value back into IMR + +ret + +;;;;;;;;;;;;;;;;;;;; diff --git a/asm/asm_pic.h b/asm/asm_pic.h new file mode 100644 index 0000000..0daea2a --- /dev/null +++ b/asm/asm_pic.h @@ -0,0 +1 @@ +void asm_pic_setup(); diff --git a/asm/asm_pit.h b/asm/asm_pit.h new file mode 100644 index 0000000..d020de1 --- /dev/null +++ b/asm/asm_pit.h @@ -0,0 +1,25 @@ +/** + * @file + * + * PIT - Programmable Interval Timer + * + * config out timer on channel 0 : mode 2 (sys timer) + * * http://en.wikipedia.org/wiki/Intel_8253#Control_Word_Register + * * http://www.brokenthorn.com/Resources/OSDevPit.html + * int0 will be triggered ~25 times a second. + * + * The most magic is performed in pit_interrupt_handler which calls + * the c function responsible for task switching doing vary bad ass + * magic... + */ + +#include + +/** Init PIT - 25 times a second*/ +void asm_pit_init(); + +/** install this interrupt handler to your Interrupt Vector Table */ +void asm_pit_tick(); + +/** get number of ticks */ +uint32_t asm_pit_get_ticks(); diff --git a/asm/asm_pit.s b/asm/asm_pit.s new file mode 100644 index 0000000..8e16d0b --- /dev/null +++ b/asm/asm_pit.s @@ -0,0 +1,40 @@ +.global asm_pit_init +.global asm_pit_tick +.global asm_pit_get_ticks + +ticks: +.int 0 + +asm_pit_get_ticks: + + mov (ticks),%eax + ret + +asm_pit_tick: + + push %eax // persist + + // INC TICK COUNTER + mov $ticks, %eax + incl (%eax) + + pop %eax // load original + + ret + +asm_pit_init: + + // configure ticking 25 times a second + // 1193180 / 25 = 47727.2 + mov $47727, %dx + + mov $0b00110100, %al + outb %al,$0x43 + + mov %dx,%ax + + out %al, $0x40 + xchg %ah,%al + out %al, $0x40 + + ret diff --git a/asm/asm_start.h b/asm/asm_start.h new file mode 100644 index 0000000..4b2db16 --- /dev/null +++ b/asm/asm_start.h @@ -0,0 +1,34 @@ +/** + * @file + * Defines the following sections/functions, some are linked at + * specific addresses in the final ELF kernel binary. + * This is specified in the _linker.ld_ file. + * + * TODO: THIS IS NOT TRUE ANYMORE (SINCE IT KILLED THE MEMORY IN BETWEEN PROABBLY) + * * 0x007000 .smp - entry point for application processors (16bit code) + * * 0x100000 .multiboot - the multiboot header + * + * * .text + * * .bootstrap_stack + * * _start() - main entry point for booting cpu, calls kernel_main(). + * + * The addresses for .smp and .multiboot are based on the assumption: + * * 0x00000500 - 0x00007BFF : guaranteed free to use + * * 0x00100000 - 0x00EFFFFF : free for use (if it exists) + * + * References + * ---------- + * * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format + * * http://wiki.osdev.org/Bare_Bones + */ + +/** This will be called by a multiboot compilant boot-loader (i.e. grub2). + * Calls kernel_main() passing through eax and ebx: + * * eax - magic number + * * ebx - multiboot structure + * */ +void _start(); + +/** 16-bit entry point for application processors */ +void _start_smp(); + diff --git a/asm/asm_start.s b/asm/asm_start.s new file mode 100644 index 0000000..ca99c20 --- /dev/null +++ b/asm/asm_start.s @@ -0,0 +1,87 @@ +.global _start +.global _start_smp +.global stack_top +.global stack_bottom + +# Fill Multiboot Haeder, init stack and call kernel_main passing two params: +# eax - magic number +# ebx - multiboot structure + +# Declare constants used for creating a multiboot header. +.set ALIGN, 1<<0 # align loaded modules on page boundaries +.set MEMINFO, 1<<1 # provide memory map +.set GFXINFO, 1<<2 # provide gfx info +.set FLAGS, ALIGN | MEMINFO | GFXINFO # this is the Multiboot 'flag' field +.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header +.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot + +# entry point for application processors we will copy this to 0x7000 later + +.section .smp +.code16 +_start_smp: +call smp_start # TODO: align later before going C + + +# Declare a header as in the Multiboot Standard. We put this into a special +# section so we can force the header to be in the start of the final program. +# You don't need to understand all these details as it is just magic values that +# is documented in the multiboot standard. The bootloader will search for this +# magic sequence and recognize us as a multiboot kernel. + +.section .multiboot +.code32 +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +.long 0 # we dont need this for ELF +.long 0 +.long 0 +.long 0 +.long 0 + +# we override this from grub anyway +.long 0 #gfx_stuff 0=enable! +.long 640 +.long 480 +.long 32 + +# Currently the stack pointer register (esp) points at anything and using it may +# cause massive harm. Instead, we'll provide our own stack. We will allocate +# room for a small temporary stack by creating a symbol at the bottom of it, +# then allocating 16384 bytes for it, and finally creating a symbol at the top. +.section .bootstrap_stack, "aw", @nobits +stack_bottom: +.skip 16384 # 16 KiB +stack_top: + +# The linker script specifies _start as the entry point to the kernel and the +# bootloader will jump to this position once the kernel has been loaded. It +# doesn't make sense to return from this function as the bootloader is gone. +.section .text + +_start: + + # To set up a stack, we simply set the esp register to point to the top of + # our stack (as it grows downwards). + movl $stack_top, %esp + + sub $8, %esp #to align on 16byte before calling C + push %ebx #pass address of the multiboot information data structure + push %eax #pass eax, so kernel can check for magic number + + call kernel_main + + # turn off interrupts and halt. + # this should never be reached + cli + hlt + +.Lhang: + jmp .Lhang + +# Set the size of the _start symbol to the current location '.' minus its start. +# This is useful when debugging or when you implement call tracing. +.size _start, . - _start diff --git a/asm/asm_task.h b/asm/asm_task.h new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/asm/asm_task.h @@ -0,0 +1 @@ +/* empty */ diff --git a/asm/asm_task.s b/asm/asm_task.s new file mode 100644 index 0000000..bf80025 --- /dev/null +++ b/asm/asm_task.s @@ -0,0 +1,114 @@ +.global task_pusha + +task_pusha: + + pushf + push $0x8 // code segment + push $userfunc + + push $0x666 + push $0x0 + + pusha + + push %ds + push %es + push %fs + push %gs + + /* + + now stack looks like: + + param // esp+72 + returnaddy + + eflags + code segment + userfunc + + 0x666 + + eax // rest by popa + ecx + edx + ebx + esp + ebp + esi + edi + + ds + es + fs + gs + + */ + + mov 72(%esp),%eax // get address of alternative stack where we want to simulate the pusha happened + + mov (%esp),%ecx + mov %ecx,(%eax) + + mov 4(%esp),%ecx + mov %ecx,4(%eax) + + mov 8(%esp),%ecx + mov %ecx,8(%eax) + + mov 12(%esp),%ecx + mov %ecx,12(%eax) + + mov 16(%esp),%ecx + mov %ecx,16(%eax) + + mov 20(%esp),%ecx + mov %ecx,20(%eax) + + mov 24(%esp),%ecx + mov %ecx,24(%eax) + + mov 28(%esp),%ecx + mov %ecx,28(%eax) + + mov 32(%esp),%ecx + mov %ecx,32(%eax) + + mov 36(%esp),%ecx + mov %ecx,36(%eax) + + mov 40(%esp),%ecx + mov %ecx,40(%eax) + + mov 44(%esp),%ecx + mov %ecx,44(%eax) + + mov 48(%esp),%ecx + mov %ecx,48(%eax) + + mov 52(%esp),%ecx + mov %ecx,52(%eax) + + mov 56(%esp),%ecx + mov %ecx,56(%eax) + + mov 60(%esp),%ecx + mov %ecx,60(%eax) + + mov 64(%esp),%ecx + mov %ecx,64(%eax) + + pop %gs + pop %fs + pop %es + pop %ds + + popa + + pop %eax + pop %eax + pop %eax + pop %eax + pop %eax + + ret diff --git a/asm/asm_usermode.h b/asm/asm_usermode.h new file mode 100644 index 0000000..16597f2 --- /dev/null +++ b/asm/asm_usermode.h @@ -0,0 +1,8 @@ +/** + * @file + * Switch to User Mode and iret to function given by pointer + * provide the address of a void func() that will be called without + * any params via iret. + */ + +void asm_usermode(uint32_t func); diff --git a/asm/asm_usermode.s b/asm/asm_usermode.s new file mode 100644 index 0000000..71ecc1d --- /dev/null +++ b/asm/asm_usermode.s @@ -0,0 +1,38 @@ +.global asm_usermode + +asm_usermode: + + mov 0x4(%esp),%edx //get adress of passed : void func() + //to be called in ring 3 + + // 0x23 is user data segment (|2 low bits) + // 0x1b is user code segment (|2 low bits) + + // set segment registers + mov $0x23, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + // ss is handled by iret + + mov %esp, %eax + + pushl $0x23 // user data segment + pushl $0x8fff000-3*32 //%eax // current stack + pushf // + + // http://x86.renejeschke.de/html/file_module_x86_id_145.html + //mov $0x200, %eax + //push %eax // eflags image + pushl $0x1B // return code segment selector + push %edx // return instruction pointer + + iret + + jmp . // never to be reached + + + + diff --git a/asm/asm_x86.h b/asm/asm_x86.h new file mode 100644 index 0000000..529a6c2 --- /dev/null +++ b/asm/asm_x86.h @@ -0,0 +1,100 @@ +#ifndef FOOLOS_X86_H +#define FOOLOS_X86_H + +/** + * @file + * + * X86 32-bit Basics + * ================= + * + * **All the functions are very specific to the targeted x86 architecture.** + * + * This is the header of our basic **x86** function definitions. + * Most of the functions are implemented in assembler in the file _asm/x86.s_, + * however a few short helper functions are defined in this header itself: + * + * * x86_set_page_directory() + * * x86_paging_enable() + * * x86_paging_disable() + * + * + * Reading and Writing Ports + * ------------------------- + * + * The functions of the form x86_outX() and x86_inX(), where the X + * indicates the value size allow reading and writing ports. + * + * * x86_outb() / x86_inb() + * * x86_outw() / x86_inw() + * * x86_outl() / x86_inl() + * + * The sizes are: + * + * * b - byte (8 bit) + * * w - word (16 bit) + * * l - double word (32 bit) + * + * Remember, that the port address is always 32 bits wide. + * + * Dependencies + * ------------ + * + * All we need are uint32_t, uint16_t and uint8_t as provided by + * + * References + * ---------- + * * http://wiki.osdev.org/Interrupt_Service_Routines + * * https://wiki.osdev.org/CPU_Registers_x86 + * * ... + * + */ + +// we need uint32_t, uint16_t, uint8_t // +#include + +/** write byte to port */ +void x86_outb (uint32_t port, uint8_t data); + +/** read byte from port */ +uint8_t x86_inb (uint32_t port); + +/** write word to port */ +void x86_outw (uint32_t port, uint16_t data); + +/** read word from port */ +uint16_t x86_inw (uint32_t port); + +/** write double word to port */ +void x86_outl (uint32_t port, uint32_t data); + +/** read double word from port */ +uint32_t x86_inl (uint32_t port); + +/** disable interrupts */ +void x86_cli (); + +/** enable interrupts */ +void x86_sti (); + +/** xchg - this can be used for semaphors and simlar */ +uint8_t x86_xchg (uint32_t addr, uint32_t val); + +/** invlpg - invalidate translation lookaside buffer */ +void x86_invlpg(uint32_t addr); + +/** read value from control register specified by num */ +uint32_t x86_get_cr(uint8_t num); + +/** write given value to the control register specified by num */ +void x86_set_cr(uint8_t num, uint32_t value); + +/** Set the address of the page directory. This is required **before** enabling paging */ +static inline void x86_set_page_directory(uint32_t pdir_addr) {x86_set_cr(3,pdir_addr);} + +/** Enable paging */ +static inline void x86_paging_enable() {x86_set_cr(0,x86_get_cr(0)| 0x80000000);} + +/** Disable paging */ +static inline void x86_paging_disable() {x86_set_cr(0,x86_get_cr(0)&~0x80000000);} + +#endif diff --git a/asm/asm_x86.s b/asm/asm_x86.s new file mode 100644 index 0000000..35052b1 --- /dev/null +++ b/asm/asm_x86.s @@ -0,0 +1,134 @@ +// Basic low-level x86 32-bit calls // + +// reading and writing ports + +.global x86_outb // 8 bit out +.global x86_inb // 8 bit in +.global x86_outw // 16 bit out +.global x86_inw // 16 bit in +.global x86_outl // 32 bit out +.global x86_inl // 32 bit in + +// interrupts + +.global x86_cli // disable interrupts +.global x86_sti // enable interrupts + +// xchg +.global x86_xchg // exchange (for semaphors etc.) + +// invlpg +.global x86_invlpg // invalidate translation lookaside buffer (tlb) + +// control registers +.global x86_get_cr +.global x86_set_cr + +x86_outb: + mov 4(%esp), %edx + mov 8(%esp), %eax + outb %al,%dx + ret + +x86_inb: + mov 4(%esp), %edx + inb %dx,%al + ret + +x86_outw: + mov 4(%esp), %edx + mov 8(%esp), %eax + outw %ax,%dx + ret + +x86_inw: + mov 4(%esp), %edx + inw %dx,%ax + ret + +x86_outl: + mov 4(%esp), %edx + mov 8(%esp), %eax + outl %eax,%dx + ret + +x86_inl: + mov 4(%esp), %edx + inl %dx,%eax + ret + +x86_cli: + cli + ret + +x86_sti: + sti + ret + +x86_get_cr: + mov 4(%esp), %ecx + cmp $0,%ecx + je get_cr0 + cmp $2,%ecx + je get_cr2 + cmp $3,%ecx + je get_cr3 + cmp $4,%ecx + je get_cr4 + ret + +x86_set_cr: + mov 4(%esp), %ecx + mov 8(%esp), %eax + cmp $0,%ecx + je set_cr0 + cmp $2,%ecx + je set_cr2 + cmp $3,%ecx + je set_cr3 + cmp $4,%ecx + je set_cr4 + ret + +get_cr0: + mov %cr0,%eax + ret + +get_cr2: + mov %cr2,%eax + ret + +get_cr3: + mov %cr3,%eax + ret + +get_cr4: + mov %cr4,%eax + ret + +set_cr0: + mov %eax,%cr0 + ret + +set_cr2: + mov %eax,%cr2 + ret + +set_cr3: + mov %eax,%cr3 + ret + +set_cr4: + mov %eax,%cr4 + ret + +x86_xchg: + mov 8(%esp), %eax // addr + mov 4(%esp), %edx // value + xchg %edx, (%eax) //LOCK protocol impemented anyway + ret + +x86_invlpg: + mov 4(%esp), %eax // addr + invlpg (%eax) + ret diff --git a/asm/int.h b/asm/int.h deleted file mode 100644 index 4133fbf..0000000 --- a/asm/int.h +++ /dev/null @@ -1,40 +0,0 @@ -void int0(); -void int1(); -void int2(); -void int3(); -void int4(); -void int5(); -void int6(); -void int7(); -void int8(); -void int9(); -void int10(); -void int11(); -void int12(); -void int13(); -void int14(); -void int15(); - -void int128(); // syscalls -void int129(); // scheduler -void int255(); // unhandled - -void exc0(); -void exc1(); -void exc2(); -void exc3(); -void exc4(); -void exc5(); -void exc6(); -void exc7(); -void exc8(); -void exc9(); -void exc10(); -void exc11(); -void exc12(); -void exc13(); -void exc14(); -void exc15(); -void exc16(); -void exc17(); -void exc18(); diff --git a/asm/int.s b/asm/int.s deleted file mode 100644 index 566b646..0000000 --- a/asm/int.s +++ /dev/null @@ -1,174 +0,0 @@ -.global int0 -.global int1 -.global int2 -.global int3 -.global int4 -.global int5 -.global int6 -.global int7 - -.global int8 -.global int9 -.global int10 -.global int11 -.global int12 -.global int13 -.global int14 -.global int15 - -.global int128 -.global int129 -.global int255 - -.global exc0 -.global exc1 -.global exc2 -.global exc3 -.global exc4 -.global exc5 -.global exc6 -.global exc7 -.global exc8 -.global exc9 -.global exc10 -.global exc11 -.global exc12 -.global exc13 -.global exc14 -.global exc15 -.global exc16 -.global exc17 -.global exc18 - -// nothing to ack -.macro ack0 -.endm - -// ack master -.macro ack1 - push %eax // persist - mov $0x20,%al - out %al,$0x20 - pop %eax // load original -.endm - -// ack master and servant -.macro ack2 - push %eax // persist - mov $0x20,%al - out %al,$0xa0 // slave - out %al,$0x20 // master - pop %eax // load original -.endm - -.macro intx ack num func - - /* - Once we arrived here the stack already contains 3x 32bit values, - which will be poped by 'iret' - - - eflags - - return code segment selector - - return instruction pointer - - There are two possiblities concerning our stack position: - - a) if the interrupt occured while kernel code was executed we are - on the same stack and have no clue about the stack alignment - - b) if the interrupt occured while user code was executed the - configured tss.esp0 was used, in this case we are at the start - of the esp0 stack. - */ - - \ack //acknowledge interrupt - //also remember that we will get new interrupts only - //after iret or reenabling themn explicitly! - - push $0x666 //make room for potential C functions 'return value'. - //we use eax already for esp (so we can context switch) - - push $0x0 //indicate if we want to return the value in ebx 0x0=NO - - pusha //Push all standard registers 8 regs x 4bytes/32bit - push %ds //Push data segment - push %es //etc... - push %fs - push %gs - - mov %esp,%eax // remember THIS stack position - - and $-16,%esp // padding to align stack on 16byte boundary before CALL - sub $8,%esp // ... - - push \num // pass in this interrupt number - push %eax // pass in original %esp (saved just few lines before) - call \func - mov %eax,%esp // use the %esp we got from c function - - pop %gs // pop everything back... - pop %fs // ... - pop %es - pop %ds - popa - - cmp $0x0,(%esp) - je skip\num - pop %ebx - pop %ebx - jmp ret\num - skip\num: - add $8,%esp // potentially set return value to eax to return to the caller - ret\num: - - iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack - -.endm - -.macro excx func - call \func - jmp . -.endm - -int0: intx ack1 $0 interrupt_handler -int1: intx ack1 $1 interrupt_handler -int2: intx ack1 $2 interrupt_handler -int3: intx ack1 $3 interrupt_handler -int4: intx ack1 $4 interrupt_handler -int5: intx ack1 $5 interrupt_handler -int6: intx ack1 $6 interrupt_handler -int7: intx ack1 $7 interrupt_handler - -int8: intx ack2 $8 interrupt_handler -int9: intx ack2 $9 interrupt_handler -int10: intx ack2 $10 interrupt_handler -int11: intx ack2 $11 interrupt_handler -int12: intx ack2 $12 interrupt_handler -int13: intx ack2 $13 interrupt_handler -int14: intx ack2 $14 interrupt_handler -int15: intx ack2 $15 interrupt_handler - -int128: intx ack0 $128 interrupt_handler -int129: intx ack0 $129 interrupt_handler - -int255: intx ack0 $255 interrupt_handler - -exc0: excx exception_handle_0 -exc1: excx exception_handle_1 -exc2: excx exception_handle_2 -exc3: excx exception_handle_3 -exc4: excx exception_handle_4 -exc5: excx exception_handle_5 -exc6: excx exception_handle_6 -exc7: excx exception_handle_7 -exc8: excx exception_handle_8 -exc9: excx exception_handle_9 -exc10: excx exception_handle_10 -exc11: excx exception_handle_11 -exc12: excx exception_handle_12 -exc13: excx exception_handle_13 -exc14: excx exception_handle_14 -exc15: excx exception_handle_15 -exc16: excx exception_handle_16 -exc17: excx exception_handle_17 -exc18: excx exception_handle_18 diff --git a/asm/pic.asm b/asm/pic.asm deleted file mode 100644 index 901f854..0000000 --- a/asm/pic.asm +++ /dev/null @@ -1,84 +0,0 @@ -;************************************************************************ -; Map the 8259A PIC to use interrupts 32-47 within our interrupt table -;************************************************************************ - -[bits 32] - -global asm_pic_setup - -%define ICW_1 0x11 ; 00010001 binary. Enables initialization mode and we are sending ICW 4 - -%define PIC_1_CTRL 0x20 ; Primary PIC control register -%define PIC_2_CTRL 0xA0 ; Secondary PIC control register - -%define PIC_1_DATA 0x21 ; Primary PIC data register -%define PIC_2_DATA 0xA1 ; Secondary PIC data register - -%define IRQ_0 0x20 ; IRQs 0-7 mapped to use interrupts 0x20-0x27 -%define IRQ_8 0x28 ; IRQs 8-15 mapped to use interrupts 0x28-0x36 - -asm_pic_setup: - -; Send ICW 1 - Begin initialization ------------------------- - - ; Setup to initialize the primary PIC. Send ICW 1 - - mov al, ICW_1 - out PIC_1_CTRL, al - -; Send ICW 2 - Map IRQ base interrupt numbers --------------- - - ; Remember that we have 2 PICs. Because we are cascading with this second PIC, send ICW 1 to second PIC command register - - out PIC_2_CTRL, al - - ; send ICW 2 to primary PIC - - mov al, IRQ_0 - out PIC_1_DATA, al - - ; send ICW 2 to secondary controller - - mov al, IRQ_8 - out PIC_2_DATA, al - -; Send ICW 3 - Set the IR line to connect both PICs --------- - - ; Send ICW 3 to primary PIC - - mov al, 0x4 ; 0x04 => 0100, second bit (IR line 2) - out PIC_1_DATA, al ; write to data register of primary PIC - - ; Send ICW 3 to secondary PIC - - mov al, 0x2 ; 010=> IR line 2 - out PIC_2_DATA, al ; write to data register of secondary PIC - -; Send ICW 4 - Set x86 mode -------------------------------- - - mov al, 1 ; bit 0 enables 80x86 mode - - ; send ICW 4 to both primary and secondary PICs - - out PIC_1_DATA, al - out PIC_2_DATA, al - -; All done. Null out the data registers - - mov al, 0 - out PIC_1_DATA, al - out PIC_2_DATA, al - - ;mask -in al, 0x21 ; read in the primary PIC Interrupt Mask Register (IMR) -and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL -out 0x21, al ; write the value back into IMR - - -in al, 0xA1 ; read in the primary PIC Interrupt Mask Register (IMR) -and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL -out 0xA1, al ; write the value back into IMR - -ret - -;;;;;;;;;;;;;;;;;;;; diff --git a/asm/pic.h b/asm/pic.h deleted file mode 100644 index 0daea2a..0000000 --- a/asm/pic.h +++ /dev/null @@ -1 +0,0 @@ -void asm_pic_setup(); diff --git a/asm/pit.h b/asm/pit.h deleted file mode 100644 index d020de1..0000000 --- a/asm/pit.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @file - * - * PIT - Programmable Interval Timer - * - * config out timer on channel 0 : mode 2 (sys timer) - * * http://en.wikipedia.org/wiki/Intel_8253#Control_Word_Register - * * http://www.brokenthorn.com/Resources/OSDevPit.html - * int0 will be triggered ~25 times a second. - * - * The most magic is performed in pit_interrupt_handler which calls - * the c function responsible for task switching doing vary bad ass - * magic... - */ - -#include - -/** Init PIT - 25 times a second*/ -void asm_pit_init(); - -/** install this interrupt handler to your Interrupt Vector Table */ -void asm_pit_tick(); - -/** get number of ticks */ -uint32_t asm_pit_get_ticks(); diff --git a/asm/pit.s b/asm/pit.s deleted file mode 100644 index 8e16d0b..0000000 --- a/asm/pit.s +++ /dev/null @@ -1,40 +0,0 @@ -.global asm_pit_init -.global asm_pit_tick -.global asm_pit_get_ticks - -ticks: -.int 0 - -asm_pit_get_ticks: - - mov (ticks),%eax - ret - -asm_pit_tick: - - push %eax // persist - - // INC TICK COUNTER - mov $ticks, %eax - incl (%eax) - - pop %eax // load original - - ret - -asm_pit_init: - - // configure ticking 25 times a second - // 1193180 / 25 = 47727.2 - mov $47727, %dx - - mov $0b00110100, %al - outb %al,$0x43 - - mov %dx,%ax - - out %al, $0x40 - xchg %ah,%al - out %al, $0x40 - - ret diff --git a/asm/start.h b/asm/start.h deleted file mode 100644 index 4b2db16..0000000 --- a/asm/start.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file - * Defines the following sections/functions, some are linked at - * specific addresses in the final ELF kernel binary. - * This is specified in the _linker.ld_ file. - * - * TODO: THIS IS NOT TRUE ANYMORE (SINCE IT KILLED THE MEMORY IN BETWEEN PROABBLY) - * * 0x007000 .smp - entry point for application processors (16bit code) - * * 0x100000 .multiboot - the multiboot header - * - * * .text - * * .bootstrap_stack - * * _start() - main entry point for booting cpu, calls kernel_main(). - * - * The addresses for .smp and .multiboot are based on the assumption: - * * 0x00000500 - 0x00007BFF : guaranteed free to use - * * 0x00100000 - 0x00EFFFFF : free for use (if it exists) - * - * References - * ---------- - * * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format - * * http://wiki.osdev.org/Bare_Bones - */ - -/** This will be called by a multiboot compilant boot-loader (i.e. grub2). - * Calls kernel_main() passing through eax and ebx: - * * eax - magic number - * * ebx - multiboot structure - * */ -void _start(); - -/** 16-bit entry point for application processors */ -void _start_smp(); - diff --git a/asm/start.s b/asm/start.s deleted file mode 100644 index ca99c20..0000000 --- a/asm/start.s +++ /dev/null @@ -1,87 +0,0 @@ -.global _start -.global _start_smp -.global stack_top -.global stack_bottom - -# Fill Multiboot Haeder, init stack and call kernel_main passing two params: -# eax - magic number -# ebx - multiboot structure - -# Declare constants used for creating a multiboot header. -.set ALIGN, 1<<0 # align loaded modules on page boundaries -.set MEMINFO, 1<<1 # provide memory map -.set GFXINFO, 1<<2 # provide gfx info -.set FLAGS, ALIGN | MEMINFO | GFXINFO # this is the Multiboot 'flag' field -.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header -.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot - -# entry point for application processors we will copy this to 0x7000 later - -.section .smp -.code16 -_start_smp: -call smp_start # TODO: align later before going C - - -# Declare a header as in the Multiboot Standard. We put this into a special -# section so we can force the header to be in the start of the final program. -# You don't need to understand all these details as it is just magic values that -# is documented in the multiboot standard. The bootloader will search for this -# magic sequence and recognize us as a multiboot kernel. - -.section .multiboot -.code32 -.align 4 -.long MAGIC -.long FLAGS -.long CHECKSUM - -.long 0 # we dont need this for ELF -.long 0 -.long 0 -.long 0 -.long 0 - -# we override this from grub anyway -.long 0 #gfx_stuff 0=enable! -.long 640 -.long 480 -.long 32 - -# Currently the stack pointer register (esp) points at anything and using it may -# cause massive harm. Instead, we'll provide our own stack. We will allocate -# room for a small temporary stack by creating a symbol at the bottom of it, -# then allocating 16384 bytes for it, and finally creating a symbol at the top. -.section .bootstrap_stack, "aw", @nobits -stack_bottom: -.skip 16384 # 16 KiB -stack_top: - -# The linker script specifies _start as the entry point to the kernel and the -# bootloader will jump to this position once the kernel has been loaded. It -# doesn't make sense to return from this function as the bootloader is gone. -.section .text - -_start: - - # To set up a stack, we simply set the esp register to point to the top of - # our stack (as it grows downwards). - movl $stack_top, %esp - - sub $8, %esp #to align on 16byte before calling C - push %ebx #pass address of the multiboot information data structure - push %eax #pass eax, so kernel can check for magic number - - call kernel_main - - # turn off interrupts and halt. - # this should never be reached - cli - hlt - -.Lhang: - jmp .Lhang - -# Set the size of the _start symbol to the current location '.' minus its start. -# This is useful when debugging or when you implement call tracing. -.size _start, . - _start diff --git a/asm/task.h b/asm/task.h deleted file mode 100644 index 40a8c17..0000000 --- a/asm/task.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/asm/task.s b/asm/task.s deleted file mode 100644 index bf80025..0000000 --- a/asm/task.s +++ /dev/null @@ -1,114 +0,0 @@ -.global task_pusha - -task_pusha: - - pushf - push $0x8 // code segment - push $userfunc - - push $0x666 - push $0x0 - - pusha - - push %ds - push %es - push %fs - push %gs - - /* - - now stack looks like: - - param // esp+72 - returnaddy - - eflags - code segment - userfunc - - 0x666 - - eax // rest by popa - ecx - edx - ebx - esp - ebp - esi - edi - - ds - es - fs - gs - - */ - - mov 72(%esp),%eax // get address of alternative stack where we want to simulate the pusha happened - - mov (%esp),%ecx - mov %ecx,(%eax) - - mov 4(%esp),%ecx - mov %ecx,4(%eax) - - mov 8(%esp),%ecx - mov %ecx,8(%eax) - - mov 12(%esp),%ecx - mov %ecx,12(%eax) - - mov 16(%esp),%ecx - mov %ecx,16(%eax) - - mov 20(%esp),%ecx - mov %ecx,20(%eax) - - mov 24(%esp),%ecx - mov %ecx,24(%eax) - - mov 28(%esp),%ecx - mov %ecx,28(%eax) - - mov 32(%esp),%ecx - mov %ecx,32(%eax) - - mov 36(%esp),%ecx - mov %ecx,36(%eax) - - mov 40(%esp),%ecx - mov %ecx,40(%eax) - - mov 44(%esp),%ecx - mov %ecx,44(%eax) - - mov 48(%esp),%ecx - mov %ecx,48(%eax) - - mov 52(%esp),%ecx - mov %ecx,52(%eax) - - mov 56(%esp),%ecx - mov %ecx,56(%eax) - - mov 60(%esp),%ecx - mov %ecx,60(%eax) - - mov 64(%esp),%ecx - mov %ecx,64(%eax) - - pop %gs - pop %fs - pop %es - pop %ds - - popa - - pop %eax - pop %eax - pop %eax - pop %eax - pop %eax - - ret diff --git a/asm/usermode.h b/asm/usermode.h deleted file mode 100644 index 16597f2..0000000 --- a/asm/usermode.h +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @file - * Switch to User Mode and iret to function given by pointer - * provide the address of a void func() that will be called without - * any params via iret. - */ - -void asm_usermode(uint32_t func); diff --git a/asm/usermode.s b/asm/usermode.s deleted file mode 100644 index 71ecc1d..0000000 --- a/asm/usermode.s +++ /dev/null @@ -1,38 +0,0 @@ -.global asm_usermode - -asm_usermode: - - mov 0x4(%esp),%edx //get adress of passed : void func() - //to be called in ring 3 - - // 0x23 is user data segment (|2 low bits) - // 0x1b is user code segment (|2 low bits) - - // set segment registers - mov $0x23, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - - // ss is handled by iret - - mov %esp, %eax - - pushl $0x23 // user data segment - pushl $0x8fff000-3*32 //%eax // current stack - pushf // - - // http://x86.renejeschke.de/html/file_module_x86_id_145.html - //mov $0x200, %eax - //push %eax // eflags image - pushl $0x1B // return code segment selector - push %edx // return instruction pointer - - iret - - jmp . // never to be reached - - - - diff --git a/asm/x86.h b/asm/x86.h deleted file mode 100644 index 8e6a741..0000000 --- a/asm/x86.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef FOOLOS_X86_H -#define FOOLOS_X86_H - -/** - * @file - * - * X86 32-bit Basics - * ================= - * - * **All the functions are very specific to the targeted x86 architecture.** - * - * This is the header of our basic **x86** function definitions. - * Most of the functions are implemented in assembler in the file _asm/x86.s_, - * however a few short helper functions are defined in this header itself: - * - * * x86_set_page_directory() - * * x86_paging_enable() - * * x86_paging_disable() - * - * - * Reading and Writing Ports - * ------------------------- - * - * The functions of the form x86_outX() and x86_inX(), where the X - * indicates the value size allow reading and writing ports. - * - * * x86_outb() / x86_inb() - * * x86_outw() / x86_inw() - * * x86_outl() / x86_inl() - * - * The sizes are: - * - * * b - byte (8 bit) - * * w - word (16 bit) - * * l - double word (32 bit) - * - * Remember, that the port address is always 32 bits wide. - * - * Dependencies - * ------------ - * - * All we need are uint32_t, uint16_t and uint8_t as provided by - * - * References - * ---------- - * * http://wiki.osdev.org/Interrupt_Service_Routines - * * https://wiki.osdev.org/CPU_Registers_x86 - * * ... - * - */ - -// we need uint32_t, uint16_t, uint8_t // -#include - -/** write byte to port */ -void x86_outb (uint32_t port, uint8_t data); - -/** read byte from port */ -uint8_t x86_inb (uint32_t port); - -/** write word to port */ -void x86_outw (uint32_t port, uint16_t data); - -/** read word from port */ -uint16_t x86_inw (uint32_t port); - -/** write double word to port */ -void x86_outl (uint32_t port, uint32_t data); - -/** read double word from port */ -uint32_t x86_inl (uint32_t port); - -/** disable interrupts */ -void x86_cli (); - -/** enable interrupts */ -void x86_sti (); - -/** xchg - this can be used for semaphors and simlar */ -uint8_t x86_xchg (uint8_t *addr, uint8_t val); - -/** invlpg - invalidate translation lookaside buffer */ -void x86_invlpg(uint32_t addr); - -/** read value from control register specified by num */ -uint32_t x86_get_cr(uint8_t num); - -/** write given value to the control register specified by num */ -void x86_set_cr(uint8_t num, uint32_t value); - -/** Set the address of the page directory. This is required **before** enabling paging */ -static inline void x86_set_page_directory(uint32_t pdir_addr) {x86_set_cr(3,pdir_addr);} - -/** Enable paging */ -static inline void x86_paging_enable() {x86_set_cr(0,x86_get_cr(0)| 0x80000000);} - -/** Disable paging */ -static inline void x86_paging_disable() {x86_set_cr(0,x86_get_cr(0)&~0x80000000);} - -#endif diff --git a/asm/x86.s b/asm/x86.s deleted file mode 100644 index 3243352..0000000 --- a/asm/x86.s +++ /dev/null @@ -1,123 +0,0 @@ -// Basic low-level x86 32-bit calls // - -// reading and writing ports - -.global x86_outb // 8 bit out -.global x86_inb // 8 bit in -.global x86_outw // 16 bit out -.global x86_inw // 16 bit in -.global x86_outl // 32 bit out -.global x86_inl // 32 bit in - -// interrupts - -.global x86_cli // disable interrupts -.global x86_sti // enable interrupts - -// xchg -.global x86_xchg // exchange (for semaphors etc.) - -// invlpg -.global x86_invlpg // invalidate translation lookaside buffer (tlb) - -// control registers -.global x86_get_cr -.global x86_set_cr - -x86_outb: - mov 4(%esp), %edx - mov 8(%esp), %eax - outb %al,%dx - ret - -x86_inb: - mov 4(%esp), %edx - inb %dx,%al - ret - -x86_outw: - mov 4(%esp), %edx - mov 8(%esp), %eax - outw %ax,%dx - ret - -x86_inw: - mov 4(%esp), %edx - inw %dx,%ax - ret - -x86_outl: - mov 4(%esp), %edx - mov 8(%esp), %eax - outl %eax,%dx - ret - -x86_inl: - mov 4(%esp), %edx - inl %dx,%eax - ret - -x86_cli: - cli - ret - -x86_sti: - sti - ret - -x86_get_cr: - mov 4(%esp), %ecx - cmp $0,%ecx - je get_cr0 - cmp $2,%ecx - je get_cr2 - cmp $3,%ecx - je get_cr3 - cmp $4,%ecx - je get_cr4 - ret - -x86_set_cr: - mov 4(%esp), %ecx - mov 8(%esp), %eax - cmp $0,%ecx - je set_cr0 - cmp $2,%ecx - je set_cr2 - cmp $3,%ecx - je set_cr3 - cmp $4,%ecx - je set_cr4 - ret - -get_cr0: - mov %cr0,%eax - ret - -get_cr2: - mov %cr2,%eax - ret - -get_cr3: - mov %cr3,%eax - ret - -get_cr4: - mov %cr4,%eax - ret - -set_cr0: - mov %eax,%cr0 - ret - -set_cr2: - mov %eax,%cr2 - ret - -set_cr3: - mov %eax,%cr3 - ret - -set_cr4: - mov %eax,%cr4 - ret diff --git a/driver/keyboard.c b/driver/keyboard.c index 65a99da..7cc93ec 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -2,7 +2,7 @@ // http://www.computer-engineering.org/ps2keyboard/scancodes1.html -#include "asm/x86.h" +#include "asm_x86.h" #include diff --git a/driver/mouse.c b/driver/mouse.c index 958cdc4..ab7ec58 100644 --- a/driver/mouse.c +++ b/driver/mouse.c @@ -7,7 +7,7 @@ #include -#include "asm/x86.h" +#include "asm_x86.h" static volatile uint8_t mouse_cycle; static volatile uint8_t mouse_byte[3]; diff --git a/driver/pci.c b/driver/pci.c index 4ea01d1..e8d8b23 100644 --- a/driver/pci.c +++ b/driver/pci.c @@ -1,7 +1,7 @@ #include "kernel/kernel.h" -#include "asm/x86.h" +#include "asm_x86.h" #include "e1000.h" #define PCI_CONFIG_DATA 0xCFC diff --git a/driver/serial.c b/driver/serial.c index 32479ae..8a5dd2e 100644 --- a/driver/serial.c +++ b/driver/serial.c @@ -1,6 +1,6 @@ #include "driver/serial.h" -#include "asm/x86.h" // provides x86_inb() and x86_outb() +#include "asm_x86.h" // provides x86_inb() and x86_outb() /** COM1 Port */ static const PORT=0x3f8; diff --git a/driver/timer.c b/driver/timer.c index 88c9931..3a8c31c 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -1,7 +1,7 @@ #include "timer.h" -#include "asm/x86.h" +#include "asm_x86.h" static volatile uint64_t task_system_clock_start=0; diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 1e209a9..501ccd4 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -1,9 +1,9 @@ #include "kernel/kernel.h" -#include "asm/int.h" -#include "asm/pit.h" +#include "asm_int.h" +#include "asm_pit.h" #include "driver/mouse.h" #include "interrupts.h" -#include "asm/x86.h" +#include "asm_x86.h" /** The size of our interrupts table */ #define INT_MAX 255 diff --git a/kernel/mp.c b/kernel/mp.c index 5cd58ac..df7549a 100644 --- a/kernel/mp.c +++ b/kernel/mp.c @@ -2,7 +2,7 @@ #include -#include "asm/x86.h" +#include "asm_x86.h" #include "smp.h" typedef struct mp_fps_struct diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 5316438..1cbd658 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -2,7 +2,7 @@ #include "kernel.h" #include "mem.h" -#include "asm/x86.h" +#include "asm_x86.h" #include "kmalloc.h" #include "vmem.h" diff --git a/kernel/smp.c b/kernel/smp.c index 619463a..894dbe0 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -7,7 +7,7 @@ #include "smp.h" #include "mem.h" #include "spinlock.h" -#include "asm/x86.h" +#include "asm_x86.h" #define FOOLOS_APIC_SPUR_INT 0x00f0 #define FOOLOS_APIC_INT_COMMAND_LOW 0x0300 diff --git a/kernel/spinlock.c b/kernel/spinlock.c index bbc68c0..03efa6e 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -1,11 +1,9 @@ - #include "spinlock.h" #include "kernel.h" -#include "asm/x86.h" +#include "asm_x86.h" -// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html static volatile uint32_t spinlocks[NUMBER_SPINLOCKS]; @@ -16,13 +14,11 @@ void check_spinlocks() klog("%d",spinlocks[i]); } -/* void lock_spin(uint32_t i) { uint32_t *addr=spinlocks+i; while(x86_xchg(addr,1)); } -*/ void lock_release(uint32_t i) { diff --git a/kernel/spinlock.h b/kernel/spinlock.h index df35e3b..8ce2f57 100644 --- a/kernel/spinlock.h +++ b/kernel/spinlock.h @@ -1,3 +1,9 @@ +/* + * @file + * + * https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html + */ + #ifndef SPINLOCK_H #define SPINLOCK_H diff --git a/kernel/vmem.c b/kernel/vmem.c index 542b3a2..1652a9e 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -1,7 +1,7 @@ #include #include "kernel.h" -#include "asm/x86.h" +#include "asm_x86.h" #include "mem.h" #include "vmem.h" diff --git a/kernel/vmem.h b/kernel/vmem.h index 8e538bb..3bbda2f 100644 --- a/kernel/vmem.h +++ b/kernel/vmem.h @@ -28,7 +28,7 @@ * .......... User Heap (brk()) | * 0x08000000 User Code | * | - * | almost 100 megs (in kernel alloc/free?) + * | almost 100 megs (in kernel alloc/free private-cpu and shared) * | * 0x02000000 FoolOS TSS Stack TOP (max ~8mb) GROWS DOWN * leave few empty pages under stack as guard. diff --git a/linker.ld b/linker.ld index 7f10731..48a413e 100644 --- a/linker.ld +++ b/linker.ld @@ -10,7 +10,7 @@ SECTIONS .multiboot BLOCK(4K) : ALIGN(4K) { - asm/start.o(.smp) + asm/asm_start.o(.smp) asm/asm_mp.o *(.multiboot) } diff --git a/userspace/foolshell.c b/userspace/foolshell.c index 38a6e55..86c083c 100644 --- a/userspace/foolshell.c +++ b/userspace/foolshell.c @@ -66,10 +66,8 @@ int main(int argc, char **argv) if(!silent)hello(); - //char *buf=malloc(256); char *buf=calloc(sizeof(char),256); -// printf("setvbuf returned %i\n", setvbuf(stdin,NULL,_IONBF,0); while(1) @@ -80,17 +78,25 @@ int main(int argc, char **argv) while(1) { char c=fgetc(stdin); - putc(c,stdout); - if(c=='\n')break; - - buf[bl]=c; - buf[bl+1]='\0'; - bl++; + if(c=='\b') + { + if(bl==0)continue; + buf[--bl]='\0'; + putc(c,stdout); + } + else + { + putc(c,stdout); + if(c=='\n')break; + buf[bl]=c; + buf[++bl]='\0'; + } } //fgets(buf,255,stdin); //buf[strlen(buf)-1]=0; // remove \n + printf("[%s]",buf); process(buf); } -- cgit v1.2.3