Where do i start??

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.
Schol-R-LEA

Re:Where do i start??

Post by Schol-R-LEA »

Berserk wrote: all the other questions remain.
There are questions, all right. I'll refrain from asking them, however, no matter how tempting it might be. You've already said you wouldn't answer most of them, anyway.
Please help.....
There are some things that are beyond my ability. This may be one of them. But I'll give it a shot.

Wow. I can't understand how a person could grasp programming in, well, most languages, really, without understanding basic linear addresses. I mean, even LISP has the idea of cons cells, that they are in some sort of linear order and can be referred to by location and so forth. It's difficult to imagine programming in C or C++ without knowing how pointers work and what they mean underneath. This is simply astonishing in someone who claims to be an experienced programmer.

OK, back to basics. Computer memory, at least on the PC, consists of thousands of 8-bit cells or sections called bytes. Each byte can hold a value from 0 to 0xFF (256 decimal). On the PC, bytes are grouped by words (two bytes) and doublewords (four bytes).

Each byte has an address, a value that tells the computer how to retrieve the memory cell's value. On the PC, that address can be represented in a variety of ways, but all of the different representations can be used to generate a single number, which is the memory cell's absolute address. Absolute addressses begin at zero.

A program is represented by a series of bytes filling up a consecutive area of memory. Each of the of individual operations that make up a program can take up from one to six bytes, depending on the instruction and the kind of parameters it takes, and a given program may be comprised of tens of thousands of these opcodes.

For a variety of reasons, it is impossible to use absolute addresses directly on the PC while in real mode, which is how the PC starts up. Instead, all addresses have to be put together from two word (16-bit) values, a segment base and a segment offset. I and others here have explained these often enough; you should be able to look up how they work with the search engine (try reply #4 in this thread to start).

To address (as it were) your specific question, the absolute address that follows absolute address 0x07C00 is 0x07C01. However, given that the boot sector takes up the area from 0x07C00 to 0x07DFF (absolute addresses), the next free memory area past the end of the boot sector where you could safely load you second stage loader would be 0x07E00. Remember, however, that you are really talking about a segmented address, which is probably (but not necessarily) being addressed as 0000:7C00 (that is to say, the Code Segment register CS is set to 0x0000, and the addresses used to refer to the specific addresses are 0x07C00 through 0x07E00, on up 0x0FFFF. Since each real-mode segment offset can only address 65536 bytes, to access more memory than that you need to change the segment base in order to address more than a single 64K area. The combination of segment bases and offset can add up to at most a 20-bit absolute address, giving access to 1Mbyte of memory.

In 32-bit protected mode, it is both more and less complicated. The segment registers are replaced with 24-bit segment selectors, while the segment offsets are now a double word (32-bits) in size, meaning that there is sufficient memory space (4 gigabytes) in a single segment that most systems simply use a single segment for each program. That, combined with paging, can make it appear to an application program as if it had the whole of a single linear memory space available to it. The OS hides all of this complexity away by dealing with the segment selectors and paging requirements for the application programs.

I'm frankly too tired to continue right now. If you have any more questions I'll reply to them as best I can later.
Schol-R-LEA

Re:Where do i start??

Post by Schol-R-LEA »

Looking at my posting from last night (or rather, very early this morning), I realize I was a rather too harsh in both my assesment of the question and in my reply. I apologize for this overreaction. I think I misjudged what you were asking, and your understanding of memory addressing. Your real questions are not so obvious or simple as all that, and I should not have been so patronizing.

As for the question of whether you could load your second stage loader at address 0000:0000, the answer is a qualified no. In real mode, the first 0x0400 (1024) bytes of the memory are taken up by the Interrupt Vector Table, the master list of addresses for the interrupt service routines; overwriting it with program code would lead to system failure when the next interrupt occurs. This is followed by the BIOS data area, which goes from 0000:0400 to 0000:05FF. This includes not only the scratch space used by the BIOS, but also the default stack that is set up when entering at boot time, IIRC. Scribbling on this before if you have set up a different stack is a Very Bad Idea.

For the record, the free areas of memory in real mode, by highest segment base, are from 0060:0000 (the first address past the BDA) to 07BF:000F (just before the beginning of the boot loader) and from 07E0:0000 to 9FFF:000F (just before the beginning of the VGA video memory area). If you activate the A20 line, you can also use the area from FFFF:0010 to FFFF:FFFF if you want.

In protected mode, the IVT ceases to be an issue directly, but it may still be important to maintain at least a copy of it so that it can be restored when running in v86 mode, or if you need to return to real mode for some reason (e.g., to use a 16-bit VESA BIOS call). Indeed, it is probably best to leave the entire first megabyte of physical memory reserved for certain special uses, for a variety of reasons (certain hardware drivers must be in the first 1MB of memory, for example). Many p-mode OSes load their kernels at 0x100000 instead for precisely this reason, while others load to the highest area of available physical memory instead.

Where you load the second stage is your choice; you have most of memory available to you, and you can put it wherever you find most convenient. You should consider how the decision will impact your overall design, however.
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Thanks for the info, it really helped ;D

Now i am up to the A20 Line ;D

I got this simple function:

Code: Select all

 _Enable_A20_Gate:
                cli

                call _Empty_8042
                mov al, 0x0D1
                out 0x64, al

                call _Empty_8042
                mov al, 0x0DF
                out 0x60, al
                call _Empty_8042

                sti

                ret
 _Empty_8042:
                mov al, 0x0D0
                in al, 0x64
                test al, 2
                jnz _Empty_8042
                ret
It works, But what does _Empty_8042 Do??

Also, is this a good way to do it?? If it doesn't get enabled, how can i make it retry (with no counter, i want it to just keep trying until it gets it right.)

Ciao ;)
Berserk

Re:Where do i start??

Post by Berserk »

Also...

Why isn't this thread sticky anymore? And does anybody know where i can get a good explanation of the A20 Line? (i tried the one at osdev.neopages.net, it is too complicated, i don't want mine to be that complicated.) The A20 Line allows for me to acess all the ram right?

