What you need to know: -some assembly programming -some knowledge about segmentation is recommended (but u'll live without) What you need to have: -An assembler.. i use tasm 2.01 .. download it on my homepage -A tool to write your code to the bootsector (not to hard to write in pascal/c/c++ etc..) -Preferably a computer to test this stuff on.. If we ever switch to protected mode, you should have a 386 at least.. What this text will teach you: This will teach you an extremely simple OS, in realmode, textmode, 16 bit, with a just as extremely simple filesys, when I get around to it. This means that this text is good for people who are just starting with OS coding. I hope. Give me feedback on what is hard to understand, what I explain to carefully, what I don't explain that should be explained, etc. Or send me mail for fun. (please send me mail:) ). I will respond ;) If you send suggestions etc for this text, plesae be specific about what you mean.. if thats possible. If you send for chatting, write whatever you feel like ;) The Bootsector =========================================== -How the computer starts the OS: When the computer starts, the bios normally checks if a: is bootable. It does that by checking if the last two bytes in sector 0 on the disk is 055AAh. If it is, then it will load that sector (the bootsector) to memory location 0:7c00h and execute it. Then it will do it's things, and load the kernel etc ... -The hello world bootsector When you make a bootsector (or any other part of your OS) remember that int 21h is not present, since that is dos's interrupt. Therefore you use int 10h to write to the screen. So, make a program that writes something on the screen, and assemble it. It should be .com , then you can put it directly on sector 0. If you for some reason can't make a .com , but .exe, don't worry.. an .exe file header is exactly 512 bytes (yes, one sector:) ), so when you copy it to sector 0, you simply skip the first sector of the .exe. Now use a disk IO tool to write the 055AAh at offset 510 in your bootsector. If you use the program I made (available on my website) that will write the signature for you. So, put the disk in a: and reboot! -Your bootsector must contain: At first, put 7c0h into DS. This isn't really needed for a bootsector, but it will make adressing variables simpler.. it depends on how you see it, i like it. Has to do with tasm's way of making .com files, i'll explain later. Note that 7c0h:0 is the same as 0:7c00h Then do: mov ax,9000h mov ss,ax mov sp,0ffffh This sets up the stack pointer. Our stack is now located in the end of segment 9000h. Note that the stack grows downwards, so when you push ax, sp will be fffdh. -tasm buggies and howto go around: When making the bootsector, I assume that you use tasm to compile it. To make tasm compile a .com , you must do org 100h (see another file for .com layout in tasm), and that means that it assume that your program is started at offset 100h. The bootsector isn't. That means that when you normally do mov di,offset [variable] that will point to somewhere else. instead, do this: mov di,offset [variable]-100h and it will work. -Loading the kernel (still in the bootsector): The kernel should be stored on second sector of the disk. Get an interrupt list, find int 13h and look up the function that read sectors. You are to specify a memory location to load it to. I load it to 7e0:100 .. (note; 0:7e00h = 7e0h:0 .. if you didnt understand that, you should find a doc about segmentation and read it). The reason I load it to offset 100h is the org 100h i mentioned. When you load it there, you wont need to mov di,offset [var]-100h .. you can do it without the -100h. To jump to the kernel, do the following: mov ax,7c00h add ax,768 ; 512 + 100h = 768 .. a sector is 512, so jump across ; that code, and add the 100h we talked about. jmp ax ; make the jump that jmp now jumps to cs:ax .. We set ds to 7c0, but we left cs alone so it will work. And you end up at the same position anyway (again, read about segmentation to understand that..) :) -Where the "##%&%¤% is the cut'n'paste-able source?! nope, you should learn this, make your own stuff and then look at other peoples source :) You can find mine at my website. The Kernel ====================== Things the kernel should do: - Give the user a command shell - Run files.. (we need a filesys too then..) - Set up interrupts.. makes things a bit easier We loaded the kernel at 7e0h:100h .. so set DS to 7e0h first. Then you are pretty much on your own to make a shell. When that is done, you could make a filesystem (probably a good idea.. but i didnt) or you could make executable file support. If you don't have a filesystem, your files will probably be limited to 512 bytes in size. But we code assembly, we dont mind .. at least not yet. So, when your shell reports that the user wanted you to start a program, you must read that program from the diskette, and load it into memory. When loading into memory, the only thing you have to watch out for, is overwriting the kernel code, or the BIOS info that is stored at 0040:something .. all the other memory is free (unless you wanna do mode13h, then stay away from a000 too). I load it at 900h:100h .. (i first did it at 800h .. but then i realized that the bugs that appeard came because i was overwriting my kernel:) ). To jump to the code, we must do a little trick. We must use a far call. We can't jump, since we'd like it to return to our code afterwards. Tasm wont let you do a far call, so we have to go around silly tasm. The opcode for a far call is is 9ah. So where you would normally put call far 900h:100h you instead: db 9ah ; opcode for call far dw 0100h ; when doing it in machine code, offset comes first. dw 0900h Now we have transferred control to a program. When that program should return to our OS, it executes a "retf" .. instead of dos's int 21h call. And bang, we're back in our OS. Before you call the program, you have to set up DS to 900h, so the program will find it's data. Just remember to push it first, and pop it after the prog returns. -Making interrupts: I assume you know what an interrupt is, and how to call it. Here's how to make one. When you do for example "int 10h" in your code, that will check an address in the interrupt vector table for the address for the code to handle that interrupt. The interrupt vector table starts at 0:0, and consist of 255 4-byte entries, which are addresses for the int handlers. We will simply load our code into memory somewhere, and alter the address for the int we want to make. The offset for for example int 20h is 0:20h*4 .. Here is some code: xor ax,ax mov es,ax ; segment 0.. mov di,20h ; we will make int 20h shl di,2 ; di := di * 4, to find offset for the address mov ax,100h mov es:[di],ax ; first offset.. 100h mov ax,500h mov es:[di],ax ; then segment .. 500h And thats it. Now the command "int 20h" will jump to 500h:100h and execute code there. Making the interrupt code is just as simple. Just three things to remember. First in the interrupt, use the command "cli" to make sure that IRQ's won't bother us. Then make your code, which is probably checking AH for function number... or whatever you want, it's your interrupt.. and when your code has finished, you do "sti" to allow IRQ's again, and then do an "iret" which means "Interrupt Return". Other than that, you organize your interrupt code just like any other .com compiled in tasm. When choosing your interrupt number, just remember that most of the interrupts are there, even if the comp just started.. It is safe to take numbers from 20h-2fh .. they are used by DOS, and since we're rid of DOS at the moment, feel free to take them. Or any other you please.. if it is free. -making a filesystem Since we are on a diskette, we will use fat12. But since I'm working at the filesystem myself at the moment, I can't write how you do it :) But if you want DOS to be able to read it (a good idea) you must alter you bootsector a bit, since DOS reads disk information from there. ============================================================================ ...th..th...thats all folks! [..for now..] I wrote this text mostly for myself.. as reference, and to sort out my own knowledge. It's really a good way to learn, you should try it :) Recommended reading: - can be found on my homepage.. - "The little black book of computer viruses", GREAT book, fun reading, teaches you alot of asm. Not really about OS, but i recommend it anyway :) - Any tutorial on the dos program debug, which is a WONDERFULL tool. I have some on my website.. And since we're really done with this tutorial, I'd like to say this: - .pdf should be illegal!! - .txt is the only real text-format - Assembly is the true language of your PC! - coders are people too.. --------- by Loonix http://loonix.technigga.net solvesle@yahoo.com