OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 2:02 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Strange memory segment behavior
PostPosted: Tue Aug 28, 2018 3:31 am 
Offline
Member
Member

Joined: Mon Jun 04, 2018 8:10 am
Posts: 44
Hello,
I am currently trying to develop a small OS with the help of a tutorial but I ran into something that looks strange and that I don't understand. This is related with memory segments.

This is how my Global Descriptor Table is setup:

Code:
void init_gdt() {

   gdt_ptr.base = (u32)&gdt_entries;
   gdt_ptr.limit = sizeof(gdt_entry_t) * GDT_SIZE - 1;

   gdt_entries[0] = create_gdt_entry(0, 0, 0, 0); // 0x00

   gdt_entries[1] = create_gdt_entry(0, 0xffffffff, 0x98, 0xc0); // code segment 0x08
   gdt_entries[2] = create_gdt_entry(0, 0xffffffff, 0x92, 0xc0); // data segment 0x10
   gdt_entries[3] = create_gdt_entry(0x00, 0x00, 0x96, 0xc0);   // kernel stack 0x18

   gdt_entries[4] = create_gdt_entry(0x30000, 0x0, 0xf8, 0xc0); // user code segment 0x20 / 0x23
   gdt_entries[5] = create_gdt_entry(0x30000, 0x0, 0xf2, 0xc0); // user data segment 0x28 / 0x2B
   gdt_entries[6] = create_gdt_entry(0x00, 0x20, 0xf6, 0xc0); // user stack 0x30 / 0x33

   load_gdt((u32)&gdt_ptr);

   print_ok();
   print("New GDT loaded\n");

}

gdt_entry_t create_gdt_entry(const u32 base, const u32 limit, const u8 access, const u8 gran) {

   return (gdt_entry_t) {

      .base_low       = (base & 0xffff),
      .base_middle    = (base >> 16) & 0xff,
      .base_high       = (base >> 24) & 0xff,

      .limit_low       = limit & 0xffff,
      .granularity    = (gran & 0xf0) | ((limit >> 16) & 0x0f),

      .access       = access

   };

}


Code:

[bits 32]
[GLOBAL load_gdt]

load_gdt:
   mov eax, [esp + 4]    ; get pointer passed by stack
   lgdt [eax]         ; load the gdt pointer

   mov ax, 0x10      ; offset in gdt for data segment
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   mov ax, 0x18      ; ...
   mov ss, ax

   jmp 0x08:flush      ; load code segment (0x08 is offset to code segment)

flush:
   ret


The user code and data segment (0x20 and 0x28) are supposed to start at memory address 0x30000 and end 4kiB further which is address 0x31000.
I am therefore not supposed to be able to access memory above 0x31000 in my user code, but here is my user code:

Code:
void task() {

   char *vid = (char *)0x88000; // 0xb8000 - 0x30000
   *vid = 'f';

   while(1);

}


What I found strange and don't understand is that I don't get any error by executing this code and that it actually writes an 'f' in the top left corner of the screen. How is this possible since I am not supposed to be able to access memory above 0x31000?
I would be pleased if anyone had an answer.
Regards


Top
 Profile  
 
 Post subject: Re: Strange memory segment behavior
PostPosted: Tue Aug 28, 2018 4:18 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Are you sure that you are in user mode? Without seeing your full code (link to an online repository, please, don't post all code here) we can't see how you have entered user mode and be sure that CS and DS have the appropriate values.

You can, of course, test these things for yourself. Run under a debugger with a breakpoint at the start of your user function and check all the appropriate register and memory values.


Top
 Profile  
 
 Post subject: Re: Strange memory segment behavior
PostPosted: Tue Aug 28, 2018 6:36 am 
Offline
Member
Member

Joined: Mon Jun 04, 2018 8:10 am
Posts: 44
Thank you for your reply and sorry for posting all the code here.

Here is a link to a repository with all the code: https://github.com/leonard-limon/osdev/

I am quite sure that I am in user mode and that CS and DS have the correct values but I will indeed check theses things with a debugger.


Top
 Profile  
 
 Post subject: Re: Strange memory segment behavior
PostPosted: Thu Aug 30, 2018 1:36 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 693
My best guess is that whatever environment you are running in is likely emulated and to speed things up they dropped the segment limit check. If you are using QEMU try using the -enable-kvm option and see what happens. The QEMU documentation says this:
Quote:
The x86 segment limits and access rights are not tested at every memory access (yet). Hopefully, very few OSes seem to rely on that for normal use.


Top
 Profile  
 
 Post subject: [Solved] Re: Strange memory segment behavior
PostPosted: Sat Sep 01, 2018 3:47 am 
Offline
Member
Member

Joined: Mon Jun 04, 2018 8:10 am
Posts: 44
Ok, it looks that the emulator is what's causing this strange behavior.
Thanks for your reply


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 106 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group