Ciao ;)
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:Where do i start??

Post by df »

i unstickyed it as i thought it was being used as too much of a general thread, instead of just doing where do i start pointers...
-- Stu --
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Ok, Fair Enough.

Now could somebody please help me with my questions ;D

Ciao ;)
DarylD

Re:Where do i start??

Post by DarylD »

Berserk, I think you really need to get yourself some books and look up computer architecture. Without understanding RAM/ROM/Ports/IRQ's you are not going to get very far and struggle. Honestly it will help a lot, a simple introductory book to "how a computer works" will really help you here.

I know it seems frustrating, I would say a lot of people here are in the same boat as me and learnt coding on old 8 bit (maybe even 16 bit) machines. Using these you "had" to really understand things, you obviously missed out these early microcomputing years, this really helps when it comes to OS development.

Without sounding harsh, it is important to be able to visualise ram structure, how ports work etc. if you are going to get very far in programming an OS. You may indeed be an experienced applications programmer, in fact its easy to tell by you're urge to get something appearing in graphics mode already (which should come later, a *lot* later)

I just get the feeling you are winding some people up on here by expecting everybody to just tell you the answer, the only reason I am experimenting with OS development is to *LEARN* and not be told.

Anyway...sorry for that, having a bad morning.
Schol-R-LEA

Re:Where do i start??

Post by Schol-R-LEA »

I have to agree with DarylD on this. You are going to have to sit down with a few books and copies of NASM and gcc, and get in at the very least several months worth of studying and practicing, before you will be doing anything more than going through the motions. This is not something that can be done by cut and paste; you have to solidly understand not only the form of the code but it purpose. Some basic understanding of both the theoretical and practical aspects of how the hardware works is absolutely essential for systems programming at this level.

Go through the book thread and see what references you can use. You know better than anyone what books will work for you personally. Check out as many of the them as you possibly can - including those not specifically related to OS programming, as they were recommended for a reason despite this - and hold on to those you find useful.

If I were to recommend a specific curriculum, it would be something like this:

Start out with The Design of Everyday Things by Donald A. Norman. As I've often said, anyone who does any interface design must read this book.

Go on to Duntemann's Assembly Language Step by Step, and an in-depth review of both C and C++, such as Thinking in C++ and Practical C Programming.

Perhaps take a bit of time to broaden your skills a bit, with a few other languages, too - trust me, it really does make a huge difference. I recommand Scheme, APL, Smaltalk, Python, tcl, SQL and Perl, in roughly that order. While it may seem like a lot, learning new languages gets easier the more that you know. You don't really need to know them insde and out, anyway, just enough to get a sense for the sdifferent ways they look at things. Perl should be last, as it borrows techniques from most of the others, and can get quite hairy

Then read through some works on basic OS concepts such as AST's Modern Operating Systems, or Stalling's Operating Systems. alongside some books specific to the x86 system, such as Linux Core Kernel Commentary (while this covers other systems, much of it is specific to the PC), Operating Systems: Design and Implementation (the Minix book) or MMURTL (not a great book overall, but the coverage of PC specific material is pretty good). It would be a good idea to read Linkers and Loaders at this stage as well, as the subject of programming loading is generally given only brief coverage in general OS books.

Follow these with a close reading of The Indispensible PC Hardware Book and The Graphics Programming Black Book (which discusses a lot of low-level programming issues not necessarily related to graphics), as well as the Intel manuals (which can also be found on Intel's website).

Then go to the Operating Systems Resources Center and similar web archives, read through as many of the various online tutorials that you can find until you think you could code a floppy disk device driver with DMA support in your sleep. :)

After you've done that, feel free to come back and ask whatever questions you still have.

I'm not joking, either - exaggerating, perhaps, but I do mean this as a serious suggestion. While I wasn't so methodical about it, I spent ten years doing this sort of thing, on and off in my spare time, before I began serious work on OS design. This is not, as you pointed out to someone else regarding game programming, something you can just pick up over a weekend; it takes a lot of time and work to learn how to do this.

