Page 1 of 2
Segmentation memory- question
Posted: Thu Sep 04, 2014 9:52 am
by szarek
Hi,
I have read a chunk of therory about Memory Managment, ( i.a. Operating System, Tanenbaum) but I can't still imagine how it exactly works.
My main problem is that I don't know how to implement it, and what is a role processor in that. I saw the implementation, which simply move the address of our first entry in the GDT to processor register lgdt.
Of course, we initialize our table, but nothing else. I don't know what we should do and what is realise by hardware.
Re: Segmentation memory- question
Posted: Thu Sep 04, 2014 10:21 am
by Combuster
Have you read the reference on
GDT and the corresponding
GDT Tutorial?
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 9:27 am
by szarek
Yes, I read it.
I cant understand why are there "3" base address and "2" limit. Help!
What is selector? And what "generate" him and when.
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 9:36 am
by mallard
Both the base address and limit are (logically) 32-bit numbers. Originally (and still when in real-mode) they were 16-bit numbers and then 24-bit numbers (on the 80286). Each time they extended the addressing, Intel added new fields to the structure to hold the extra bits, rather than define a completely new structure.
Thus, the 32-bit base address is split into one 16-bit field and two 8-bit fields. The limit has one 16-bit number and an additional 4-bit field to make 20 bits. Setting the "Gr" bit of the flags effectively multiplies this 20-bit number by 4096 (the page size) to make a 32-bit number. Note that the limit either has to be page-aligned or less than 1MB.
The selector is just the offset into the GDT that the entry you want starts at. Since the entires are 8 bytes, the selectors are 8 for the first entry (since entry 0 isn't usable), 16 for the second, 24 for the third, etc.
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 9:57 am
by szarek
The selector is just the offset into the GDT that the entry you want starts at. Since the entires are 8 bytes, the selectors are 8 for the first entry (since entry 0 isn't usable), 16 for the second, 24 for the third, etc.
The selector is given by processor to my handlers for GDT, isn't it?
Thus, the 32-bit base address is split into one 16-bit field and two 8-bit fields. The limit has one 16-bit number and an additional 4-bit field to make 20 bits. Setting the "Gr" bit of the flags effectively multiplies this 20-bit number by 4096 (the page size) to make a 32-bit number. Note that the limit either has to be page-aligned or less than 1MB.
Ok, we will assume that we set up "Gr" bit. Now the limit is 32-bit. Thus, where are access byte?
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 1:56 pm
by alexfru
RTFMing is a prerequisite for understanding and working in x86 protected mode. Looks like there hasn't been much if any of it.
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 5:03 pm
by szarek
ok, I read some article about it.
So, I have another question now.
I one tutorial about GDT the code initializing GDT is following:
Code: Select all
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
I do not understand why all the segments have the same base address and limit.
After all, they will override each other.
Re: Segmentation memory- question
Posted: Fri Sep 05, 2014 8:43 pm
by alexfru
That's the whole point, to have all the segments wide open, not bother manipulating them, pretend they don't exist and use everywhere (except interrupt and exception handlers and a couple of places in the boot loader and the kernel) 32-bit or 64-bit offsets. I'm sure there are many articles stating exactly what I said. Are you going to read up or ask every little question first?
Re: Segmentation memory- question
Posted: Sat Sep 06, 2014 3:31 am
by Brendan
Hi,
szarek wrote:I do not understand why all the segments have the same base address and limit.
After all, they will override each other.
Let's start from the start!
For 80x86 there's 2 different things: segmentation and paging. Both can be used for isolating/protecting processes from each other, but they work in very different ways and have different advantages/disadvantages.
The advantages of segmentation are that it uses 4 privilege levels, can give you "byte granular" protection, and can be used for protecting a process from itself (e.g. a process can have many segments). However; very few OSs have a reason to use more than 2 privilege levels; in practice, for the segment's base address "byte granular" protection isn't very useful due to alignment requirements (you'd want to align the base address to the start of a cache line) and the segment's limit is only "byte granular" if the segment is 64 KiB or less (for larger segments you have "4 KiB granular"); and very few people care about protecting a process from itself and no modern tools (e.g. compilers, linkers, etc) support that anyway.
The disadvantages of segmentation are that it's not portable (unlike paging, few other CPUs support anything like it, including 80x86 itself when running 64-bit code); it does nothing to solve physical memory fragmentation problems (which makes it slow); and the GDT/LDT table lookups and protection checks involved in segment register loads makes it even slower.
The advantage of paging is that it's extremely flexible - it solves the physical memory management fragmentation problem and allows for a large number of tricks (like allocation on demand, copy on write, swap space, memory mapped files, etc) to be implemented easily and efficiently. The disadvantages are that there's a little overhead caused by TLB misses and page table management (but it's far less than segmentation) and it costs a little RAM for page tables (but due to the "tricks" I mentioned, it typically saves far more RAM than it costs).
Now; you actually have 4 choices:
- Don't use segmentation or paging. This is mostly a bad idea because you can't do anything (including not being able to protect processes from each other or protect the kernel from processes) and can't get any of the other benefits of segmentation or paging. Despite this, it might be suitable for some rare cases - e.g. maybe game consoles (where you don't care about protection/isolation because everything is on read-only media and only one game is run at a time), and small embedded systems; although for both these cases it can be argued that the processes are "bootable applications" (where the "kernel" is more like a shared library than a kernel) and that it isn't an OS at all.
- Use segmentation alone. This is mostly a bad idea because segmentation is slow and makes it hard to implement many important "tricks".
- Use paging alone. This is what almost all modern OSs do.
- Use segmentation and paging at the same time. This gives you the advantages of both, while also giving you the overhead of both. However, you don't really get any useful advantages from segmentation unless you're attempting to protect a process from itself (e.g. detect bugs like dodgy pointers, etc), and there are far better ways to either debug processes that may have these bugs (e.g. tools like valgrind) or prevent these types of bugs from being possible (e.g. managed languages); which means that it's extremely hard to justify the additional overhead (and complexity).
Of course if you want to use paging alone (and don't want to use segmentation at all), then you'll find that there's no way to disable segmentation for 80x86 protected mode. Instead of disabling it, you'd set segments up so that they effectively do nothing - e.g. "base = 0, limit = 4 GiB". This is what almost all OSs designed for 80x86 protected mode do; and it's also what the "tutorial about GDT the code" you were reading does.
Cheers,
Brendan
Re: Segmentation memory- question
Posted: Sat Sep 06, 2014 9:15 am
by Gigasoft
szarek wrote:ok, I read some article about it.
The M in RTFM does not stand for "article".
Re: Segmentation memory- question
Posted: Sat Sep 06, 2014 4:03 pm
by szarek
Ok, thanks a lot
but... I hava a little quesiont
I'm handling interrputed with IDT.
Assume, that I have a function handling a interrupt caused by 'divide by zero':
void handle_divide_by_zero(){
put "Divide by zero!";
}
How should I handle this, so that the kernel can continue to operate.
Now it is so that if the division by zero will arrange it comes to looping and continuous display: "Divide by zero!"
Re: Segmentation memory- question
Posted: Sat Sep 06, 2014 4:19 pm
by Brendan
Hi,
szarek wrote:Assume, that I have a function handling a interrupt caused by 'divide by zero':
void handle_divide_by_zero(){
put "Divide by zero!";
}
How should I handle this, so that the kernel can continue to operate.
Now it is so that if the division by zero will arrange it comes to looping and continuous display: "Divide by zero!"
Determine what caused the division by zero (e.g. kernel or a process). If it was caused by the kernel, do a "kernel panic" (e.g. display details) and HLT all the CPUs (wait for user to reset the computer). If it was caused by a process, then either terminate that process, or (if you're doing the hideous "POSIX-ish" thing") send a "SIGFPE" signal back to the process (which means you return to the process' signal handler and don't return the instruction that caused the problem).
Cheers,
Brendan
Re: Segmentation memory- question
Posted: Sat Sep 06, 2014 4:43 pm
by szarek
thanks
Re: Segmentation memory- question
Posted: Sun Sep 07, 2014 7:26 am
by szarek
and the next very little question
:
http://wiki.osdev.org/PIC
What are these address, for example: 0x0020
I know that is I/O port, but I'd like to know where this address is placed.Is it the place in memory or something else?
Re: Segmentation memory- question
Posted: Sun Sep 07, 2014 9:41 am
by Brendan
HI,
szarek wrote:and the next very little question
:
http://wiki.osdev.org/PIC
What are these address, for example: 0x0020
I know that is I/O port, but I'd like to know where this address is placed.Is it the place in memory or something else?
The CPU has 2 different "spaces". The main one is the physical address space, that you use with normal instructions to (either directly or indirectly) read from and write to addresses that correspond to RAM, ROM, memory mapped devices, etc.
The second one is "IO port space". To access an address in IO port space you need to use special instructions (e.g. "in", "out", etc). For example, you might use "in al,0x20" to read the byte at "IO port space address 0x20" into AL. Of course most people would just say "read IO port 0x0020". This is similar to "mov al,[0x0020]" but not the same - "mov al,[0x0020]" would read the byte from the right address in the wrong space.
Cheers,
Brendan