Changing data segment

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
Viperidae
Posts: 10
Joined: Sun Sep 02, 2012 7:00 pm

Changing data segment

Post by Viperidae »

Hello, I am developing a 32 bit OS and have developed a working ELF loader that works just fine. Now I do not have paging enabled (I plan to later, but right now I am just trying to load kernel modules) and I am trying to execute modules at boot. Basically since again at this time multitasking is not fully implemented I just want to load each module, call init (which will install interrupt handlers and just set up what ever the module is for) and then exit and execute the next one. It works, but I can not do anything with pointers in the C program (because it still thinks it is using the kernels data segment). So basically what I want to do is make a new data segment that points to the modules .data segment in RAM. I am doing this by setting entry number 6 in the GDT like.

Code: Select all

setGDTEntry(6, DataAddress,DataSize, 0xF2, 0xCF);
The setEntry method works just fine, it looks like

Code: Select all

void setGDTEntry(int num, uint Base, uint limit, byte access, byte gran)
Again both work 100%, the problem that I am having occurs when I change the data segment selector. I am doing this in assembly, the ELFs entry point is stored in EAX.

Code: Select all

mov ax, 30h ; This is 8 * 6, the GDT entry containing the new data segment
mov ds, ax ; set data segment
call address ; JUMP!!!!
mov ax, 0xF ; Restore kernel data segment
mov ds, ax ; set data segment
This will cause my kernel to panic, giving CPU exception 0x6, invalid opcode. The source code for my C Program is just a hello world program that copies text into video RAM (nothing much to see.). Does anyone know what I am doing wrong? I am new to the whole concept of the GDT and segment selectors.......... And I can not have paging or multitasking enabled at this time, I really do not feel like explaining why....
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Changing data segment

Post by bluemoon »

Code: Select all

mov ax, 0xF ; Restore kernel data segment
mov ds, ax ; set data segment
This refer to 8-th descriptor (or 1-st in normal sense), with bit[2]: LDT, and bit[1:0]: user mode.
Are you sure that was intended?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Changing data segment

Post by Brendan »

Hi,

If the module's data needs to be in a different segment, then it's likely that your module's code also needs to be in a different segment and that "call address" needs to be a far call (that changes CS) and not just a near call (which doesn't).

Also, if you're using ELF because that's what your C compiler/linker prefers, then it's extremely likely that the code generated by that compiler assumes that CS, DS, ES and SS all refer to the same area of memory and can be used interchangeably. Basically you need to also load ES and SS (which implies switching to a different stack, possibly including copying parameters from the old stack to the new stack).

Note that for a monolithic kernel that uses ELF, the most natural way of supporting modules is to use dynamic linking. Dynamic linking is a little more complicated, but it's also much faster because it avoids all those slow segment register loads (and it is supported by compilers).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Viperidae
Posts: 10
Joined: Sun Sep 02, 2012 7:00 pm

Re: Changing data segment

Post by Viperidae »

bluemoon wrote:

Code: Select all

mov ax, 0xF ; Restore kernel data segment
mov ds, ax ; set data segment
This refer to 8-th descriptor (or 1-st in normal sense), with bit[2]: LDT, and bit[1:0]: user mode.
Are you sure that was intended?
Oh lol. No it wasn't, I was thing of 16 (0x10) and IDK but I didnt feel like opening the source code for that and for some reason I typed 0xF instead of 0x10
Post Reply