flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > help optimizing bootsector |
Author |
|
ASHLEY4 07 Nov 2004, 18:25
Your read sector would be smaller if you read a sector at a time in a loop you inc sector number until it gets to 19, you make it 1, then you cmp head to 0 or 1, if 1 you make 0 and inc track number, if 0 you inc it to 1 ,and you keep loop and checking until you come to the end address.
Also y fill in gs, fs, in realmode ?. And yes you should be able to fit more in, theres space for a cdplayer in there . \\\\||//// (@@) ASHLEY4. Batteries not included, Some assembly required. |
|||
07 Nov 2004, 18:25 |
|
bubach 07 Nov 2004, 18:33
Hmm.. i tried to make a loop, but every time it changes almost every param. register, but i guess i could try again.
But a cdplayer? don't think so... PS: when i use this with a test kernel, it says that it takes up 1,07 mb of the floppy, why? how can i fix that? bootsector+kernel = 5kb hmm.. if i had more space i could try to make it load a real file from the root dir... / Christoffer Last edited by bubach on 13 Feb 2012, 14:30; edited 1 time in total |
|||
07 Nov 2004, 18:33 |
|
ASHLEY4 07 Nov 2004, 18:53
Y do you not do what i do, that is use bootprog http://alexfru.chat.ru/epm.html
any demos i have sent you that uses win image will have it on the disk, just delete the exe or com on the demo disk put a exe or com of the same name, you can use this to test your program as a exe or com, when it works right start making it smaller to fit the boot sector and then put it on the boot sector. \\\\||//// (@@) ASHLEY4. Batteries not included, Some assembly required. |
|||
07 Nov 2004, 18:53 |
|
Matrix 07 Nov 2004, 19:14
435 bytes and i was not radical
its already 62 bytes shorter, you should try to think more about that progress bar thingy, i whouldn't do that. Code: ;----------------------------------------------------; ; BOS bootsector ; ;----------------------------------------------------; ; FAT12 compatible. Sets pmode & A20. Kernel must be ; ; the first thing on disk after the bootsector. ; ; ; ; TODO: optimize enought for error checking when ; ; loading sectors and print 2 progress dots ; ; for each "bunch" of sectors loaded correctly. ; ; ; ; by: Christoffer Bubach, 2004 ; ;----------------------------------------------------; use16 org 0x7C00 boot: jmp near fix nop ;-----------------------------------------; ; Standard BIOS Parameter Block, "BPB." ; ;-----------------------------------------; bpbOEM db 'BOS 0.03' bpbSectSize dw 512 bpbClustSize db 1 bpbReservedSec dw 1 bpbFats db 2 bpbRootSize dw 224 bpbTotalSect dw 2880 bpbMedia db 240 bpbFatSize dw 9 bpbTrackSect dw 18 bpbHeads dw 2 bpbHiddenSect dd 0 bpbLargeSect dd 0 ;-----------------------------------------------; ; extended BIOS Parameter Block for FAT12/FAT16 ; ;-----------------------------------------------; bpbDriveNo db 0 bpbReserved db 0 bpbSignature db 41 bpbID dd 1 bpbVolumeLabel db 'BOOT FLOPPY' bpbFileSystem db 'FAT12 ' ;-----------------; ; code area ; ;-----------------; fix: jmp 0x0000:start start: ; cli ; i guess its not needed comment out for 2 bytes mov ax, cs mov ds, ax mov es, ax mov gs, ax mov fs, ax push 0x9000 ; i have not tested this yet, but its intresting no? pop ss ; mov ax, 0x9000 ; mov ss, ax mov sp, 0x8000 mov [bpbDriveNo], dl ; sti ;------------------------; ; set textmode/font size ; ;------------------------; mov ax, [text_mode_no] mov bl, 0 int 0x10 ;--------------------; ; print loading mess ; ;--------------------; mov bp, loading mov ax, 0x1301 mov bx, 0x0007 mov cx, 12 mov dx, 0x0102 int 0x10 ;----------------; ; set A20 ver. 1 ; ;----------------; call .out call .cmd_wait mov al, 0xd1 out 0x64, al call .cmd_wait mov al, 0xdf out 0x60, al call .cmd_wait jmp .done .cmd_wait: in al, 0x64 test al, 0x02 jnz .cmd_wait ret .out: in al, 0x64 test al, 0x01 jnz .read ret .read: in al, 0x60 jmp .out .done: ;-------------; ; test if set ; ;-------------; call a20test jz pre_read ;----------------; ; set A20 ver. 2 ; ;----------------; in al, 0x92 or al, 0x02 out 0x92, al ;-------------; ; test if set ; ;-------------; call a20test jz pre_read jmp error ;-----------------------------; ; print progress dots (faked) ; ;-----------------------------; pre_read: mov bp, progress mov ax, 0x1301 mov bx, 0x0002 mov cx, 14 mov dx, 0x0201 int 0x10 ;--------------------------------------; ; read a 50 kb file to mem. ; ;--------------------------------------; read: push es ;-------------; ; reset drive ; ;-------------; xor ax, ax mov dl, [bpbDriveNo] int 0x13 jc read ;---------------------------------------------------; ; set es and hope that bios does not mess with it.. ; ;---------------------------------------------------; push $ffff ; mov ax, 0xffff pop es ; mov es, ax ;-----------------; ; read 17 sectors ; ;-----------------; mov bx, 0x10 xor dh,dh mov ax,$0211 ;mov ah, 2 ;mov al, 17 mov cx,2 ; mov ch, 0 ; mov cl, 2 int 0x13 jc read ; read 18 sectors block mov bx, 0x2210 mov dh,1 mov cx,1 ;mov ch, 0 ;mov cl, 1 call readsector_common ; read 18 more ; mov bx,0x4610 xor dh,dh mov cx,$0101 push cx call readsector_common ; read 18 more ; mov bx,0x6A10 pop cx ; mov cx,$0101 mov dh,1 call readsector_common ; read 18 more ; mov bx,0x8E10 xor dh,dh mov cx,$0201 push cx call readsector_common ; read 18 more ; ; read the last 11 ; mov bx,0xB210 mov ax,$020b pop cx ; mov cx,$0201 mov dh,1 int 0x13 ; stop motor ; mov dx,0x3F2 mov al,0x0C out dx,al pop es jmp pmode readsector_common: mov ax,$0212 ;mov ah, 2 ;mov al, 18 int 0x13 ret ;----------------------------; ; some functions and data ; ;----------------------------; ;----------------; ; variables ; ;----------------; loading db 'Starting BOS' progress db '.' ;.............' msg_error db 'I/O error' ;, press any key to restart..' text_mode_no dw 3 ;----------; ; test A20 ; ;----------; a20test: mov al,byte [fs:0] mov ah,al not al xchg al,byte [gs:10h] cmp ah,byte [fs:0] mov [gs:10h], al ret ;------------; ; error.. ; ;------------; error: mov bp, msg_error mov ax, 0x1301 mov bx, 0x0004 mov cx, 37 mov dx, 0x0401 int 0x10 mov ah, 0 int 0x16 int 0x19 ;--------------------------------; ; end of functions and data area ; ;--------------------------------; ;----------------------------; ; set pmode ; ;----------------------------; pmode: cli lgdt [gdtr] mov eax, cr0 or eax, 1 mov cr0, eax jmp 0x08:flush ;---------------------------------------------------------; ; start of 32-bit area. flush segments and jump to kernel ; ;---------------------------------------------------------; use32 flush: ;-------------------------------; ; refresh all segment registers ; ;-------------------------------; mov eax, 0x10 mov ds, eax mov es, eax mov fs, eax mov gs, eax mov ss, eax mov esp, 0xfffc ;---------------------; ; jump to loaded file ; ;---------------------; jmp 0x08:0x100000 ;--------------------------------; ; global descriptor table (gdt) ; ;--------------------------------; gdt: dw 0x0000, 0x0000, 0x0000, 0x0000 codesel: dw 0xFFFF, 0x0000, 0x9800, 0x00CF datasel: dw 0xFFFF, 0x0000, 0x9200, 0x00CF gdt_end: gdtr: dw gdt_end - gdt - 1 dd gdt ;-------------------------------------; ; set the BOOT-signature at byte 510. ; ;-------------------------------------; ; rb boot+512-2-$ ; dw 0xAA55 |
|||
07 Nov 2004, 19:14 |
|
Matrix 07 Nov 2004, 19:18
instead of squeezing everything into the bootsector you could put more sectors on the disk which whould be read and called @ boot time.
|
|||
07 Nov 2004, 19:18 |
|
bogdanontanu 07 Nov 2004, 20:42
IMHO you should NOT attempt to squezze too much things into the boot sector, you will always run low on space there.
For booting from a real floppy the only optimization thing in there should be an attempt to read multiple sectors at a time (not trivial) as this should speed up the loading process. Otherwise use a simple loop for one sector on a time. You can see that kind of loop in SolOS boot sector source code. The nex SolOS release will also have the "fast boot" version for reading one track at a time. IMHO the boot sector shoul do ONLY some simple tasks: 1) Startup PC 2) READ the folowing sectors (2nd stage application) into memory and give it control You can put much more complex setup code in this 2nd stage application. I use this approach. Please consider that you will have to boot from HDD, CD-ROM, USB, etc/whatever also and placing all the code for this in a small 512bytes sector is not an option IMHO. Also reading propretary filesystems like FAT12/FAT32 directly from the boot sector is not a good option IMHO. |
|||
07 Nov 2004, 20:42 |
|
ASHLEY4 07 Nov 2004, 23:11
Bogdanontanu, I do not think "bubach" is trying to make a OS boot loader as such.
I think he is trying to make a pmode exe/com file loader. like bootprog, but for pmode, i may be wrong (did i realy say that) . PS: like your OS. \\\\||//// (@@) ASHLEY4. Batteries not included, Some assembly required. |
|||
07 Nov 2004, 23:11 |
|
beppe85 08 Nov 2004, 00:08
Most of job already is done. But you still can get unbelieved 6(if I coded correctly) bytes by reorganizing the A20 stuff:
Code: jmp .out .cmd_wait: in al, 0x64 test al, 0x02 jnz .cmd_wait ret .read: in al, 0x60 .out: in al, 0x64 test al, 0x01 jnz .read call .cmd_wait mov al, 0xd1 out 0x64, al call .cmd_wait mov al, 0xdf out 0x60, al call .cmd_wait .done: I guess it's not what were you asking for, but, here is... |
|||
08 Nov 2004, 00:08 |
|
bubach 08 Nov 2004, 08:37
I have my own FAT12 bootloader and second stage loader, but they are for nasm, and i thought that when i am going to rewrite it anyway, i could test and see how much i can squize in.
It's like a experiment for me.. Ashley4: i know about bootprg, and i have it, but i prefer code that is written by myself.. ps: no need for com&exe support, bin style is enought... Thanks for the help. Now maybe i could fit in some extra function if i do something about the loading dots..? / Christoffer Last edited by bubach on 13 Feb 2012, 14:31; edited 2 times in total |
|||
08 Nov 2004, 08:37 |
|
bubach 08 Nov 2004, 08:40
one more thing:
do i really need to test if the A20 is set between the 2 functions? it can't harm to set it twice, can it? Last edited by bubach on 13 Feb 2012, 14:32; edited 1 time in total |
|||
08 Nov 2004, 08:40 |
|
bubach 09 Nov 2004, 09:21
Hello, i have done some more work on it now.
Matrix: all those calls to read_common, takes up space.. I managed to get the size down even more without that.. Here is my newest version, originaly 411 bytes, but i added a check for 386 processor and memory 4mb.. Now it's 510 bytes, but i would like to have enought space to send drive no. and memory size to the loaded file, so if anyone can think of a way to save some more bytes..... Code: ;----------------------------------------------------; ; BOS bootsector ; ;----------------------------------------------------; ; FAT12 compatible. Sets pmode & A20. Kernel must be ; ; the first thing on disk after the bootsector. ; ; ; ; size: 510 bytes (with bootsignature) :-p ; ; ; ; my old size before cpu, mem and better error ; ; checking was 411 bytes. ; ; ; ; TODO: pass bpbDriveNo & memory_size to loaded file ; ; ; ; by: Christoffer Bubach, 2004 ; ;----------------------------------------------------; use16 org 0x7C00 boot: jmp near fix nop ;-----------------------------------------; ; Standard BIOS Parameter Block, "BPB." ; ;-----------------------------------------; bpbOEM db 'BOS 0.03' bpbSectSize dw 512 bpbClustSize db 1 ;----------------------------------------; ; setting this to 20 reserves ~48kb, and ; ; setting it to 21 reserves ~200kb ! (?) ; ;----------------------------------------; bpbReservedSec dw 1 bpbFats db 2 bpbRootSize dw 224 bpbTotalSect dw 2880 bpbMedia db 240 bpbFatSize dw 9 bpbTrackSect dw 18 bpbHeads dw 2 bpbHiddenSect dd 0 bpbLargeSect dd 0 ;-----------------------------------------------; ; extended BIOS Parameter Block for FAT12/FAT16 ; ;-----------------------------------------------; bpbDriveNo db 0 bpbReserved db 0 ;--------------------------------------------------; ; extended boot signature. if it is not 29h (41d), ; ; then the following three fields is not present. ; ;--------------------------------------------------; bpbSignature db 0 ;------------------------; ; saving some bytes. =) ; ;------------------------; ; bpbID dd 1 ; bpbVolumeLabel db 'BOOT FLOPPY' ; bpbFileSystem db 'FAT12 ' ;-----------------; ; "fix"-jump ; ;-----------------; fix: jmp 0x0000:start ;-----------------------; ; variables ; ;-----------------------; loading db 'Starting BOS' ram_error db ' RAM' a20_error db ' A20' cpu_error db ' CPU' read_error db 'Read' msg_error db ' error, press any key to restart..' memory_size dw 0x0000 ;----------------------------------; ; set to 0x1112 for 80x50 mode ; ;----------------------------------; text_mode_no dw 3 ;-----------------------------------------------; ; "real" starting point of bootsector code ; ;-----------------------------------------------; start: mov ax, cs mov ds, ax mov es, ax mov ax, 0x9000 mov ss, ax mov sp, 0x8000 mov [bpbDriveNo], dl ;--------------------; ; clear the screen ; ;--------------------; mov ax, 3 mov bl, 0 int 0x10 ;------------------------; ; set textmode/font size ; ;------------------------; mov ax, [text_mode_no] int 0x10 ;--------------------; ; print loading mess ; ;--------------------; mov bp, loading mov ax, 0x1301 mov bx, 0x0007 mov cx, 12 mov dx, 0x0102 int 0x10 ;---------------------; ; set cursor location ; ;---------------------; mov bx, 0x0002 mov ah, 2 mov dx, 0x0201 int 0x10 ;------------; ; print dots ; ;------------; mov ah, 0x09 mov al, '.' mov cx, 14 int 0x10 ;----------------------------------------------; ; 386 check, i have room for such luxury.. =) ; ;----------------------------------------------; pushf pop ax mov dx, ax xor ax, 0x4000 push ax popf pushf pop ax and ax, 0x4000 and dx, 0x4000 cmp ax, dx jnz mem mov bp, cpu_error jmp error ;-------------------------------------; ; memory check, only up to 64 mb ; ;-------------------------------------; mem: mov ah, 0x88 int 0x15 mov [memory_size], ax cmp ax, 3072 jae a20 mov bp, ram_error jmp error ;----------------; ; set A20 ver. 1 ; ;----------------; a20: jmp .out .cmd_wait: in al, 0x64 test al, 0x02 jnz .cmd_wait ret .read: in al, 0x60 .out: in al, 0x64 test al, 0x01 jnz .read call .cmd_wait mov al, 0xd1 out 0x64, al call .cmd_wait mov al, 0xdf out 0x60, al call .cmd_wait ;----------------; ; set A20 ver. 2 ; ;----------------; in al, 0x92 or al, 0x02 out 0x92, al ;-----------------; ; test if A20 set ; ;-----------------; mov al, byte [fs:0] mov ah, al not al xchg al, byte [gs:10h] cmp ah, byte [fs:0] mov [gs:10h], al jz read ;------------------; ; a20 error.. ; ;------------------; mov bp, a20_error ;------------; ; error.. ; ;------------; error: mov ax, 0x1301 mov bx, 0x0004 mov cx, 4 mov dx, 0x0401 int 0x10 mov bp, msg_error mov cx, 34 mov dx, 0x0405 int 0x10 mov ah, 0 int 0x16 int 0x19 ;-----------------------------------------------------------; ; read the first 50 kb of the disk to to memory at 1mb. ; ;-----------------------------------------------------------; read: push es ;--------------------------------------------------; ; error checking. we can fail a total of 10 times. ; ;--------------------------------------------------; xor cx, cx push cx .reset: pop cx inc cx cmp cx, 11 jne .cont mov bp, read_error jmp error .cont: push cx ;-------------; ; reset drive ; ;-------------; xor ax, ax mov dl, [bpbDriveNo] int 0x13 jc .reset ;---------------------------------------------------; ; set es and hope that bios does not mess with it.. ; ;---------------------------------------------------; push 0xffff pop es ;-----------------; ; read 17 sectors ; ;-----------------; mov bx, 0x10 mov ax, 0x0211 mov cx, 2 mov dh, 0 int 0x13 jc .reset ;--------------; ; read 18 more ; ;--------------; mov bx, 0x2210 inc al mov cx, 1 mov dh, 1 int 0x13 jc .reset ;--------------; ; read 18 more ; ;--------------; mov bx, 0x4610 mov cx, 0x0101 mov dh, 0 int 0x13 jc .reset ;--------------; ; read 18 more ; ;--------------; mov bx, 0x6A10 mov dh, 1 int 0x13 jc .reset ;--------------; ; read 18 more ; ;--------------; mov bx, 0x8E10 mov cx, 0x0201 mov dh, 0 int 0x13 jc .reset ;------------------; ; read the last 11 ; ;------------------; mov bx, 0xB210 mov ax, 0x020B mov dh, 1 int 0x13 jc .reset ;------------; ; stop motor ; ;------------; mov dx, 0x3F2 mov al, 0x0C out dx, al pop cx pop es ;----------------------------------; ; set protected mode (32-bit) ; ;----------------------------------; cli lgdt [gdtr] mov eax, cr0 or eax, 1 mov cr0, eax jmp 0x08:flush ;---------------------------------------------------------; ; start of 32-bit area. flush segments and jump to kernel ; ;---------------------------------------------------------; use32 flush: ;-------------------------------; ; refresh all segment registers ; ;-------------------------------; mov eax, 0x10 mov ds, eax mov es, eax mov fs, eax mov gs, eax mov ss, eax mov esp, 0xfffc ;-----------------------------------; ; jump to loaded file (1mb in mem) ; ;-----------------------------------; jmp 0x08:0x100000 ;--------------------------------; ; global descriptor table (gdt) ; ;--------------------------------; gdt: dw 0x0000, 0x0000, 0x0000, 0x0000 codesel: dw 0xFFFF, 0x0000, 0x9800, 0x00CF datasel: dw 0xFFFF, 0x0000, 0x9200, 0x00CF gdt_end: gdtr: dw gdt_end - gdt - 1 dd gdt ;-------------------------------------; ; set the BOOT-signature at byte 510. ; ;-------------------------------------; rb boot+512-2-$ dw 0xAA55 Last edited by bubach on 13 Feb 2012, 14:32; edited 1 time in total |
|||
09 Nov 2004, 09:21 |
|
beppe85 09 Nov 2004, 11:26
Some byte savings:
On the 386 check: - can you put 0x4000 on a register, say, cx? - change the last jnz/mov/jmp to mov/jnz, I guess there's no need to preserve bp On the sectors load: - instead of cx, use di if you can - jne/mov/jmp -> mov/jne, same as 386 |
|||
09 Nov 2004, 11:26 |
|
bubach 09 Nov 2004, 13:39
Ok, thanks.
What other things do u want in a bootloader? I could fit in some more, with less error checking and without my "custom" error messages... Some questions: How can i make the FAT system to behave like it should, when i am writing a file after the bootsector? As it is now, i could overwrite it if the floppy is full, becasue i can´t make the "reserved_sector" field to work... and now XP reports that the used space is 1,07mb instead of boots. 512b and kernel~5kb. i guess that it´s becasue i overwrite one of the FAT´s? the one that should be right after the bootsector? Can i make the file (that is going to be loaded), visible on the floppy, as a normal file, even thou it´s "hard-written" to specific sectors? / Christoffer |
|||
09 Nov 2004, 13:39 |
|
Matrix 09 Nov 2004, 13:42
that's because MS dos and windos stuff has many bugs in there own patented codes and algorithms like for example ignoring the reserved sectors, not using some parameters given in drive info block ... yeah, you can do such things, you only have to put a valid fat and directory entry on the floppy. |
|||
09 Nov 2004, 13:42 |
|
bubach 09 Nov 2004, 14:40
But when i read the MS Fat document they wrote that MS-code is almost the only ones that do check correctly.. I guess that isn't true.
So now i have to figure out how to make a tool, wich does the copying and updates the FAT.. (links to info & source please.. ) But to make it 100% FAT compatible i need to move the file a bit, right? into a fixed location of the FAT data area.. (where?) again, some links to info&snippets on this would be great.. / Christoffer Last edited by bubach on 13 Feb 2012, 14:33; edited 1 time in total |
|||
09 Nov 2004, 14:40 |
|
beppe85 18 Dec 2004, 23:44
The challenge is still open?
I have figured out a way to squeeze even more bytes(dozens of it). I'm posting a snippet. As this was done two weeks or so ago, I'm not sure if I changed more than I remember. But the idea is to work out the geometry of the floppy. First read the cylinder, head ^= 1, increment cylinder on head goes zero. Note that you'll reread the boot sector. so the target code is plus 0x200. Code: ;---------------------------------------------------; ; set es and hope that bios does not mess with it.. ; ;---------------------------------------------------; mov ax, 0xffff mov es, ax ;-----------------------; ; prepare for disk read ; ;-----------------------; mov bx, 0x10 ; buffer start xor dh, dh ; head 0 mov cx, 1 ; cilinder 0, sector 1 ;---------------------------; ; read 18 sectors each turn ; ;---------------------------; .track: mov ax, 2 shl 8 or 18 ; read sectors function int 0x13 ; jc .track add bh, 0x24 ; update buffer pointer = bx += 0x2400 add ch, dh ; increment cilinder on dh = 1 btc dx, 0 cmp ch, 3 ; past cilinder 3? jbe .track If I did any mistake(I have _not_ tested), plz point them out to me. |
|||
18 Dec 2004, 23:44 |
|
vid 19 Dec 2004, 12:44
somtething like
Code: mov ax,cs mov ds,ax mov es,ax can be [code] push cs cs pop es ds [code] another not-so-nice trick: You could group most-often used data in 256 bytes, point some addressing register on it (now i am not sure if at beginning ar in the middle) and istead of absolute addressing use register + byte displacement which is one byte shorter (in most case, i think). But this way it will be hardly readable. |
|||
19 Dec 2004, 12:44 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.