I've been more than happy to offer what help I could the past four or five months, but I'm worried that after all this time you still haven't really understood what we've been showing you. When after all this time you suddenly ask about such a basic matter, it makes us all wonder just how well you've really been paying attention.

Please, for your own sake and for the sanity of the rest of us, try to understand things on you own just for once.
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

I am sorry, i will go and read some book a bit later, but i am not going to spend 10 years doing it, i will learn as i go ;D. I know you'se may think it's a bad idea, but it's the way i do things, and it works for me ;)

Now i got a question, is there a way to do the same thing like in nasm, which does

Code: Select all

 times 510($$-$) db 0 (Or something like that, i can't recall it now!)
In my C Kernel, the reason i want to do this is that i want to make my Kernel a specific size, and make sure it stays that way, and it would also allow me to load the right amount from my BootLoader, to memory ;D

I want my Kernel to be limited in size (a certain size) ;D

Ciao ;D
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

Post by Pype.Clicker »

the best way to do this is probably to play with linker scripts... however, i'm not sure it's that interresting to enforce the kernel to be - say - 64Kb while it is actually smaller ... it will just take more time to load, and lock more memory ...
What could be useful could be to use that trick to pad your kernel to a integer number of sectors.

Now, what you could do is reading out the byte size of your kernel file and use it to generate constants...
1. the kernel is compiled and flattened into kernel.bin
2. a small tool reads kernel.bin's size (fopen(), fseek(0,SEEK_END), ftell(), fclose())
3. the size you found is used to generate some "asm header" file:
fprintf(asm_header,"%%define KERNEL_SIZE %i",size);
4. assemble your boot sector (or second-stage loader if any) that includes the asm_header file.
Berserk

Re:Where do i start??

Post by Berserk »

I see what you mean, it is a bad idea :)

There is something that i am curious about, i load sectors from my floppy, it works perfectly. But what i am wondering is that i see people loading things to different registers, such things as the Segment get loaded to bx, and into a different register in other bootsectors/ssl's, what is the best place to put them, i need a good tutorial on floppy disk's, everyting else i understand, except this, well, i understand all i need to for now. So if somebody could explain this, maybe i am a bit irritating with all my posts, but this has been buggin me fot the last week!

Cya.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

Post by Pype.Clicker »

just get the bios interrupt list ... i guess it will answer a lot of questions.

And, putting the segment in BX ? that sounds like a joke ... if anyone did it, i think his code is unlikely to work ... the target destination for the INT 13h is es(segment):bx(offset).
Berserk

Re:Where do i start??

Post by Berserk »

Thanks,

I already know that the Segment doesn't go into bx, but i have seen it in other peoples code, so i got a bit confused ;D

Thanks, and i already have a list of interrupts from a thing called HelpPC, it is very handy ;)

Cya.
tfurtado

Re:Where do i start??

Post by tfurtado »

Where can I find this interrupt list?
Put the link here, please.

Bye!
Schol-R-LEA

Re:Where do i start??

Post by Schol-R-LEA »

Acid Demon wrote: Where can I find this interrupt list?
Put the link here, please.
Ralf Brown's Interrupt List can be downloaded at his website, or browsed online at Marc Perkel's mirror site. It describes all of the commonly supported BIOS routines, DOS calls, and DOS 16-bit drivers. The specific interrupt you want is the [tt]INT 0x13[/tt], which takes the following arguments for different routines:
  • [tt]AH= 0[/tt] - reset drive;
    [tt]DL[/tt] =drive number
  • [tt]AH=2[/tt] - read a sector to memory;
    [tt]AL[/tt] = number of sectors to read (must be nonzero)
    [tt]CH[/tt] = low eight bits of cylinder number
    [tt]CL[/tt] = sector number 1-63 (bits 0-5)
    high two bits of cylinder (bits 6-7, hard disk only)
    [tt]DH[/tt] = head number
    [tt]DL[/tt] = drive number (bit 7 set for hard disk)
    [tt]ES:BX[/tt] -> data buffer
  • [tt]AH=3[/tt] - Write a sector from memory;
    [tt]AL[/tt] = number of sectors to write (must be nonzero)
    [tt]CH[/tt] = low eight bits of cylinder number
    [tt]CL[/tt] = sector number 1-63 (bits 0-5)
    high two bits of cylinder (bits 6-7, hard disk only)
    [tt]DH[/tt] = head number
    [tt]DL[/tt] = drive number (bit 7 set for hard disk)
    [tt]ES:BX[/tt] -> data buffer
What you have to do is set each of the arguments, with the argument in AH determining which function is actually called. Once the different registers are set, you then perform an [tt]INT 0x13[/tt] call. It is important to remember that these values are invariably listed in hex, which for a variety of reasons is more convenient than decimal for these purposes.

For an example of using them, see this early version of my boot loader. Note that I was specific not to use the numeric values inline, but rather used named constants wherever possible. The unfortunate practice of using 'magic numbers' is widespread in assembly programming, and IMAO is one of the things that makes assembly language seem difficult to new programmers.
Post Reply