problem in linking the kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:problem in linking the kernel

Post by Pype.Clicker »

it certainly means that you're trying to execute code on an invalid memory address (for instance, physical memory that doesn't exist).

check out that your GDT base is correct, and that you load GDTR correctly aswell ... don't forget to perform translations required if your data segment isn't 0-based or if paging is enabled ...
adeelmahmood1

Re:problem in linking the kernel

Post by adeelmahmood1 »

what do u mean by my data segment being 0 based. well that can be the problem in my code .. can u explain this thing.. why do we need a 0 based data segment and how we can make our data seg,ment 0 based.
thanx
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:problem in linking the kernel

Post by Pype.Clicker »

I mean the base field (both base_lo, base_me and base_hi) in your previous GDT for your datasegment is 0.

If this is not the case (for instance, because you want your code to be loaded @1MB but have logical address starting at "0" so that you could load it anywhere else by just modifying the loader that builds the GDT), then it means that when you issue

Code: Select all

mov [0x1234],al
the physical memory byte addressed is indeed offset + ds.base == 0x00001234 + 0x00100000 = 0x00101234.
The compiler don't care as long as ds.base == ss.base (?== cs.base), but *you* should care as soon as you try to fill a system register with an address the C compiler created.

so

Code: Select all

struct pageEntry KernelPageDirectory[1024];
 asm("mov %0,%%CR3"::"g"(KernelPageDirectory));
will not work because the compiler will fill your register with &KernelPageDirectory, which is just an offset in DS ... the correct code would be

Code: Select all

#define DS_BASE 0x100000
#define logical2physical(x) (((void*)x)+DS_BASE)
struct pageEntry KernelPageDirectory[1024];
 asm("mov %0,%%CR3"::"g"(logical2physical(KernelPageDirectory)));
note, i don't even know what your GDT looks like and that's what i asked everybody to fill in a OSID card :)
slacker

Re:problem in linking the kernel

Post by slacker »

Tim Robinson wrote: Better:

Code: Select all

dw Address >> 16  ; High word
dw Address & 0FFFFh   ; Low word
However, you can't use >> and & on expressions (such as Address) that the assembler itself can't resolve. This includes symbols that are defined in other files.
if this code wont work on the address of a certain ISR, what will work so that i could obtain the high word and low word of an ISR address??
adeelmahmood1

Re:problem in linking the kernel

Post by adeelmahmood1 »

i tried to attach the gdt file but there was some problem so i m pasting the code in here
asm GDT

Code: Select all

gdt:
; NULL descriptor
   dw 0
   dw 0
   db 0
   db 0
   db 0
   db 0

[global CODE_SEL]
CODE_SEL   equ $ - gdt
   dw 0FFFFh
   dw 0
   db 0
   db 9Ah   ; present,ring 0,code,non-conforming,readable
   db 0CFh   ; page-granular (4 gig limit), 32-bit
   db 0
[global DATA_SEL]
DATA_SEL   equ $ - gdt
   dw 0FFFFh
   dw 0
   db 0
   db 92h   ; present, ring 0, data, expand-up, writable
   db 0CFh   ; page-granular (4 gig limit), 32-bit
   db 0

gdt_end: 

gdt_ptr:
   dw gdt_end - gdt - 1
   dd gdt
C GDT

Code: Select all

DESCR_SEG gdt[5];      /* GDT */
GDTR gdtr;            /* GDTR */


void setup_GDT_entry (DESCR_SEG *item,
                      dword base, dword limit, byte access, byte attribs) {
  item->base_l = base & 0xFFFF;
  item->base_m = (base >> 16) & 0xFF;
  item->base_h = base >> 24;
  item->limit = limit & 0xFFFF;
  item->attribs = attribs | ((limit >> 16) & 0x0F);
  item->access = access;
}



void setup_GDT() {
  dword tmp;

  /* 0x00 -- null descriptor */
  setup_GDT_entry (&gdt[0], 0, 0, 0, 0);

  /* 0x08 -- code segment descriptor */
  setup_GDT_entry (&gdt[1], ((dword)_CS)<<4, 0xFFFF, ACS_CODE, 0);

  /* 0x10 -- data segment descriptor */
  setup_GDT_entry (&gdt[2], ((dword)_DS)<<4, 0xFFFF, ACS_DATA, 0);

  /* 0x18 -- stack segment descriptor */
  setup_GDT_entry (&gdt[3], ((dword)_SS)<<4, 0xFFFF, ACS_STACK, 0);

  /* 0x20 -- text video mode segment descriptor */
  setup_GDT_entry (&gdt[4], 0xB8000L, 0xFFFF, ACS_DATA, 0);

  /* setting up the GDTR register */
  gdtr.base = ((dword)_DS)<<4;
  gdtr.base += (word)&gdt;
  gdtr.limit = sizeof(gdt)-1;
  lgdt (&gdtr);
}

/*   
I HAVE DEFINE 
_DS=0x10
_CS=0x08
_SS=0x18
*/
Tim

Re:problem in linking the kernel

Post by Tim »

slacker wrote:if this code wont work on the address of a certain ISR, what will work so that i could obtain the high word and low word of an ISR address??
You need to write code to set the addresses in the IDT at run time. That is, you need to do the bit shifting and masking yourself.
slacker

Re:problem in linking the kernel

Post by slacker »

the bitshifting has to be done in the actual running code instead of the data section?
Tim

Re:problem in linking the kernel

Post by Tim »

Yes.
slacker

Re:problem in linking the kernel

Post by slacker »

would this do it?

Code: Select all

fixaddrs:
call zeroout
MOV EAX, ISR0
MOV [tempaddr], EAX
AND EAX, 0xFFFF
MOV [ISR0L], AX
MOV EAX, [tempaddr]
SHR EAX, 16
MOV [ISR0H], AX

zeroout:
XOR EAX, EAX
MOV [tempaddr], EAX
MOV [temphi], AX
MOV [templow], AX
ret
Tim

Re:problem in linking the kernel

Post by Tim »

This should do it (although add a RET at the end of fixaddrs). It could probably be simplified slightly (remember that AX = EAX & 0FFFFh always), but it should do the job.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:problem in linking the kernel

Post by Pype.Clicker »

you can also replace "[tmpaddr]" by some general register (like ebx, ecx, edx, etc.) so that you're not in need for an extra global variable
Post Reply