Page 2 of 2

Re:questions on high half kernel

Posted: Fri May 12, 2006 12:40 pm
by asmboozer
okay, I have tested without directory of index 0 paged.

boches tells me
00018588554e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00018588554i[CPU0 ] protected mode
00018588554i[CPU0 ] CS.d_b = 32 bit
00018588554i[CPU0 ] SS.d_b = 32 bit
00018588554i[CPU0 ] | EAX=80000011 EBX=0002bdc0 ECX=00000001 EDX=000003ff
00018588554i[CPU0 ] | ESP=c0104ff8 EBP=c0105008 ESI=0002beda EDI=0002bedb
00018588554i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00018588554i[CPU0 ] | SEG selector base limit G D
00018588554i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00018588554i[CPU0 ] | CS:0008( 0001| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | DS:0010( 0002| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | SS:0010( 0002| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | ES:0010( 0002| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | FS:0010( 0002| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | GS:0010( 0002| 0| 0) 40000000 000fffff 1 1
00018588554i[CPU0 ] | EIP=c01000a8 (c01000a8)
00018588554i[CPU0 ] | CR0=0x80000011 CR1=0 CR2=0x00000040
00018588554i[CPU0 ] | CR3=0x00102000 CR4=0x00000000
00018588554i[CPU0 ] (instruction unavailable) page not present
00018588554i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00018588554i[APIC0] local apic in CPU 0 initializing
the EIP is just pointed at

Code: Select all

c01000a2:       8b 45 f4                mov    0xfffffff4(%ebp),%eax
c01000a5:       0f 22 d8                mov    %eax,%cr3
c01000a8:       0f 20 c0                mov    %cr0,%eax
c01000ab:       0d 00 00 00 80          or     $0x80000000,%eax
c01000b0:       0f 22 c0                mov    %eax,%cr0
c01000b3:       c9                      leave  
c01000b4:       c3                      ret    
last, i know why there needs set the 0 page dir a proper address.

it's because, gdt_install is called after init_paging(),while gdt is in section .setup.


thanks all your help.

Re:questions on high half kernel

Posted: Fri May 12, 2006 12:43 pm
by asmboozer
another question,

if out_format is binary, can it work?

Re:questions on high half kernel

Posted: Sun May 14, 2006 8:33 am
by JAAman
<<<<<<<<<<<<< it jumps here before paging enabled. >>>>>>>>>>>>>>>>>
im sorry but it appears that you really dont understand the difference between logical, linear, and physical addresses

that code is jumping to a higher logical address -- which the GDT is mapping lower, you appear to be at the higher half, but you really are not (since the term 'higher half' usually implies high linear address -- i guess its possible to use only higher logical (and lower linear), but then you would need only the bottom mapping in the page tables, not the upper mapping, as you stated)
if I do not misunderstand your statement.

as i know, the grub doesn't set paging enabled.

and from the source code, I don't know paging is enabled before
you cannot be in the higher half before paging is enabled, i did not mean that paging is enabled at that point, i ment that you are not yet at the higher half after this code is run -- you appear to be in higher half, but are acctually still in the lower half -- until you remap the GDT back to a zero base, you are in the lower half (and you cant do that until you have enabled paging)



sorry if i am going over code you arnt having trouble with, but you asked why you needed to map both the lower and higher addresses, and i believe this is an important issue that you dont appear to understand (unless im not understanding your responses)

Re:questions on high half kernel

Posted: Sun May 14, 2006 11:10 am
by mystran
I've been thinking of implementing the following (rather trivial) trick:

Put kernel segments' base address at 0. Kernel lives in lower half.

Put user segments' base address at 2GB. Userspace thinks it lives in the lower half, even if it really lives in higher half.

Now both can think they are living in lower half, and refer to the other part as high-half.

For extra pleasure, never cast addresses from userspace into pointer types in kernel, but use a macro like:

Code: Select all

#define UserPtrCast(p,t) ((t)(p+0x80000000))
Then forget how UserPtrCast works, and you can search your sources for userspace pointer use, if you think you might have forgot to validate one. Wee....

Ofcourse in C++ you could make the above into a static inline template function which does validation for you.

Code: Select all

static const int BORDER = 0x80000000; // 2GB split
template <class T>
static inline T * UserPtr(unsigned long p) {
  if(p < BORDER) {
    return (T*) (p+BORDER);
  } else throw InvalidUserPointer();
}
Ofcourse for more safety one could build a pointer wrapper that reads virtual memory tables and does temporary mappings automatically (so you can dereference it from any context), and checks actually addresses for access, catching page faults and such, but that'd be a bit perverse.

Ofcourse none of this has anything to do with relocating kernel, which I am not going to bother with any time soon.

Re:questions on high half kernel

Posted: Sun May 14, 2006 5:04 pm
by Ryu
mystran wrote: Put user segments' base address at 2GB. Userspace thinks it lives in the lower half, even if it really lives in higher half.
Hmm, that is confusing, they really should be living in the the lower half of linear address. Being lower half said and 2GB, this is IA-32 with no PAE.