flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Boot sector example that loads a secondary binary file. Goto page 1, 2 Next |
Author |
|
Mac2004 08 Jan 2007, 18:26
I saw somewhere in this board questions about secondary file loading by a boot sector.
Here's my very simple boot sector example that loads a binary file into memory and executes it. I have kept the source as simple as possible because it should serve as an example. I hope somebody can find it useful for hobby OS development. I have included the whole package in the zip-file below. So here's the boot sector code: Code: ;============================================================================= ; Boot loader that loads a secondary file and executes it. ; Written in 2007 by Mac2004. ; ; This code has been kept intentionally VERY simple and all extra stuff ; have been left out. I hope this will help people trying to write their ; own OS's. Having a working boot loader is a essential towards own OS. ; The boot sector loads a binary file from sector 2 to 18 and then ; executes it. ; ; You use this code only at you own risk. I don't take any responsibility ; what happens to your data etc. If you don't understand this code, ; don't use it! ; ; ; installation instructions. ;---------------------------- ; You can write boot sector and the secondary file on disk with Partcopy ; which can be found through Google. ; ; pcopy min_boot.bin 0 200 -f0 --> write boot sector code on floppy a: ; ; pcopy 2nd_file.bin 0 2200 -f0 200 --> write secondary file right ; after the boot sector a: ; ; version history: ; ------------------ ; ; 2007-21-3 fixed a stack pointer bug. ;============================================================================= org 7C00h ;bios puts us here! use16 ;use 16-bit code code_start: jmp start nop ;fasm requires this no-operation command ;======================================== ; Main boot sector code starts from here. ;======================================== start: push cs pop ds ;ds=cs (0) ; Setup the stack. ;---------------- cli ; Disable interrupts mov ax, 0x9000 ; Put stack at 0x90000 mov ss, ax ; SS = 9000 and ; mov sp, 0 ; mov sp, 0F800h ; set stack pointer to 0xf800 sti ; Enable interrupts mov byte[bootdrv],dl ;save the boot drive number ;print that we're alive! ;----------------------- mov si, loading_msg ; Print a message call putstr ;----------------------- ;Load 17 sectors! ;----------------------- .load: mov ax,0x1000 mov es,ax ;set segment to 0x1000 mov bx,0 ;offset= 0 mov dl,byte[bootdrv] mov dh,0 ;set Head mov cl,2 ;set Sector mov ch,0 ;set track mov ah,2 ;bios int 0x13 function ah=2, read sectors mov al,17 ;read one sector int 0x13 ;call bios jnc ok_load_setup ;if ok - continue mov si, error_msg ; Print a message call putstr jmp .load ok_load_setup: mov si, ok_msg ; Print a message call putstr ;--------------------------- ; Jump to the loaded program ;--------------------------- mov sp, 0 ; Restore stack pointer mov ax, 0x1000 mov es, ax mov ds, ax push word 0x1000 push word 0 retf ;================================================== ;Procedures used by the boot sector code. ;================================================== ;*********************************************************** ; putstr: Print a 0-terminated string (SI=pointer to string) ; ; Input: SI=pointer to string. ; ; Output: -- ;*********************************************************** putstr: lodsb or al,al jz putstrd mov ah,0x0E mov bx,0x0007 int 0x10 jmp putstr putstrd: retn ;================================================== ;Variables used by the boot sector code. ;================================================== bootdrv db 0 ; bootdrive number loading_msg db 'Booting...',13,10,0 ok_msg db 'OK!',13,10,0 error_msg db 'Error!',13,10,0 ;//////////////////////////////////////////////////////////////////// ;//////////////////////////////////////////////////////////////////// ;fill rest of boot sector to meet exactly 512 bytes rb 7C00h+512-2-$ ;fill up to the boot record signature db 055h,0AAh ;the signature itself and here's the secondary file code Code: ;===================================================================== ; An example of secondary file to be loaded by the boot loader. ; Written in 2007 by Mac2004. ; ; You use this code only at you own risk. ; If you don't understand this code, don't use it! ;===================================================================== mov ax, 1000h ; Update segment registers mov ds, ax mov es, ax ;A quick hack to reserve some extra space to see ;whether multiple sector loading works or not. ;----------------------------------------------- jmp reserve_space_dummy reservation: times 6*512 db 0 reserve_space_dummy: ;Print something to show that we truly are here. ;----------------------------------------------- mov si, msg ; Print a message call putstr mov ax,206 mov cl,'3' mov ch,' ' call RM_PutChar hang: ; Just hang jmp hang ;**************************************************************** ; putstr: Print a 0-terminated string (SI=pointer to string) ; ; Input: SI=pointer to string ; ; Output: -- ;**************************************************************** putstr: lodsb or al,al jz .putstrd mov ah,0x0E mov bx,0x0007 int 0x10 jmp putstr .putstrd: ret ;************************************************************ ; RM_PutChar- Prints one text mode char at specified ; position. ; ; input: ax- startaddress in bytes ; cx - char to be printed ; output: -- ;************************************************************ RM_PutChar: push es pusha mov dx,ax ;save Startaddress push ax mov ax,0xB800 mov es, ax pop ax mov bx,0 add ax,dx ;write actual char ;------------------ add bx, ax ;get start position mov [es:bx],cx ;print char shr bx,1 ;calculate correct x-position for cursor .done: popa pop es ret ; end of procedure msg db 'Greetings from the secondary file....',13,10,0
Last edited by Mac2004 on 15 Nov 2007, 19:37; edited 3 times in total |
|||||||||||
08 Jan 2007, 18:26 |
|
vsoly 20 Mar 2007, 08:29
Hello!
The example dont work in Bochs. I compile all files but work only boot file, it write "OK". Maybe in Bochs kernel file is out of 17 sectors? |
|||
20 Mar 2007, 08:29 |
|
vsoly 20 Mar 2007, 13:42
It is possible call kernel by filename, or it does not work? If it possible, what method is better, by filename or by sector number?
|
|||
20 Mar 2007, 13:42 |
|
Mac2004 20 Mar 2007, 16:25
Thank you all for testing!
vsoly: I didn't test my boot sector with Bochs, because i don't have it. I may have a fix for your problem. I found out that my boot code was not working properly on one pc I bought after posting this example. I came to realize that the problem was with setting the sp to zero. It worked with every other pc I tested, but not with last pc I bought. original code: Code: ; Setup the stack. ;---------------- cli ; Disable interrupts mov ax, 0x9000 ; Put stack at 0x90000 mov ss, ax ; SS = 9000 and mov sp, 0 ; SP = 0000 => Stack = 90000 <==(PROBLEM) sti ; Enable interrupts the solution: Code: ; Setup the stack. ;---------------- cli ; Disable interrupts mov ax, 0x9000 ; Put stack at 0x90000 mov ss, ax ; SS = 9000 and ; mov sp, 0 ; SP = 0000 => Stack = 90000 mov sp,0F800h ; offset for stack sti ; Enable interrupts After loading the secondary file you need set the sp back zero before jumping to the next level. Rest of the boot code after all sectors are loaded: Code: ;---------------------------------- ; Jump to the loaded program ;---------------------------------- mov sp, 0 ; Restore stack pointer back to zero mov ax, 0x1000 mov es, ax mov ds, ax push word 0x1000 push word 0 retf Just let me know if this fix will work with the bochs. If it works I will update the example code and the zip- package as well regards, Mac2004 Last edited by Mac2004 on 20 Mar 2007, 17:23; edited 1 time in total |
|||
20 Mar 2007, 16:25 |
|
Mac2004 20 Mar 2007, 17:00
vsoly wrote: It is possible call kernel by filename, or it does not work? If it possible, what method is better, by filename or by sector number? When loading a binary file, bios only loads a bunch of sectors from disk to memory. At this point there's no true file system present. Setting up the file system is a task of the secondary file which is loaded by the boot sector. I hope this will help you I guess you have seen some examples that load fat12 or fat16 files. My example does not use fat due to the fact that i want use my own file system. regards, Mac2004 Last edited by Mac2004 on 21 Mar 2007, 15:23; edited 2 times in total |
|||
20 Mar 2007, 17:00 |
|
Mac2004 20 Mar 2007, 17:22
Quote: It's good practice to reserve the 2nd boot sector. Its also good practice to fill out the partition info that is reserved by the BIOS. ie: the 'BIOS Parameter Block'. Various INT 13h handlers will look for information here. I agree with you about the 2nd boot sector As fas as I know BIOS Parameter Block is a DOS thing and I'am not using DOS stuff here. Adding BPB to my example is not very complicated. Thanx for you comments, Hayden! regards, Mac2004 |
|||
20 Mar 2007, 17:22 |
|
vsoly 21 Mar 2007, 05:32
Unfortunelly dont work under Bochs. I think, what under Bochs cannot point second sector. The kernel file is placed with easy "copy->paste" operation.
About FAT loading! Thanks, good idea |
|||
21 Mar 2007, 05:32 |
|
Mac2004 21 Mar 2007, 15:07
Quote:
Have you tried my example with real pc instead of Bochs? I will update my example with the above stack pointer fix. I'am not very familiar with the Bochs, because I prefer real pc's. regards Mac2004 |
|||
21 Mar 2007, 15:07 |
|
Mac2004 21 Mar 2007, 16:05
I have updated the code and the zip package. Updated version includes the stack pointer fix.
regards, Mac2004 |
|||
21 Mar 2007, 16:05 |
|
hckr83 24 Mar 2007, 15:53
I have made a very simple FS that is extremely easy to implement that you may be intrested in
also, if you use ABS and do one sector at a time, it should be simple to fix the sector limit |
|||
24 Mar 2007, 15:53 |
|
Mac2004 25 Mar 2007, 12:49
Quote:
Yes, please. Improvements are by all means welcome. Quote:
It seems that some pc's have problems with doing multiple sector loading?? My code worked with all the pc's (6) I have tested. Perhaps it is time to make a one sector at the time loader as well? regards, Mac2004 |
|||
25 Mar 2007, 12:49 |
|
Hayden 25 Mar 2007, 16:32
Windows 2k/XP does lots of single sector reads at bootup even when it has checked for IBM/MS Extended read capabilties. ( dont know why )
If there are hard drives present on the system you might want to try interrupt 40h for floppy disk reads under bochs. |
|||
25 Mar 2007, 16:32 |
|
Mac2004 25 Mar 2007, 20:09
Quote:
Perhaps some pc's cannot handle correctly multiple sector loading? I have updated my boot sector. This version loads 1 sector at the time. Please see the attached file.
Last edited by Mac2004 on 15 Nov 2007, 19:43; edited 1 time in total |
|||||||||||
25 Mar 2007, 20:09 |
|
hckr83 25 Mar 2007, 21:16
I have yet to make a spec thing for my FS, but I geuss I could write a bit of a draft here..
basically, it doesn't tell any info about the current device, Though it is usually assumed that it is on a 1.44mb floppy There are no "system" sectors like there are in most OS's, this is designed so that it could be done anything with.. There is no index for finding files, you must scan through the whole floppy, when there are a lot of files this can be VERY slow, but for a simple thing with a few files it should work relatively well The only way to identify if a sector is a start of a file, empty, or data of a file, is to check the very first byte of the sector(this starts at abs sector 2) 0x3C means start of file 0x2C means empty space 0x1C means reserved any other value is assumed to be a corrupted sector For the start of a file, the file info is stored like this, - 0x3C - word value of how many immediately following sectors - string of 16 chars for the filename(null terminated) - dword value of how many actual bytes in the file(this need not be used for a simple boot sector and you should use the above) - attribute byte, in this format(going from bit 7 to bit 0 using | as a seperator) read only|hidden|system|do not move me(for defrag apps)| everything else is unused -now just the data of the file note that no value is placed in the first byte of sectors in the "data" of a file, this is only placed at the first file sector free space info is stored like this: - 0x2C - word value of how many immediately following sectors are free reserved space info is stored like this: -0x1C - word value of how many immediately following sectors are free It is really quite simple now isn't it? you can add your own index file if wanted or something, whatever the only bad thing about this design is that it doesn't support fragmentation, so a "space alignment" program may need to be made to correctly align spots of free space so as to make more free space readily available also note that nothing in the boot sector is needed to be specified like in fat and most other FSs..(though this forces you to assume a lot) |
|||
25 Mar 2007, 21:16 |
|
Mac2004 26 Mar 2007, 15:05
hckr83: I have got two ideas to improve your file system:
1) Every file could contain a link (sector number) to next file start. This improves searching because only one sector in each file needs to be read in order to find the next file. or/and 2) A simple table of sectors and size placed on the first sectors of disk. This allows faster file search to be implemented. regards, Mac2004 |
|||
26 Mar 2007, 15:05 |
|
Mac2004 19 Sep 2010, 17:18
vsoly wrote: Hello! I forgot to update this earlier: Bochs and other emulators seem to require a full 1.44MB floppy image in order to work. So the assembled code must be padded to fit exactly the 1.44mb size. Regards Mac2004 |
|||
19 Sep 2010, 17:18 |
|
baldr 20 Sep 2010, 17:45
Mac2004 wrote: Bochs and other emulators seem to require a full 1.44MB floppy image in order to work. |
|||
20 Sep 2010, 17:45 |
|
egos 20 Sep 2010, 18:52
baldr is right. Bochs works on shortened disk images perfectly.
|
|||
20 Sep 2010, 18:52 |
|
edfed 20 Sep 2010, 19:58
it is also possible to load a .com program.
the algo is: Code: copy bootsector to 0:7E00h jmp 0:7E00h create PSP code at 1000h:0 load .com code at PSP+100h far call 1000h:0 load C: bootsector at 0:7C00h jmp 0:7C00h PSP: init segments call near 100h far ret the PSP code is located at cs:0 the PSP command line parameter is at cs:80h, and is empty there. the .com code is located at cs:100h (org 100h) the .com code exits with a simple near ret the PSP exits with a far ret Code: ;version 13/05/2008 15:31;;;;; comload: use16 org 7c00h boot: cld cli mov ax,0800h mov ss,ax mov sp,7ff0h sti push cs word 0b800h pop fs ds mov [root+disk.drv],dl mov cx,512 mov ax,0020h mov es,ax mov di,07c00h mov si,di rep movsb jmp 20h:@f @@: push cs pop ds mov ax,[root.ptr+fptr.seg] mov es,ax xor di,di mov cx,psp.end-psp mov si,psp rep movsb @@: mov si,root call disk mov dl,[si+disk.drv] mov bx,[si+disk.ptr] mov word[bx+fptr.off],0 call far dword[bx+fptr.off] mov word[bx+fptr.off],100h jmp @b ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;; FUNCTIONS ;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; psp: push ds es fs gs mov ax,cs mov ds,ax mov ax,100h call ax pop gs fs es ds mov dword[fs:0],'abcd' retf .end: include '../fool/disk.inc' include '../fool/fptr.inc' ;align 4 macro Disk cmd,drv,cnt,chs,ptr { dd disk db cmd,drv dw cnt dd chs,ptr,0,0 } root: Disk disk.read,disk.fd0,1,2,.ptr .ptr: dd 1000h:0100h,512 free = 510-(padding-$$) padding rb free dw 0aa55h bits = 12 repeat bits/4 d = '0' + free shr (bits-%*4) and 0Fh if d > '9' d = d + 'A'-'9'-1 end if display d end repeat display 'h free bytes ',13,10 disk.inc this is the only way i found to play with BIOS sectors without any error. it's huge, but it is fiable. Code: disk: .call=0 ; function .cmd=4 ; drive command read or write .drv=5 ; drive number, BIOS based .cnt=6 ; count of sectors .s=8 ; starting sector .h=9 ; starting head .c=10 ; starting cylinder .ptr=12 .s0=16 ; number of sectors .h0=17 ; number of heads .c0=18 ; number of cylinders .lba0=20 ; number of lba sectors .read=2 ; .write=3 ; .fd0=0 ; .fd1=1 ; .fd2=2 ; .fd3=3 ; .hd0=80h ; .hd1=81h ; .hd2=82h ; .hd3=83h ; push esi edi call .id mov edi,[si+.ptr] or edi,edi jne @f pop edi esi ret @@: mov eax,[di+fptr.size] shr eax,1 ; ah is holding the sector count jc .1 or al,al ; if the mod 512 is not nul je @f .1: inc ah ; there is one extra sector to write @@: movzx eax,ah mov [si+.cnt],ax ; sectors to write mov al,[si+.s] mov ah,[si+.h] mov bx,[si+.c] mov cx,[si+.cnt] mov dx,[di+fptr.off] push ax bx cx dx es .next: dec word[si+.cnt] jl .end push ax bx mov cx,bx mov bl,cl mov cl,ch mov ch,bl shl cl,6 and cl,0c0h or cl,al mov dh,ah pushaw call .atom jnc @f popaw pushaw call .atom jnc @f popaw pushaw call .atom jnc @f .error: popaw pop bx ax clc jmp .tchao @@: add word[di+fptr.off],512 popaw pop bx ax inc al cmp al,[si+.s0] jne @f mov al,1 inc ah cmp ah,[si+.h0] jl @f mov ah,0 inc bx cmp bx,[si+.c0] jl .next mov bx,0 @@: jmp .next .atom: call .reset mov ax,[di+fptr.seg] or ax,ax jne @f mov ax,ds @@: mov es,ax mov bx,[di+fptr.off] mov ah,[si+.cmd] mov al,1 int 13h ret .reset: mov dl,[si+.drv] mov ah,0 int 13h ret @@: mov word[si+.c0],0 mov byte[si+.h0],0 mov byte[si+.s0],0 mov dword[si+.lba0],0 clc ret .id: cmp byte[si+.drv],0 jns .floppy call .reset jc @b mov ah,8 mov dl,[si+.drv] int 13h inc dh mov [si+.h0],dh mov bx,cx and cl,not 0c0h mov [si+.s0],cl mov cl,ch mov ch,bl shr ch,6 inc cx mov [si+.c0],cx @@: movzx eax,byte[si+.s0] movzx ebx,byte[si+.h0] movzx ecx,word[si+.c0] imul eax,ebx imul eax,ecx mov [si+.lba0],eax stc ret .floppy: mov word[si+.c0],80 mov byte[si+.h0],2 mov byte[si+.s0],18 jmp @b .end: stc .tchao: pop es dx cx bx ax mov [si+.s],al mov [si+.h],ah mov [si+.c],bx mov [di+fptr.off],dx mov [si+.cnt],cx cmp byte[si+.drv],0 jl @f mov dx,3f2h out dx,al @@: pop edi esi ret fptr.inc this is my handle for memory zones in real mode. a single 8 bytes structure. a far pointer, and a size counter. Code: fptr: .off=0 .seg=2 .size=4 reference to a fptr is made by loading it's local adress in ds. Code: fptr0: dd 1000h:0,0ffffh ... mov eax,fptr0 call far dword[eax] ... at home, bochs is ok to load it, launch .com and return. problem to load c:/boot i just propose as a challenge... create the official fasm example for bootloader, different of the fat12 loader still present. a collaborative project to bring the ultimate boot loader for os construction under fasm.. anyone interested? |
|||
20 Sep 2010, 19:58 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.