Newbie needing clarification.

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.
Post Reply
calpol
Posts: 5
Joined: Sun Aug 26, 2007 10:15 am

Newbie needing clarification.

Post by calpol »

Up until now i'd been building a 16bit realmode OS which was nice and simple and didn't really pose a challenge at all, just make a simple command parser for a shell and let BIOS interrupts do all the work. I've now decided to get into the *good* stuff and do something that isn't so monotanous. So I've been trying to get into 32bit programming and leave those nice easy BIOS interrupts behind and do something relatively challenging .

But alas it's too challenging and i need some help getting a understanding of how this mess of gdt's, idt's, isr's and irqs work. I'd appreciate it if you could maybe scan through my questions and perhaps shed some light on my confusion.

GDT - okay all i know is that it has something to do with paging (one of the bits enables it, or at least allows it) and you need one for protected mode. I'm guessing from this i can create new entries and each entry would be protected from the next? can someone give a blunt explanation of it's uses?

ISR's - Interrupt service routines are the routines that get called when someone tries to divide by 0 or something else wrong right? and you need to make loads of structures of idt entries to map them to an ISR routine right? I really could do with some examples.

IRQS - from what i've read these are channels you can use to interact with hardware where most of them are reserved and isn't really necessary but somehow better than just using "out" instructions, right? I've been trying to make a 32bit routine for getting input via the keyboard and apparently this is the best (or only) way to go about it, as apparently channel 1 (the keyboard channel) fires an interrupt whenever a key is pressed and is my cue to read from from port 64 (or 60??) to fetch the letter. Have i got the idea? does someone have any examples?

64bit mode - other than having 64bit registers and some extra instructions apparently you can only use paging and you can't use "hardware multitasking", is hardware mulitasking the tss? (whats the tss btw? something to do with gdt?) and how would i go about making software mulititasking? obviously i'd do everything in 32bit first and then possibly port it to 64bit, i'd just dont want to build a hardware task switcher and then spend weeks rebuilding a software one if you get my drift. I've yet to read through AMD's docs though, although i'd appreciate it if you could shed some light as intels and amd's docs aren't that good at explaining things.

Stack - i've spent the last 2 hours constantly changing where and how big my stack is, i don't know how big a stack can get (i'd imagine about 200 bytes tops right?) but i've currently got it situated under my kernel at 0x7E00 and the kernel starts at 0x10000, i should think thats enough room? and is under the kernel a good idea? I'm very fussy and don't like wasting memory or being inefficient (done everything in assembly so far, i'd hate to use C :p).

I'd very much appreciate some guidance from you no matter how short or small, feel free to bombard me with links to random pages and as i really am struggling to find out how these things work.
Last edited by calpol on Tue Aug 28, 2007 5:12 pm, edited 1 time in total.
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

You should read Bran's tutorial, which GLNeo posted, but here is brief clarification.
GDT - okay all i know is that it has something to do with paging (one of the bits enables it, or at least allows it) and you need one for protected mode. I'm guessing from this i can create new entries and each entry would be protected from the next? can someone give a blunt explanation of it's uses?
You're confusing the GDT (global descriptor table) and CR0 (control register zero). CR0 has bits that enable paging and protected mode. The GDT has nothing to do with paging. It describes the setup for the alternate memory management system - segmentation. Segmentation as a memory management technology is now outdated, people use paging only instead. However, it also contains bits that select what ring (supervisor/user) code can run in. So you still need to use it.
ISR's - Interrupt service routines are the routines that get called when someone tries to divide by 0 or something else wrong right? and you need to make loads of structures of idt entries to map them to an ISR routine right? I really could do with some examples.
Yes, interrupt service routines are routines (functions) that get called whenever an interrupt occurs. That interrupt can be via software (the 'int n' instruction), a trap/fault (div/0, GPF etc), or externally, via an IRQ...
IRQS - from what i've read these are channels you can use to interact with hardware where most of them are reserved and isn't really necessary but somehow better than just using "out" instructions, right? I've been trying to make a 32bit routine for getting input via the keyboard and apparently this is the best (or only) way to go about it, as apparently channel 1 (the keyboard channel) fires an interrupt whenever a key is pressed and is my cue to read from from port 64 (or 60??) to fetch the letter. Have i got the idea? does someone have any examples?
Hmm, slightly mixed up. IRQ stands for Interrupt ReQuest. Devices, when they want to signal something (note SIGNAL, not SEND/RECIEVE data - nothing can be sent/recieved via an IRQ), can raise an IRQ. This essentially is just a binary signal sent to the interrupt controller chip (PIC) which forwards it to the CPU. The CPU recieves it in the form of an interrupt, just as if the 'int n' instruction were used. It jumps into an interrupt handler, and the handler can, for example, send/recieve data (as in the keyboard, for example). It is not a replacement for the out instruction, it just lets hardware tell the cpu when it's ready to do something.
64bit mode - other than having 64bit registers and some extra instructions apparently you can only use paging and you can't use "hardware multitasking", is hardware mulitasking the tss? (whats the tss btw? something to do with gdt?) and how would i go about making software mulititasking? obviously i'd do everything in 32bit first and then possibly port it to 64bit, i'd just dont want to build a hardware task switcher and then spend weeks rebuilding a software one if you get my drift. I've yet to read through AMD's docs though, although i'd appreciate it if you could shed some light as intels and amd's docs aren't that good at explaining things.
Ye, hardware multitasking involves the TSS. Well, all multitasking involves the TSS, but hardware involves it to a greater extent. The TSS is the Task State Segment. It is a special entry in the GDT that describes a task. It has fields for all the general purpose registers (eax,ebx, blah blah), and for kernel and user stack pointers. Hardware multitasking involves telling the CPU you want to change tasks (not exactly sure of the implementation, I've never done it myself), and it changing between TSSs for you. In software multitasking, you use the TSS only to store the kernel stack pointer. This is automatically fetched from the current TSS when a ring-switch occurs (interrupt from user mode, for example). This functionality is inbuilt into the x86 architecture and still works on x86-64.
Stack - i've spent the last 2 hours constantly changing where and how big my stack is, i don't know how big a stack can get (i'd imagine about 200 bytes tops right?) but i've currently got it situated under my kernel at 0x7E00 and the kernel starts at 0x10000, i should think thats enough room? and is under the kernel a good idea? I'm very fussy and don't like wasting memory or being inefficient (done everything in assembly so far, i'd hate to use C :p).
Stacks can be as big as you like. For example if you were transferring data in a C program:

Code: Select all

unsigned char buf[1024];
read(&buf, bleh bleh)
write(&buf, bleh bleh)
That stack would be at least 1024 bytes big. In linux, all kernel stacks have a maximum size of 2 pages (8192 bytes).
There is no problem with locating it that far down, other than you might run into memory-mapped RAM holes and cripple yourself accidentally.
I immediately initialise my kernel-heap, start paging, get some RAM from the heap and relocate my stack there.

Read Bran's tutorials. I also am making some tutorials - http://www.jamesmolloy.co.uk. They're in no way finished, but I would appreciate your feedback on what's done so far (just done one on the GDT and IDT, so thats worth a look for you i think.)

JamesM
Post Reply