diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-07-11 00:18:49 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-07-11 00:18:49 +1000 |
| commit | 99d16e98e04c73e108160d7d70244bafdb33b6fc (patch) | |
| tree | 4bdd78c2340e4c9ff2a875ad07908b5f258357fc /kernel/timer.s | |
| parent | b99a1b58d63dfefb319eecb564c07a4029e02233 (diff) | |
Implemented a basic scheduler using an array of task structures in which
each structure has a TSS inside, as well as several descriptor entries
in the GDT pointing to each task's TSS. Task switching is performed in
hardware by means of far jumping to the new task's TSS descriptor in the
GDT. Task states are saved manually by copying the saved state from the
interrupt handler's stack, back into the task's TSS.
Added the function save_state() to sched.c which can be called from
assembly to copy the state information of the suspended task from the
current stack, to it's respective task structure. NOTE: this assumes
that the pointer cstate has been set ahead of time to point to the state
information on the stack, and that the pointer ctask has not yet been
modified.
Added the function reschedule() which is currently called from the
timer's tick handler. Currently, this function merely alternates between
the two tasks created in sched_init(), but in future, will be expanded
to decided independently which task will run next.
The function userspace_init() was renamed to the more appropriate
sched_init().
Moved most of the code from the original userspace_init() to the new
function create_proc() which sets up a virtual address space and state
information, copies the specified binary into the new address space,
then returns a pointer to the newly created tasks entry in the task
table.
Defined the type pid_t in unistd.h as a 16-bit unsigned integer.
Added two new debugging system calls for checking which task is
currently active. The getpid() system calls returns the caller's PID
whilst the getpdir() call returns the physical location of the caller's
page directory (the value of CR3). The getpdir() call can be used as a
fallback to determine which task is *actually* running if the
information in ctask or the getpid() call is faulty.
Added two new subroutines; set_tss() and clear_tss() (whose prototypes
are defined in asm/system.h) for managing the task-state descriptor
entries in the GDT. set_tss() initializes a TSS descriptor and sets it's
base pointer to the supplied TSS pointer whilst clear_tss() simply marks
a TSS descriptor as 'not present' without clearing it.
Diffstat (limited to 'kernel/timer.s')
| -rw-r--r-- | kernel/timer.s | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/timer.s b/kernel/timer.s index 3723782..c84a847 100644 --- a/kernel/timer.s +++ b/kernel/timer.s @@ -1,15 +1,40 @@ global ticks global timer_init +extern cstate extern register_isr +extern reschedule ticks: dd 0 tick_handler: + pusha + ; save the data segment selectors + mov ax, ds push ax + ; switch to kernel data segments + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + ; save a pointer to the state information + mov [cstate], esp + + ; handle the timer tick inc dword [ticks] mov al, 0x20 out 0x20, al + + ; call the scheduler + call reschedule + + ; restore the data segment selectors pop ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa iret timer_init: |
