flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > 2 phase boot code, |
Author |
|
Dex4u 06 Feb 2006, 18:44
I think your making a lot of work for yourself, why not get "bootprog" from here:
http://alexfru.chat.ru/epm.html#bootprog This will let you put your "boot1" any where on the floppy and update your "boot1" from win/linux as if it was a normal file, it includes nasm source code for both floppy and hdd loading. This is the program i use to load my OS "Dex4u". |
|||
06 Feb 2006, 18:44 |
|
lazer1 06 Feb 2006, 21:20
Dex4u wrote: I think your making a lot of work for yourself, why not get "bootprog" from here: I'll study it, in the meantime I attempted the following boot0, it copies the sectors from 2 onwards to 10000h correctly however the jump to 10000h didnt function, the boot1 code at 10000h (not presented here) was fine at 7c00h can anyone see the error with this boot0? Code: QUANTITY equ 32768 org 7c00h mov ebx,01000h mov es,bx ; <<4 = 10000h mov ebx,0 ; es:bx = buffer = 1000:0 == 10000h mov edx,0 mov ecx,0 mov cl,2 ; sector no. starts at 1! mov eax,QUANTITY shr eax,9 ; al = no. sectors mov ah,02h ; read sectors int 13h mov ebx,01000h mov ss,bx mov [esp_phase0],esp mov esp,0fff8h mov es,bx mov ds,bx mov ebx,0 call far [ds:bx] mov ebx,0 mov ds,bx mov ss,bx mov esp,[esp_phase0] ret esp_phase0 dd 0 and the version of boot1 I'm using is the following which just selects 80 x 25 x 2 text and writes a 'Q' to the top left Code: org 10000h ; 80 x 25 x 2 text B8000 mov ax,03h int 10h mov eax,0B8000h shr eax,4 mov fs,ax mov eax,0 mov byte [fs:eax],'Q' add eax,1 mov byte [fs:eax],0fh ret so boot0 is in sector 1, boot1 in sector 2, boot0 reads boot1 to 10000h and then does "call far [ds:bx]" to 10000h, Q does not appear in the top left of the screen, Now if I replace "org 10000h" by "org 7c00h" in boot1 and put boot1 in sector 1 then it does echo Q in the top left correctly |
|||
06 Feb 2006, 21:20 |
|
RedGhost 07 Feb 2006, 04:05
you know you can just make your bootloader 2 sectors and rb to fill out 1024 (that's what i originally did for my OS, but then trimmed it to 512)
|
|||
07 Feb 2006, 04:05 |
|
lazer1 07 Feb 2006, 14:17
RedGhost wrote: you know you can just make your bootloader 2 sectors and rb to fill out 1024 (that's what i originally did for my OS, but then trimmed it to 512) excuse my ignorance, but what is "rb"? BTW I've resolved the problem, I was trying to call an address, what I should have done was call a pointer to an address: WRONG CODE: Code: =============WRONG:============ mov ebx,01000h mov ds,bx mov ebx,0 call far [ds:bx] ; this isnt calling 010000h ; but is calling *010000h, ... CORRECT CODE: Code: =============CORRECT:=========== mov bx,ds mov gs,bx mov ecx,boot1 .... ; this part changes ds and ebx, mov ebx,ecx call far [gs:bx] ; cx isnt allowed for this, .... boot1 dw 0,01000h ; 01000:0 == 10000h I will improve this further to just: MUCH BETTER CODE: Code: =========== EVEN BETTER boot0 fragment === mov bx,boot1 call far [ds:bx] .... boot1 dw 0,01000h ; 01000:0 == 10000h ============ CORRESPONDING boot1 fragment === org 10000h push ds push es mov ebx,1000h mov ds,bx mov es,bx ... pop es pop ds retf ; retf required to complement call far in boot0 in this improved code boot1 sets up its own segment registers and restores the original values at the end, this produces cleaner code as you can see trying to set up segment registers in boot0 was complicated. The whole scheme now is very straightforward, the only complicated part is the code to copy boot0 and boot1 to the disk, actually once boot0 is setup copying boot1 to the disk is just the reverse of the first part of boot0, so setting up could be done easily as 2 programs write0 and write1 write0 copies boot0 to sector 1 with 55aa at the end and write1 copies boot1 to sector 2 onwards, doing it via 1 program is more complicated as you have to deal with the shell arguments and detect different errors, although the above looks like subroutines it is more than that as it is 1 program calling another program like a subroutine so it is a plugin boot, I think I will upload the improved boot0 and boot1 later once I've improved the code enough, the earlier post asked why dont I use bootprog, the answer is I want to hit the metal directly without referencing any OS such as Linux or Windows and also to not reference any filesystem such as FAT. Just hit the sectors directly. I accept that bootprog is a more sophisticated path than I am taking, its just that it is a very maximalist path. as written the scheme allows bootcode of up to 32K, I can improve the scheme to allow bootcode of any size but the code will become more complicated. |
|||
07 Feb 2006, 14:17 |
|
lazer1 07 Feb 2006, 14:43
here are the new improved versions,
you assemble both, copy boot0 to sector 1 (LBA 0) with 55aa at the end of the sector, and copy boot1 to sector 2 (LBA 1) if you now boot with the floppy disk a Q will appear at the top left of the screen, boot0: Code: QUANTITY equ 32768 org 7c00h ;========= read QUANTITY bytes from sector 2 (LBA 1) to ; 10000h via int 13h ah=02h mov ebx,01000h mov es,bx ; <<4 = 10000h mov ebx,0 ; es:bx = buffer = 1000:0 == 10000h mov edx,0 mov ecx,0 mov cl,2 ; sector no. starts at 1! mov eax,QUANTITY shr eax,9 ; al = no. sectors mov ah,02h ; read sectors int 13h ;========= far call to above code at 10000h: === mov bx,phase1 call far [ds:bx] ; [orig_ds:phase1] lab1: jmp lab1 ret phase1 dw 0,01000h ; 1000:0 == 10000h and boot1: Code: org 10000h push ds push es push fs push eax ; the above pushes arent actually necessary! ; as the caller doesnt reference any of them ; afterwards mov eax,01000h mov ds,ax mov es,ax ; 80 x 25 x 2 text B8000 mov ax,03h int 10h mov eax,0B8000h shr eax,4 mov fs,ax mov eax,0 mov byte [fs:eax],'Q' add eax,1 mov byte [fs:eax],0fh pop eax pop fs pop es pop ds retf |
|||
07 Feb 2006, 14:43 |
|
Mac2004 11 Feb 2006, 14:11
Hi lazer1
'rb' stands for 'reserve byte'. With it you can reserve uninitialized variables. regards Mac2004 |
|||
11 Feb 2006, 14:11 |
|
kake_zinger 01 Mar 2006, 07:15
There is no need to make separate programs just make 1 loader as big as you want and jmp over the dw aa55h at the end of the boot block (first 512 bytes) to the next part of the loader, which you of course have loaded at its proper place already.
Just use org nnn if you want the 2nd stage be loaded somewhere else than as a continuum to the boot block (at 7e00h) and jmp's and all will be just fine. Extra bonus to whom can incorporate the 55AA boot signature as part of the boot code eliminating need for any jmp. That disassembles to PUSH BP / STOSB so an enterprising booter could use it for printing a successfull boot string in video memory or something similar. Now we only need a rationalization for doing the push and we'll set for the Perfect Boot Sector with not a byte wasted. |
|||
01 Mar 2006, 07:15 |
|
Borsuc 01 Mar 2006, 18:28
kake_zinger wrote: Extra bonus to whom can incorporate the 55AA boot signature as part of the boot code eliminating need for any jmp. That disassembles to PUSH BP / STOSB so an enterprising booter could use it for printing a successfull boot string in video memory or something similar. Now we only need a rationalization for doing the push and we'll set for the Perfect Boot Sector with not a byte wasted. Nice idea, but sadly, the jmp may be needed (altough not necessary for the signature), because BIOSes, sadly, load the code either at 07C0:0000, or at 0000:7C00, or every other combination... Note also, that it also depends on the alignment.. i.e: you can as well write a 16-bit instruction like mov right before the signature, and use the signature as a immediate value or something like that.. that's possible because x86 has instructions with opcodes that vary in size between different instructions. |
|||
01 Mar 2006, 18:28 |
|
kake_zinger 02 Mar 2006, 08:17
No need to be sad because despite what cs is loaded with the size of the boot sector will never break a segment limit. You can also load 1 cylinder (2 tracks=18k) from fdd without worrying about this at all.
Besides it's a complete non-issue unless you will be staying in 16bit mode for some strange reason. Otherwise I'd think that a minimum of 32k (ffff-7c00)of 16bit code would be more than enough for anyone. The idea of 55AA as part of some other op was good, just need to find out if something like that exists while being reasonably useful. |
|||
02 Mar 2006, 08:17 |
|
Madis731 02 Mar 2006, 08:25
Code: mov ax,0AA55h at the $=509 for example You can also end one instruction with 55h as an immediate or whatever and start the next instruction (stosb) |
|||
02 Mar 2006, 08:25 |
|
tom tobias 02 Mar 2006, 08:53
Madis731 wrote: .... Hmm. Isn't this the thread where rb was unknown??? Hmm. Gosh, if someone does not know rb, a mysterious assembler directive, isn't it also possible that someone (else, perhaps) might not fathom the meaning of $=509????? rb: reserve byte. Does this literally mean, reserve storage for only 8 bits, not 16, not 32? If so, then what are the alternative expressions for reserving storage for more conventional data sizes? What is the advantage of having different directives for different data sizes, rather than a single directive to allocate memory of a size specified by the programmer, or "coder"--for those who prefer to create inscrutable accomplishments. |
|||
02 Mar 2006, 08:53 |
|
kake_zinger 02 Mar 2006, 09:43
I think he's referring to the IP in decimal notation.
07C0:01FD B855AA MOV AX,0AA55H 07C0:0200 next instr here, 1st byte of next sector (sector 2) from floppy It's funny how basic counting creates much problems in programming. Floppy cylinders are counted from 0-79 but sectors from 1-18, in bios call. But when actually programming the fdd controller I think sectors are numbered 0-17. Boot sector is 512 bytes but when starting from 0000 the 512th byte is at address 0511 decimal = 01FFh. Ask an everyman what are the basic numbers of the decimal number system and they'll reply with 1-10. Of course that's not entirely their problem, that's what you get when kids are being taught simplified truths in school which actually are not truths at all. It all starts very early, kids counting in playing games 1-10 when they could do it 9-0 as well (the descending order down to zero for the dramatic "lift-off" effect, you know "...ZERO! I'M COMINGGG!!" when playing hide and seek . |
|||
02 Mar 2006, 09:43 |
|
kake_zinger 04 Mar 2006, 15:00
About the difficulty of correct counting:
Me and two of my friends went to that hotel and were told that there was only one room left and it would cost us $30 for the night. We each paid $10 and went to the room. Later, the desk clerk realized he had made an error by overcharging us $5. He asked the bell-hop to return the $5 to us. This bell-hop was a bigger prick than the desk clerk and figured that since $5 was not easy to divide among 3 men, he would just return $3 to us - $1 to each. Therefore, each of us paid $9, which totals $27 for the room. Add that to the $2 the bell-hop kept and the total is only $29! Where is the missing $1? Who has it? We beat the hell out of the bell-hop and took all his money so we actually made out fairly well on the deal. |
|||
04 Mar 2006, 15:00 |
|
Adam Kachwalla 02 Apr 2006, 02:34
Quote: Extra bonus to whom can incorporate the 55AA boot signature as part of the boot code eliminating need for any jmp. That disassembles to PUSH BP / STOSB so an enterprising booter could use it for printing a successfull boot string in video memory or something similar. Now we only need a rationalization for doing the push and we'll set for the Perfect Boot Sector with not a byte wasted. I really do not see why people whinge about adding "JMP [label]" to their code as if Godzilla or King Kong will JMP out of the computer and smash them to pieces... Can somebody please tell me the problem with adding that line of code? |
|||
02 Apr 2006, 02:34 |
|
Borsuc 05 Apr 2006, 18:49
Adam Kachwalla wrote: I really do not see why people whinge about adding "JMP [label]" to their code as if Godzilla or King Kong will JMP out of the computer and smash them to pieces... Can somebody please tell me the problem with adding that line of code? perfect code okay, I was joking, nothing is perfect.. jmp takes more space, and time.. even if it's not noticeable, just let's build something more original/perfect. |
|||
05 Apr 2006, 18:49 |
|
Adam Kachwalla 05 Apr 2006, 21:30
I think that the 0x55AA at the end is also unnecessary, but you must have it. It will also make it easier to make the file exactly 512 bytes long. (because RB doesn't work unless there are some significant bytes after that). You can use the DB or DW directive, ot other instructions, to put extra bytes in. So, at the end, you should always have something like:
Code: RB 510-$ DW 0xAA55 |
|||
05 Apr 2006, 21:30 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.