diff --git a/include/asm/io.h b/include/asm/io.h index bc51561472e9d42e432f7cf9a635905fda7eabb9..b2f16c15bae528f9efb79f34f814c3f4a0be53ad 100644 --- a/include/asm/io.h +++ b/include/asm/io.h @@ -1,10 +1,31 @@ #ifndef _IO_H #define _IO_H +#define outb(value,port) \ +__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port)) + + +#define inb(port) ({ \ +i unsigned char _v; \ + __asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \ + _v; \ +}) + + #define outb_p(value, port) \ __asm__("outb %%al, %%dx\n" \ "\tjmp 1f\n" \ "1:\tjmp 1f\n" \ "1:" :: "a"(value), "d"(port)) + +#define inb_p(port) ({ \ +unsigned char _v; \ +__asm__ volatile ("inb %%dx,%%al\n" \ + "\tjmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:":"=a" (_v):"d" (port)); \ +_v; \ +}) + #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index dce71186b97e61d967b13ab8e2da1dfedcb58bbc..2278399dac843f834d5e7c5afe40b319ceb79644 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1,6 +1,8 @@ #ifndef _SCHED_H #define _SCHED_H +#define HZ 100 + #include #include diff --git a/kernel/sched.c b/kernel/sched.c index b7a5043608e01042cdb0e8f5bc1d9145cf06057b..503810ee3c943cabecea03ff5bd45cffcd6ee4b7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1,10 +1,13 @@ #include #include - +#include + +#define LATCH (1193180/HZ) #define PAGE_SIZE 4096 extern int system_call(); +extern void timer_interrupt(); union task_union { struct task_struct task; @@ -21,6 +24,14 @@ struct short b; } stack_start = {&user_stack[PAGE_SIZE >> 2], 0x10}; +void do_timer(long cpl) { + static unsigned char c = '0'; + if (c > 127) { + c = '0'; + } + printk("\b%c", c++); +} + void sched_init() { struct desc_struct* p; set_tss_desc(gdt + FIRST_TSS_ENTRY, &(init_task.task.tss)); @@ -28,6 +39,14 @@ void sched_init() { __asm__("pushfl; andl $0xffffbfff, (%esp); popfl"); ltr(0); lldt(0); + + /* open the clock interruption! */ + outb_p(0x36, 0x43); + outb_p(LATCH & 0xff, 0x40); + outb(LATCH >> 8, 0x40); + set_intr_gate(0x20, &timer_interrupt); + outb(inb_p(0x21) & ~0x01, 0x21); + set_system_gate(0x80, &system_call); } diff --git a/kernel/sys_call.S b/kernel/sys_call.S index a71dab3cbcbaa2e5de6aec6443a0aac9d6bb6fb2..a75406c7e14c02cabf34e35d63482418bb0a1589 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -1,11 +1,24 @@ .code32 .text -.globl system_call +.globl system_call, timer_interrupt + +EAX = 0x00 +EBX = 0x04 +ECX = 0x08 +EDX = 0x0C +FS = 0x10 +ES = 0x14 +DS = 0x18 +EIP = 0x1c +CS = 0x20 +EFLAGS = 0x24 +OLDESP = 0x28 +OLDSS = 0x2c + int_msg: - .asciz "In kernel interrupt" + .asciz "In kernel interrupt\n\r" system_call: - /* we do not have function _printk now, so trick it */ pushl %eax pushl %ecx pushl %edx @@ -28,3 +41,35 @@ system_call: popl %eax iret +ret_from_sys_call: + popl %eax + popl %ebx + popl %ecx + popl %edx + popw %fs + popw %es + popw %ds + iret + +.align 4 +timer_interrupt: + pushw %ds + pushw %es + pushw %fs + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + movl $0x10, %eax + movw %ax, %ds + movw %ax, %es + movl $0x17, %eax + movw %ax, %fs + movb $0x20, %al + outb %al, $0x20 + movl CS(%esp), %eax + andl $3, %eax + pushl %eax + call do_timer + addl $4, %esp + jmp ret_from_sys_call