problem in linking the kernel
- Pype.Clicker
- 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
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 ...
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 ...
Re:problem in linking the kernel
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
thanx
- Pype.Clicker
- 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
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
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
will not work because the compiler will fill your register with &KernelPageDirectory, which is just an offset in DS ... the correct code would be
note, i don't even know what your GDT looks like and that's what i asked everybody to fill in a OSID card
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 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));
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)));
Re:problem in linking the kernel
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??Tim Robinson wrote: Better: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.Code: Select all
dw Address >> 16 ; High word dw Address & 0FFFFh ; Low word
Re:problem in linking the kernel
i tried to attach the gdt file but there was some problem so i m pasting the code in here
asm GDT
C GDT
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
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
*/
Re:problem in linking the kernel
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 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??
Re:problem in linking the kernel
the bitshifting has to be done in the actual running code instead of the data section?
Re:problem in linking the kernel
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
Re:problem in linking the kernel
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.
- Pype.Clicker
- 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
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