; ; Copyright 2010 Stefan Lankes, Chair for Operating Systems, ; RWTH Aachen University ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; This file is part of metalsvm. [BITS 32] SECTION .code extern get_new_task extern current_task ;extern task_table ; C prototyp: ; ; typedef struct { ; unsigned char* top; ; unsigned int ip; ; tid_t id; ; ... ; } task_t; ; After an interrupt, the original return address has to push on the stack ; because we want to comeback... global schedule_entry schedule_entry: cli sub esp, 4 ; add some space for the retunr address, ; which is stored in current_task->ip pushfd pusha push ds push es push fs push gs mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax ;mov eax, DWORD [current_id] ;shl eax, 0x4 ; 16 = sizeof(task_t) ;mov edx, DWORD [eax+task_table+4] ;mov [esp+13*4], edx ;mov DWORD [eax+task_table+4], 0 mov eax, DWORD [current_task] mov edx, [eax+4] mov DWORD [esp+13*4], edx mov DWORD [eax+4], 0x00 jmp L1 ; Scheduler, which switchs to the new tasks global schedule schedule: ret cli ; return address is already on the stack (via call schedule) pop eax pushfd push 0x08 push eax push byte 0 push byte 32 pusha push ds push es push fs push gs mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov eax, DWORD [current_task] mov [eax], esp ;call get_new_task mov DWORD [current_task], eax mov esp, [eax] pop gs pop fs pop es pop ds popa add esp, 8 xor eax, eax ; return value is 0 iret cli pushfd pusha push ds push es push fs push gs mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax ; store current esp ;mov eax, DWORD [current_id] ;shl eax, 0x4 ; 16 = sizeof(task_t) L1: ;mov [eax+task_table], esp mov eax, DWORD [current_task] mov [eax], esp ;call get_new_task ; set current task and restore esp ;mov DWORD [current_id], eax ;shl eax, 0x4 ; 16 = sizeof(task_t) ;mov esp, [eax+task_table] mov DWORD [current_task], eax mov esp, [eax] pop gs pop fs pop es pop ds popa popfd sti ret