Stack problem
Posted: Sat Aug 11, 2007 11:59 am
I'm writing freestanding code for my OS experiment, and i have a problem that i cannot resolve.
Initialy I had kernel stack segment selector same as data segment, and now Im trying to separate it.
The boot plan is the folowing:
1. boot sector is loading some amount of sectors from disk which are the loader code
2. loader code switches to protected mode and have functions to access full memory, DMA etc. It operates with 2 selectors at all (code and data).
3. loader code loads the main kernel, with no space limitations.
I had allocated new selector in gdt and trying to set stack before entering the BIG kernel with the folowing code(AT&T asm syntax):
void k_setup_stack(void *ret_address)
{
k_pmode_gdt_init();
asm("
cli
mov %%edx,%%esp
mov %%edx,%%ebp
mov %%ax,%%ss
ljmp $8,$nxt
nop
nxt:
mov %%ax,%%ss // another try
mov %%edx,%%esp
mov %%edx,%%ebp
sti
// trying to push
push %%eax
push %%eax
push %%eax
push %%eax
s: jmp s //////////////////////////////////////////////////////////////////
ret
:
: "a"(KERNEL_STACK_SELECTOR),
"d"(KERNEL_STACK_SIZE),
"c"(ret_address)
);
k_panic("stop");
}
, but the CPU behavior is some kind bogus.
The results I have at point "s: jmp s".
Bochs cpu dump:
eax:0x0010000f, ebx:0x00000000, ecx:0x0010000f, edx:0x00001000
ebp:0x00001000, esp:0x00000ff0, esi:0x00007c52, edi:0x0000ffde
eip:0x00100c52, eflags:0x00000202, inhibit_mask:0
cs:s=0x0008, dl=0x0000ffff, dh=0x00cf9a00, valid=1
ss:s=0x0018, dl=0x40001000, dh=0x00c09312, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9200, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
fs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
gs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00121000, limit=0x3f
idtr:base=0x00120000, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000011, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
Stack values:
<bochs:3> print-stack
Stack address size 4
| STACK 0x00000ff0 [0x00000000]
| STACK 0x00000ff4 [0x00000000]
| STACK 0x00000ff8 [0x00000000]
| STACK 0x00000ffc [0x00000000]
| STACK 0x00001000 [0x000003e9]
| STACK 0x00001004 [0x01b40001]
| STACK 0x00001008 [0x10cd20b5]
| STACK 0x0000100c [0xa27c03a0]
| STACK 0x00001010 [0x010f1003]
| STACK 0x00001014 [0xe4107716]
| STACK 0x00001018 [0xe6020c92]
| STACK 0x0000101c [0xc0200f92]
| STACK 0x00001020 [0x220f010c]
| STACK 0x00001024 [0x102aeac0]
| STACK 0x00001028 [0x66fa0008]
| STACK 0x0000102c [0x8e0010b8]
<bochs:4>
there are zeroes in the stack which resulted by my pushes... I cannot undestand what is going wrong. This is the main question.
And the other question is about the whole idea in general. I see no limitations from C compiler of having separate stack segment to run stack safely. Windows puts stacks after disabled memory page but in that case you have a page fault, in which the CPU pushes error code to the stack, so double fault is triggered (etc) and cpu reboots.
I will be very gratefull of help.
Initialy I had kernel stack segment selector same as data segment, and now Im trying to separate it.
The boot plan is the folowing:
1. boot sector is loading some amount of sectors from disk which are the loader code
2. loader code switches to protected mode and have functions to access full memory, DMA etc. It operates with 2 selectors at all (code and data).
3. loader code loads the main kernel, with no space limitations.
I had allocated new selector in gdt and trying to set stack before entering the BIG kernel with the folowing code(AT&T asm syntax):
void k_setup_stack(void *ret_address)
{
k_pmode_gdt_init();
asm("
cli
mov %%edx,%%esp
mov %%edx,%%ebp
mov %%ax,%%ss
ljmp $8,$nxt
nop
nxt:
mov %%ax,%%ss // another try
mov %%edx,%%esp
mov %%edx,%%ebp
sti
// trying to push
push %%eax
push %%eax
push %%eax
push %%eax
s: jmp s //////////////////////////////////////////////////////////////////
ret
:
: "a"(KERNEL_STACK_SELECTOR),
"d"(KERNEL_STACK_SIZE),
"c"(ret_address)
);
k_panic("stop");
}
, but the CPU behavior is some kind bogus.
The results I have at point "s: jmp s".
Bochs cpu dump:
eax:0x0010000f, ebx:0x00000000, ecx:0x0010000f, edx:0x00001000
ebp:0x00001000, esp:0x00000ff0, esi:0x00007c52, edi:0x0000ffde
eip:0x00100c52, eflags:0x00000202, inhibit_mask:0
cs:s=0x0008, dl=0x0000ffff, dh=0x00cf9a00, valid=1
ss:s=0x0018, dl=0x40001000, dh=0x00c09312, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9200, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
fs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
gs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00121000, limit=0x3f
idtr:base=0x00120000, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000011, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
Stack values:
<bochs:3> print-stack
Stack address size 4
| STACK 0x00000ff0 [0x00000000]
| STACK 0x00000ff4 [0x00000000]
| STACK 0x00000ff8 [0x00000000]
| STACK 0x00000ffc [0x00000000]
| STACK 0x00001000 [0x000003e9]
| STACK 0x00001004 [0x01b40001]
| STACK 0x00001008 [0x10cd20b5]
| STACK 0x0000100c [0xa27c03a0]
| STACK 0x00001010 [0x010f1003]
| STACK 0x00001014 [0xe4107716]
| STACK 0x00001018 [0xe6020c92]
| STACK 0x0000101c [0xc0200f92]
| STACK 0x00001020 [0x220f010c]
| STACK 0x00001024 [0x102aeac0]
| STACK 0x00001028 [0x66fa0008]
| STACK 0x0000102c [0x8e0010b8]
<bochs:4>
there are zeroes in the stack which resulted by my pushes... I cannot undestand what is going wrong. This is the main question.
And the other question is about the whole idea in general. I see no limitations from C compiler of having separate stack segment to run stack safely. Windows puts stacks after disabled memory page but in that case you have a page fault, in which the CPU pushes error code to the stack, so double fault is triggered (etc) and cpu reboots.
I will be very gratefull of help.