Hi,
Ok, I realise that replying to my own post might be a sign of insanity, but I've been doing some research and think I've found the main reason why my advice isn't helping GLneo much...
From an earlier post:
GLneo wrote:
Code:
_task_timer
cld
pushad
push ds
push es
push fs
push gs
; mov eax,[p]
; mov [eax],esp
; lea eax,[kstackend]
; mov esp,eax
mov eax, _timer_handler
call eax
; mov eax,[p]
; mov esp,[eax]
; mov ebx,[eax+8]
; mov [sys_tss+4],ebx
mov al,0x20
out 0x20,al
pop gs
pop fs
pop es
pop ds
popad
iretd
This code matches the tutorial at
http://www.osdever.net/tutorials/multit ... ?the_id=84 (and the link posted by Beyond Infinity, it's author
) almost identically. The macros used within this tutorial have comments
, specifically:
Code:
%macro REG_SAVE 0
;save all registers in the kernel-level stack of the process and switch to the kernel stack
cld
pushad
push ds
push es
push fs
push gs
mov eax,[p] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
lea eax,[kstackend] ; switch to the kernel's own stack.
mov esp,eax
%endmacro
Unless my wits have completely failed me, this tutorial assumes a CPL=3 stack per task, a CPL=0 stack per task and a CPL=0 stack that's shared by all tasks. This is (IMHO) quite unusual, but explains a lot about previous discussion - my response to this was:
Brendan wrote:
I not sure I completely understand what the code is meant to do (hint: comments are good). For example, what are [p] and [kstackend], and what's at [sys_tss+4]?
The name [kstackend] makes me wonder if it's the "kernel stack top" and if you're intending to have a single kernel stack that's shared by all tasks (which may be reasonable, unless it's a monolithic kernel or you might want to support multiple CPUs one day). Even if you are intending to use a single kernel stack for all tasks, that isn't the way to do it (you need the data that is pushed on the stack to return to the task and it must not be overwritten, and you wouldn't need to reset ESP0 in the TSS).
Due to the missing comments I was guessing, and assumed it may be for an OS that uses a CPL=3 stack per task and a CPL=0 stack that's shared by all tasks (without the additional CPL=0 stack per task, which I still find "unusual").
Earlier, GLneo posted the following code:
GLneo wrote:
Code:
push everything
mov esp, [kernel_esp]
pop everything; all kernels data
call task_switcher
push everything; kernels data
mov esp, [new_esp]
pop everthing
iret
This version doesn't match any tutorial that I've been able to find, but (based on guess-work alone), I'm wondering if it originated from something that has a CPL=3 stack per task and a CPL=0 stack shared by all tasks (similar to the first tutorial, but without the additional CPL=0 stack per task that I found unusual). I could be completely wrong though...
The advice I've been giving is for an OS that uses a CPL=3 stack per task and a CPL=0 stack per task, where no stack is ever shared. This is the same as what my OS uses, roughly similar to what Linux uses (I don't want to confuse things more by discussing the more recent "4 KB kernel stack" patch/option), the same as Solaris (IIRC), is very similar to what Intel's hardware task switching does, and is IMHO far more common.
As far as I can tell, GLneo has been relying on several different sources of information that are all based on radically different kernel stack handling methods - it's no wonder it's so confusing!
@GLneo: Now that I think I understand where half of the confusion is coming from, I (and the rest of the people trying to help) will hopefully be able to give better advice. Before this can happen you'd need to choose how you want your OS to handle the kernel stack/s and let us know. Also, do you understand the consequences of each different method of kernel stack handling?
@Colonel Kernel: Coincidence?
Cheers,
Brendan