summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-10-04 00:53:30 +0200
committerMiguel <m.i@gmx.at>2018-10-04 00:53:30 +0200
commitce16fe524c14ccaae67fb634105da5aef08ead48 (patch)
tree03990f29389bd4c55f40b804b809c7060c24c739
parenta455cd5af26bf8731e7c981a9421b16ab34dae6f (diff)
moving framebuffer access completely to userspace
-rw-r--r--Makefile2
-rw-r--r--README.md5
-rw-r--r--driver/keyboard.c9
-rw-r--r--driver/keyboard.h2
-rw-r--r--driver/mouse.c3
-rw-r--r--driver/serial.c4
-rw-r--r--driver/timer.c8
-rw-r--r--driver/vesa.c1
-rw-r--r--grubiso/boot/grub/grub.cfg2
-rw-r--r--interface/crt0.s4
-rw-r--r--kernel/apic.c1
-rw-r--r--kernel/interrupts.c27
-rw-r--r--kernel/kernel.c58
-rw-r--r--kernel/kernel.h7
-rw-r--r--kernel/kmalloc.c2
-rw-r--r--kernel/log.c14
-rw-r--r--kernel/log.h10
-rw-r--r--kernel/ringbuffer.c58
-rw-r--r--kernel/ringbuffer.h2
-rw-r--r--kernel/scheduler.c151
-rw-r--r--kernel/smp.c20
-rw-r--r--kernel/vmem.c11
-rw-r--r--kernel/vmem.h1
-rw-r--r--userspace/crt0.s4
-rw-r--r--userspace/init.c11
25 files changed, 250 insertions, 167 deletions
diff --git a/Makefile b/Makefile
index fb18e1a..5c6dc75 100644
--- a/Makefile
+++ b/Makefile
@@ -206,7 +206,7 @@ qemu-debug: all
-net nic,model=e1000 \
-net tap,ifname=tap0,script=no,downscript=no \
-vga virtio \
- -m 1024 -s #-S
+ -m 1024 -s -S
# qemu -enable-kvm -s -S ~/temp/FoolOs/disk.img
# qemu -enable-kvm -s -singlestep disk.img
# qemu-system-i386 -enable-kvm -s -S -kernel foolos.img -smp 4 -initrd userspace/ext2.img
diff --git a/README.md b/README.md
index 434c133..06a0495 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,8 @@ Todos
* PRIO: ringbuffers (spinlock on/off, interrupts on/off, read/write blocks of data);
* PRIO: Writing to ext2 RAM-image!!!!
* PRIO: Fix scheduler. use all cpus! / accounting/bookkeppiung x86: tsc /rdtscp? / load bareer / queues?
+* PRIO: gcc toolchain
+
* PRIO: semaphores/ mutexes
* PRIO: return value / argv / env
* PRIO: create/remove pages on demand (sbrk, stack, load prog)
@@ -106,6 +108,8 @@ Todos
* TODO: GCC optimizations (break kernel?) / volatile keyword etc?
* TODO: gcc-foolos (Porting (ncurses, gcc, binutils, vim, apache...)
+* EXTRA: fallback to pic/pit
+
* EXTRA: switch to DMA where possible!?
* EXTRA: Unit Testing
* EXTRA: GUI / Window Manager (update\_rect, etc..) / double buffering / physical, virtual sizE? virtio ? / Cairo library
@@ -113,6 +117,7 @@ Todos
* EXTRA: qemu tcg , slower other cpus
* EXTRA: Crazy & Funny terminal effects while typing (idea)
* EXTRA: port to arm and berryboot / minicom?
+* EXTRA: port doom/quake/mesa 3d
Disclaimer
----------
diff --git a/driver/keyboard.c b/driver/keyboard.c
index cc060c7..2be9c12 100644
--- a/driver/keyboard.c
+++ b/driver/keyboard.c
@@ -17,7 +17,6 @@ static bool shift_l=false;
static bool shift_r=false;
static bool capslock=false;
-static uint32_t kb_stream;
static char num_syms[]={')','!','@','#','$','%','^','&','*','('};
int hex_to_dec(char c)
@@ -30,13 +29,12 @@ int hex_to_dec(char c)
extern struct netdev e1000_dev;
static void put(uint8_t c)
{
- syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0);
+// syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0);
}
uint32_t keyboard_interrupt(uint32_t esp)
{
-
- ringbuffer_put(&kb_in,x86_inb(0x60));
+ if(!ringbuffer_put(&kb_in,x86_inb(0x60))) kpanic("full");
return esp;
}
@@ -51,11 +49,10 @@ bool keyboard_worker()
}
-void keyboard_init(uint32_t s)
+void keyboard_init()
{
kb_in=ringbuffer_init(1);// 4096 bytes ringbuffer;
interrupt_register(INTERRUPT_KEYBOARD,&keyboard_interrupt);
- kb_stream=s;
}
void keyboard_handle(uint8_t in)
diff --git a/driver/keyboard.h b/driver/keyboard.h
index 98f1f4e..007f1d1 100644
--- a/driver/keyboard.h
+++ b/driver/keyboard.h
@@ -8,6 +8,6 @@
#include <stdbool.h>
-void keyboard_init(uint32_t s);
+void keyboard_init();
void keyboard_handle(uint8_t in);
bool keyboard_worker();
diff --git a/driver/mouse.c b/driver/mouse.c
index 810cb83..274c9a5 100644
--- a/driver/mouse.c
+++ b/driver/mouse.c
@@ -81,8 +81,7 @@ static void mouse_write(uint8_t a_write)
uint32_t mouse_interrupt(uint32_t esp)
{
- uint8_t b=x86_inb(0x60);
- ringbuffer_put(&mouse_in,b);
+ if(!ringbuffer_put(&mouse_in,x86_inb(0x60)))kpanic("full");
return esp;
}
diff --git a/driver/serial.c b/driver/serial.c
index 16b3b6c..4e43251 100644
--- a/driver/serial.c
+++ b/driver/serial.c
@@ -1,5 +1,3 @@
-#ifndef FOOLOS_LOG_OFF
-
#include "serial.h"
#include "asm_x86.h" // provides x86_inb() and x86_outb()
@@ -38,5 +36,3 @@ void serial_write(uint8_t a)
while (is_transmit_empty() == 0);
x86_outb(PORT,a);
}
-
-#endif
diff --git a/driver/timer.c b/driver/timer.c
index 1a97ad8..0d9b11e 100644
--- a/driver/timer.c
+++ b/driver/timer.c
@@ -160,8 +160,8 @@ uint64_t timer_init()
{
uint64_t epoch_time=get_rtc_time();
- task_system_clock_start=epoch_time*100; // since pit ticks 100 times a second
- asm_pit_rate_50ms(); //tick at 100hz
+ task_system_clock_start=epoch_time*20; // clock ticks 20 times a second
+ asm_pit_rate_50ms(); //tick at 20hz
interrupt_register(INTERRUPT_PIT_TIMER,&timer_interrupt);
@@ -170,10 +170,10 @@ uint64_t timer_init()
uint64_t timer_get_ms()
{
- return (asm_pit_get_ticks()+task_system_clock_start)*50;
+ return (asm_pit_get_ticks()+task_system_clock_start)*50; // 50ms passed on each tick
}
uint64_t timer_get_uptime_ms()
{
- return asm_pit_get_ticks()*50;
+ return asm_pit_get_ticks()*50; // 50ms passed on each tick
}
diff --git a/driver/vesa.c b/driver/vesa.c
index 7405422..bd5c53d 100644
--- a/driver/vesa.c
+++ b/driver/vesa.c
@@ -152,6 +152,7 @@ uint32_t vesa_init(multiboot_information *inf, foolfont *rawfont)
int line_height=12;
int col_width=10;
+
console_lines=vesaYres/line_height;
console_cols=vesaXres/col_width;
diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg
index ad49f88..f16c3a0 100644
--- a/grubiso/boot/grub/grub.cfg
+++ b/grubiso/boot/grub/grub.cfg
@@ -1,4 +1,4 @@
-set timeout=0 //seconds
+set timeout=1 //seconds
if loadfont ${prefix}/fonts/unicode.pf2
diff --git a/interface/crt0.s b/interface/crt0.s
index 26ad47c..dedc86c 100644
--- a/interface/crt0.s
+++ b/interface/crt0.s
@@ -19,10 +19,10 @@ jne copy
pop %ecx
pop %ebx
-# environment adress was passed on stack
-
movl $0xf5000000, _impure_ptr
+# environment adress was passed on stack
+
pop %eax
mov %eax, environ
diff --git a/kernel/apic.c b/kernel/apic.c
index 75837f7..509fd3b 100644
--- a/kernel/apic.c
+++ b/kernel/apic.c
@@ -71,6 +71,7 @@ static uint32_t apic_read(uint32_t offset)
uint32_t apic_id()
{
+ if(local_apic_addr==0)return 0;
return apic_read(APIC_APICID)>>24;
}
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index 49c0191..4aa9db3 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -64,13 +64,32 @@ void interrupt_register(uint32_t irq, uint32_t func_addr)
*/
uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
{
- uint32_t *stack;
-
if(handlers[irq]!=0)
{
uint32_t (*f)(uint32_t esp)=handlers[irq];
esp=f(esp);
apic_eoi();
+ return esp;
+ }
+
+ if(irq==INTERRUPT_APIC_TIMER)
+ {
+ klog ("tick");
+ esp=scheduler_run(esp,-1);
+ apic_eoi();
+ return esp;
+ }
+
+ kpanic("unhandled interrupt %d",irq);
+
+
+ uint32_t *stack;
+
+ if(handlers[irq]!=0)
+ {
+ //uint32_t (*f)(uint32_t esp)=handlers[irq];
+ //esp=f(esp);
+ apic_eoi();
}
else if(irq!=INTERRUPT_SYSCALL&&irq!=INTERRUPT_IPI&&irq!=INTERRUPT_APIC_TIMER)
@@ -83,7 +102,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
{
case INTERRUPT_SYSCALL:
stack=esp;
- task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx
+ // task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx
break;
@@ -105,7 +124,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
// reschedule to kernel worker on these
if(irq==INTERRUPT_SYSCALL||irq==INTERRUPT_KEYBOARD||irq==INTERRUPT_MOUSE)
{
- scheduler_wake_worker(esp);
+ // scheduler_wake_worker(esp);
esp=scheduler_run(esp,-1);
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 70b1913..3e07fde 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -41,7 +41,32 @@
#include "driver/vesa.h"
#include "asm_pit.h"
-/* F00L 0S Entry point (called directly from asm/multiboot.asm */
+/** F00L 0S Entry point (called directly from asm/multiboot.asm)
+ *
+ * After this procedure completes we are in a well defined state.
+ *
+ * * All Processors are up and running in 32bit protected mode.
+ * * Interrupts are installed and enabled:
+ *
+ * - PS/2 Keyboard CPU0
+ * - PS/2 Mouse CPU0
+ * - PIT Timer (20Hz) (DISABLED in apic.c) CPU0
+ * - APIC Timer (Frequency defined in kernel.h) ALL CPUS
+ * - E1000 CPU0
+ *
+ * * Software Interrupts:
+ *
+ * - Syscalls
+ * - IPI
+ *
+ * * Framebuffer is in a known state.
+ * * Paging is enabled.
+ * * Each CPU runs on its own stack at VMEM_CPU_STACK
+ * * Each CPU has its own private page at VMEM_CPU_PRIVATE
+ * * We are ready to start scheduling on the next interrupt.
+ *
+ */
+
void kernel_main(uint32_t eax,uint32_t ebx)
{
// -- COM1 -- //
@@ -60,7 +85,7 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("The Kernel was loaded at: 0x%08X - 0x%08X",get_kernel_start(),get_kernel_end());
klog("0x00000000 - 0x%08X will get identity mapped", VMEM_KERNEL_PAGES*4096);
if(kernel_end>=top_kernel_vmem)kpanic("kernel to big. increase VMEM_KERNEL_PAGES");
- fixme("fear overrun of the initial buffer!");
+ fixme("still fear overrun of stack");
// -- DISABLE LEGACY PIC -- //
klog("Remapping & Disabling Programmable Interrupt Controller (PIC) ...");
@@ -87,7 +112,6 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Interrupt Vector Table (IVT) init ...");
interrupts_init(0x08);
interrupts_install();
- fixme("register interrupt callback funcs (instead hardcoded dispatcher)");
// -- PCI SCAN --/
klog("PCI init ...");
@@ -120,14 +144,16 @@ void kernel_main(uint32_t eax,uint32_t ebx)
ioapic_config();
// -- VESA -- //
+ /*
fixme("tell terminal syscall somehow if we are vga or textmode");
klog("Video Electronics Standards Association (VESA) init ... ");
// binfont has to fit in ONE ext2 block //
+
fixme("support binfonts spanning multiple blocks?");
uint32_t inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,VESA_FONT_PATH);
uint32_t addr= ext2_inode_blockstart( VMEM_EXT2_RAMIMAGE,inode,0);
- vesa_init(cfg_multiboot,addr);
+ vesa_init(cfg_multiboot,addr); // this only sets some internal static variables
klog("Compositor init ...");
compositor_init(cfg_multiboot->framebuffer_width,cfg_multiboot->framebuffer_height,cfg_multiboot->framebuffer_pitch);
@@ -136,29 +162,35 @@ void kernel_main(uint32_t eax,uint32_t ebx)
// -- STD STREAMS -- //
klog("Standard Streams init ...");
fd_init_std_streams(0,cfg_multiboot->framebuffer_type!=2);
+ */
// -- KB -- //
klog("Keyboard init ...");
- keyboard_init(0);
+ keyboard_init();
// -- MOUSE -- //
klog("Mouse init ...");
mouse_init();
- // we wait till almost the end since the time will only start ticking after we
- // enable interrupts
- klog("Programmable Interval Timer (PIT) init ...");
- uint64_t unixtime=timer_init();
- klog("Unix Time = %u seconds",unixtime);
-
// -- E1000 INIT (TODO: only if present!) --/
if(e1000_addr)
{
+ #ifndef DISABLE_E1000
klog("E1000 init ...");
- // e1000_init(e1000_addr);
+ e1000_init(e1000_addr);
+ #endif
}
+ // we wait until the end since the time will only start ticking once
+ // we enable interrupts.
+ klog("Programmable Interval Timer (PIT) init ...");
+ klog("Reading CMOS Clock ...");
+ uint64_t unixtime=timer_init();
+ klog("Unix Time = %u seconds",unixtime);
+
klog("Symmetric Multi Processing (SMP) start ... ");
// for(int i=1;i<cfg_acpi.processors;i++)apic_sipi(i,0x7);
- smp_bsp();
+
+
+ smp_bsp(); // start base processor
}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 8ec8852..03429f4 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -25,11 +25,14 @@ REFERENCES
#define VESA_MAX_WIDTH 1920
#define VESA_MAX_HEIGHT 1080
+#define DISABLE_E1000
//#define FOOLOS_UNIT_TESTING // Run Unit Tests
-#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether)
+//#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether)
//#define FOOLOS_COLORLESS // Turn off colors in log
#define HIDE_FIXME
+#define FOOLOS_APIC_FREQ 3 // how many apic ticks per second
+
#define MAX_MOUNTS 10
#define BIN_INIT "/bin/init"
@@ -65,7 +68,7 @@ REFERENCES
#define VMEM_USER_ENV 0x07000000 // 1 page / per user process
-#define VMEM_USER_PROG_PAGES 256*16
+#define VMEM_USER_PROG_PAGES (256*16)
#define VMEM_USER_PROG 0x08048000 // ? pages / per user process (usual entry: 0x8048080)
#define VMEM_USER_STACK_PAGES 4 // 4 pages / per thread
diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c
index 38db6fc..b677559 100644
--- a/kernel/kmalloc.c
+++ b/kernel/kmalloc.c
@@ -99,7 +99,7 @@ uint32_t kballoc(uint32_t size)
mark_used(blk,size);
spinlock_release(SPINLOCK_ALLOC);
- klog("allocated %d blocks at 0x%08X",size,data_addr+blk*4096);
+ //klog("allocated %d blocks at 0x%08X",size,data_addr+blk*4096);
return data_addr+blk*4096;
}
diff --git a/kernel/log.c b/kernel/log.c
index af6ebac..179f9a8 100644
--- a/kernel/log.c
+++ b/kernel/log.c
@@ -6,6 +6,8 @@
#include <stdbool.h>
#include "spinlock.h"
+#include "smp.h"
+#include "apic.h"
#include "kernel/kernel.h"
#include "driver/serial.h"
@@ -23,8 +25,10 @@ static void log_string(char *str)
}
}
-void log(bool color,char *module_name, int prio, char *format_string, ...)
+void log(char *module_name, int prio, char *format_string, ...)
{
+ uint32_t cpu=apic_id();
+
#ifdef FOOLOS_LOG_OFF
return;
#endif
@@ -44,10 +48,10 @@ void log(bool color,char *module_name, int prio, char *format_string, ...)
tfp_vsprintf(buf_info,format_string,va);
va_end(va);
- if(color) tfp_sprintf(buf_log,"\033[36;40m%s\033[31;40m %s:\033[37;40m %s\n",buf_time,module_name,buf_info);
- else tfp_sprintf(buf_log,"%s %s: %s\n",buf_time,module_name,buf_info);
+ tfp_sprintf(buf_log,"\033[36;40m%s\033[33;40mCPU %02d:\033[31;40m%s:\033[37;40m %s\n",buf_time,cpu,module_name,buf_info);
+// tfp_sprintf(buf_log,"%sCPU %02d:%s: %s\n",buf_time,cpu,module_name,buf_info);
-// spinlock_spin(SPINLOCK_LOG);
+ spinlock_spin(SPINLOCK_LOG);
log_string(buf_log);
-// spinlock_release(SPINLOCK_LOG);
+ spinlock_release(SPINLOCK_LOG);
}
diff --git a/kernel/log.h b/kernel/log.h
index 4e25bef..d834efd 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -11,7 +11,7 @@
#define FOOLOS_LOG_DEBUG 2
#define FOOLOS_LOG_FINE 1
-void log(bool color,char *module_name, int prio, char *format_string, ...);
+void log(char *module_name, int prio, char *format_string, ...);
// __FUNCTION__ ?
#ifndef FOOLOS_LOG_OFF
@@ -35,16 +35,16 @@ void log(bool color,char *module_name, int prio, char *format_string, ...);
#define S1(x) #x
#define S2(x) S1(x)
-#define klog(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__), 10, LOG_LABEL_INFO __VA_ARGS__)
-#define kpanic(...) {log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) ,0, LOG_LABEL_PANIC __VA_ARGS__ ); while(1);}
+#define klog(...) log(__FILE__ ":" S2(__LINE__), 10, LOG_LABEL_INFO __VA_ARGS__)
+#define kpanic(...) {log(__FILE__ ":" S2(__LINE__) ,0, LOG_LABEL_PANIC __VA_ARGS__ ); while(1);}
#ifdef HIDE_FIXME
#define fixme(...) {}
#else
-#define fixme(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) , 10, LOG_LABEL_FIX __VA_ARGS__)
+#define fixme(...) log(__FILE__ ":" S2(__LINE__) , 10, LOG_LABEL_FIX __VA_ARGS__)
#endif
-#define testlog(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) , 10,LOG_LABEL_TEST __VA_ARGS__)
+#define testlog(...) log(__FILE__ ":" S2(__LINE__) , 10,LOG_LABEL_TEST __VA_ARGS__)
#endif
diff --git a/kernel/ringbuffer.c b/kernel/ringbuffer.c
index 43d0e33..3886340 100644
--- a/kernel/ringbuffer.c
+++ b/kernel/ringbuffer.c
@@ -16,48 +16,58 @@ void ringbuffer_free(ringbuffer *f)
kbfree(f->data);
}
-bool ringbuffer_put(ringbuffer* f,uint8_t c)
+bool ringbuffer_full(ringbuffer* f)
{
- if(ringbuffer_full(f))return false;
-
- f->data[f->back]=c;
- f->back--;
- f->back+=f->size;
- f->back%=f->size;
- return true;
+ if((f->back-1+f->size)%f->size==f->front)return true;
+ return false;
}
-bool ringbuffer_full(ringbuffer* f)
+bool ringbuffer_empty(ringbuffer* f)
{
- if((f->back-1+f->size)%f->size==f->front)
- {
- return true;
- }
+ if(f->front==f->back)return true;
return false;
}
bool ringbuffer_has(ringbuffer* f)
{
- bool res=true;
+ return !ringbuffer_empty(f);
+}
+
+//
+
+bool ringbuffer_put(ringbuffer* f,uint8_t c)
+{
+ if(ringbuffer_full(f))return false;
+
+ f->data[f->back]=c;
+ f->back--;
+ f->back+=f->size;
+ f->back%=f->size;
- if(f->front==f->back)
- res=false;
- return res;
+ return true;
}
uint8_t ringbuffer_get(ringbuffer* f)
{
- char c;
-
- if(f->front==f->back)
- {
- return 0;
- }
+ if(ringbuffer_empty(f))return 0; // indistinguishable from value 0 :( // TODO
- c=f->data[f->front];
+ uint8_t c = f->data[f->front];
f->front--;
f->front+=f->size;
f->front%=f->size;
+
return c;
}
+
+// TODO //
+
+uint32_t ringbuffer_write(ringbuffer* f, uint8_t *buf, uint32_t size)
+{
+ return 0;
+}
+
+uint32_t ringbuffer_read(ringbuffer* f, uint8_t *buf, uint32_t size)
+{
+ return 0;
+}
diff --git a/kernel/ringbuffer.h b/kernel/ringbuffer.h
index 6ad9537..f68f766 100644
--- a/kernel/ringbuffer.h
+++ b/kernel/ringbuffer.h
@@ -27,7 +27,7 @@
#include <stdbool.h>
/** Ringbuffer sturcutre */
-typedef volatile struct ringbuffer_struct
+typedef struct ringbuffer_struct
{
uint32_t size;
uint32_t front;
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index a4e3743..9fdff7d 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -74,10 +74,10 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
}
current_task[cpu]=0;
- last_task[cpu]=0;
+// last_task[cpu]=0;
// need to make space on the esp stacks for pushing vals vias task_pusha
-
+
// this is our main kernel task at slot 0 (per cpu)
task_list[cpu][0].parent=0;
task_list[cpu][0].pid=nextPID();
@@ -85,10 +85,10 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][0].syscall=false;
task_list[cpu][0].thread=false;
task_list[cpu][0].vmem=dir;
- task_list[cpu][0].esp = VMEM_CPU_STACK_TOP-0x200-8;
- task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks
- strcpy(task_list[cpu][0].name,"kernel_worker");
- fd_init_std_streams(task_list[cpu][0].pid,0);
+ task_list[cpu][0].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
+ task_list[cpu][0].esp0 = 0; // esp0 not required by kernel space tasks
+ strcpy(task_list[cpu][0].name,"kernel worker");
+ //fd_init_std_streams(task_list[cpu][0].pid,0);
// this will go to userspace
task_list[cpu][1].parent=0;
@@ -97,11 +97,11 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][1].thread=false;
task_list[cpu][1].syscall=false;
task_list[cpu][1].vmem=dir;
- task_list[cpu][1].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
- task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
- strcpy(task_list[cpu][1].name,"init");
- fd_init_std_streams(task_list[cpu][1].pid,0);
-
+ task_list[cpu][1].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
+ task_list[cpu][1].esp = VMEM_USER_STACK_TOP-0x200-8;
+ task_list[cpu][1].esp0 = kballoc(4)+4*4096; // esp0 needed by user space tasks
+ strcpy(task_list[cpu][1].name,"userspace init");
+ //fd_init_std_streams(task_list[cpu][1].pid,0);
// sleeper
task_list[cpu][2].parent=0;
@@ -111,9 +111,9 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][2].syscall=false;
task_list[cpu][2].vmem=dir;
task_list[cpu][2].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
- task_list[cpu][2].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
+ task_list[cpu][2].esp0 =0; // esp0 not needed by kernel space tasks
strcpy(task_list[cpu][2].name,"idle process");
- fd_init_std_streams(task_list[cpu][2].pid,0);
+ //fd_init_std_streams(task_list[cpu][2].pid,0);
// stacks
task_pusha(task_list[cpu][0].esp);
@@ -128,8 +128,8 @@ static uint32_t scheduler_schedule(uint32_t idx)
if(task_list[cpu][idx].active && !task_list[cpu][idx].syscall)
{
- if(current_task[cpu]!=0)last_task[cpu]=current_task[cpu];
- if(current_task[cpu]==idx)return task_list[cpu][idx].esp;
+ //if(current_task[cpu]!=0)last_task[cpu]=current_task[cpu];
+ //if(current_task[cpu]==idx)return task_list[cpu][idx].esp;
current_task[cpu]=idx;
@@ -162,49 +162,26 @@ volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t preference)
uint32_t cpu=smp_get(SMP_APIC_ID);
uint32_t init=smp_get(SMP_SCHEDULER_INIT);
- if(init){
+ if(init)
+ {
scheduler_init(cpu,x86_get_page_directory());
smp_set(SMP_SCHEDULER_INIT,0);
+ klog("Scheduler initialized for cpu %d",cpu);
+ return task_list[cpu][current_task[cpu]].esp;
}
-
else task_list[cpu][current_task[cpu]].esp=oldesp;
- uint32_t esp;
-
- if(preference!=-1)
- {
- esp=scheduler_schedule(preference); // try preference
- if(esp)return esp;
-
- if(current_task[cpu]==0)// we have interrupted a task with ring1 work
- {
- esp=scheduler_schedule(last_task[cpu]); // try preference
- if(esp)return esp;
- }
- }
- else
- {
- //klog("preempt %d", last_task[cpu]);
- }
-
for(int i=0;i<MAX_TASKS;i++)
{
- int idx=(last_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style
-// if(preference==-1&&idx==0)continue;
-
- if(idx==preference||idx==2)continue;// skip sleeper and preferred tasks here.
-
- esp=scheduler_schedule(idx);
-
- if(esp){
- //klog("%d",idx);
- return esp;
- }
+ int idx=(current_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style
+// if(idx==2)continue;// skip sleeper here
+ uint32_t esp=scheduler_schedule(idx);
+ if(esp)return esp;
}
+ kpanic("nothing left to schedule");
- // force the sleeper task...
+ // force the sleeper task here ...
return scheduler_schedule(2);
-
}
@@ -213,35 +190,60 @@ void scheduler_func()
// we need enable here again (since the pushed eflags have it disabled)? TODO: why they disabled it!???
x86_sti();
+
uint32_t cpu=smp_get(SMP_APIC_ID);
+ fixme("this will dadlock on context switch during log if never switched back before finish");
+
if(current_task[cpu]==0)
- while(1)
{
- task_syscall_worker();
+ while(1)
+ {
+ uint64_t t0=x86_rdtscp();
+ asm("hlt"); // sleeper task
+ uint64_t t1=x86_rdtscp();
+ klog("task 0 / slept cycles: l:%d h:%d",(t1-t0));
+ }
+
+// task_syscall_worker();
+ //task_list[cpu][0].syscall=true; // sleep
+ //__asm__("int $0x81"); // wake scheduler! with IPI
+
}
- if(current_task[cpu]==2)
- while(1)
+ if(current_task[cpu]==1)
{
- uint64_t t0=x86_rdtscp();
- asm("hlt"); // sleeper task
- uint64_t t1=x86_rdtscp();
- klog("slept: l:%d h:%d",(t1-t0));
+ if(cpu==0)
+ {
+ uint32_t alloc;
+ uint32_t entry_global=load_elf(BIN_INIT,&alloc);
+ task_set_brk(task_get_current_pid(),alloc);
+ asm_usermode(entry_global);
+ kpanic("init died on cpu %d",cpu);
+ }
+
+ while(1)
+ {
+ uint64_t t0=x86_rdtscp();
+ asm("hlt"); // sleeper task
+ uint64_t t1=x86_rdtscp();
+ klog("task 1 / slept cycles: l:%d h:%d",(t1-t0));
+ }
}
- if(current_task[cpu]==1)
- while(1)
+ if(current_task[cpu]==2)
{
- if(cpu==0)
- {
- uint32_t alloc;
- uint32_t entry_global=load_elf(BIN_INIT,&alloc);
- task_set_brk(task_get_current_pid(),alloc);
- asm_usermode(entry_global);
- while(1);
- }
+ while(1)
+ {
+ uint64_t t0=x86_rdtscp();
+ asm("hlt"); // sleeper task
+ uint64_t t1=x86_rdtscp();
+ klog("task 2 (sleeper) / slept cycles: l:%d h:%d",(t1-t0));
+ }
}
+
+ kpanic("unknwon task");
+
}
volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread, char *name)
@@ -324,9 +326,10 @@ void scheduler_wake_all()
*/
void task_syscall_worker()
{
- static uint32_t c=0;
- /// TODO: cross check all cpus!
uint32_t cpu=smp_get(SMP_APIC_ID);
+ task_list[cpu][0].syscall=true; // sleep (syscall misused)
+ return;
+ /// TODO: cross check all cpus!
while(1)
{
@@ -335,14 +338,14 @@ void task_syscall_worker()
//TODO: would be enough only to lock during ringbuffer acces!?
- x86_cli(); // disable temporarily mouse/kb/timer interrupts.
- wake|=keyboard_worker();
- wake_mouse|=mouse_worker();
- x86_sti();
+ //x86_cli(); // disable temporarily mouse/kb/timer interrupts.
+ //wake|=keyboard_worker();
+ //wake_mouse|=mouse_worker();
+ //x86_sti();
- if(wake_mouse)compositor_swap_buffers();
+ //if(wake_mouse)compositor_swap_buffers();
- if(wake)scheduler_wake_all();
+ //if(wake)scheduler_wake_all();
//if(cpu==0)compositor_swap_buffers();
diff --git a/kernel/smp.c b/kernel/smp.c
index 01230cf..a57b4b9 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -34,19 +34,22 @@ void smp_main_generic(bool bsp)
{
if(!bsp) // for the bsp this was already done beforehand
{
+ struct pdirectory_struct *dir=vmem_kernel_dir();
+ x86_set_page_directory(dir);
+ x86_paging_enable();
+
+ klog("Just setup Paging on CPU with lapic_id=0x%x",apic_id());
+
klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id());
interrupts_install();
klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id());
gdt_init();
- klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id());
- struct pdirectory_struct *dir=vmem_kernel_dir();
- x86_set_page_directory(dir);
- x86_paging_enable();
}
// setup stack and jump to kernel_ap();
+ fixme("we hate iniline assembly!");
uint32_t ebp=VMEM_CPU_STACK_TOP;
asm volatile("mov %0, %%ebp"::"r"(ebp));
asm volatile("mov %ebp, %esp");
@@ -58,7 +61,7 @@ void run_smp()
apic_enable();
klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id());
- apic_init_timer(3);// freq x HZ
+ apic_init_timer(FOOLOS_APIC_FREQ);// freq x HZ
klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id());
asm_smp_unlock();
@@ -67,13 +70,6 @@ void run_smp()
smp_set(1000,'a'+apic_id());
smp_set(SMP_SCHEDULER_INIT,1);
- if(apic_id()==0)
- {
-// apic_sipi(1,0x7);
-// apic_sipi(2,0x7);
-// apic_sipi(3,0x7);
- }
-
x86_sti();
while(1)asm("hlt"); // wait for scheduler to kick in
diff --git a/kernel/vmem.c b/kernel/vmem.c
index d99f6fd..a388535 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -346,7 +346,7 @@ pdirectory* vmem_kernel_dir()
vmem_add_identity(dir,VMEM_KERNEL,VMEM_KERNEL_PAGES,false);//identity map first 32 megs...
vmem_add_identity(dir,e1000_addr,32,false);//identity map 32 pages for e1000
- vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,false);//32megs should be enough for 4k (think about pitch)
+ vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch)
vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1,false); //apic addr should be at pagestart, right? TODO: check.
vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1,false);
@@ -359,17 +359,22 @@ pdirectory* vmem_kernel_dir()
vmem_add_alloc(dir,VMEM_USER_ENV,1,true);
vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true);
vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true);
- vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area
+// vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area
return dir;
}
void vmem_add_framebuffer(pdirectory *dir)
{
- vmem_del_generic(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,false, true);
+ //vmem_del_generic(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,false, true);
vmem_add_alloc(dir, VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area
}
+void vmem_add_total_framebuffer(pdirectory *dir)
+{
+ vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch)
+}
+
void vmem_free_space_dir(pdirectory *dir,bool stack_only)
{
diff --git a/kernel/vmem.h b/kernel/vmem.h
index 73f9ce6..7573dc3 100644
--- a/kernel/vmem.h
+++ b/kernel/vmem.h
@@ -58,5 +58,6 @@ void vmem_free_dir(struct pdirectory_struct *dir);
struct pdirectory_struct* vmem_new_space_dir(struct pdirectory_struct *copy_dir,bool stack_only);
void vmem_free_space_dir(struct pdirectory_struct *dir,bool stack_only);
void vmem_add_framebuffer(struct pdirectory_struct *dir);
+void vmem_add_total_framebuffer(struct pdirectory_struct *dir);
struct pdirectory_struct* vmem_kernel_dir();
diff --git a/userspace/crt0.s b/userspace/crt0.s
index 26ad47c..dedc86c 100644
--- a/userspace/crt0.s
+++ b/userspace/crt0.s
@@ -19,10 +19,10 @@ jne copy
pop %ecx
pop %ebx
-# environment adress was passed on stack
-
movl $0xf5000000, _impure_ptr
+# environment adress was passed on stack
+
pop %eax
mov %eax, environ
diff --git a/userspace/init.c b/userspace/init.c
index 0a3b870..d130bc8 100644
--- a/userspace/init.c
+++ b/userspace/init.c
@@ -1,11 +1,22 @@
#include <stdio.h>
#include <time.h>
+#include "put_pixel.h"
int main(int argc, char **argv)
{
+
+ // int x=10/0; // provoke divide by zero
+
+ uint8_t *mem=0xf6000000;
+ *mem='a';
+ while(1);
+
char *argv1[]={"/bin/fsh",0};
char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0};
+
+
+
// loop forever and spawn shells if the top-shell exits
while(1)
{