Ok I have all the framework done. Programs I want it to do all linked up in another program Done. A c++ program to write to boot sector DONE. All I need now is a simple (less than a gig of text:) way to start the other program from the Original booted program I also read (several) books on makeing a 32bit asembly languige (I just can'spell well) OS I have asked on yahoo answers google everywhere (for all you sas poster not literaly) I am using flat asembly or masm im flexibul and it on windows. Using iPod to type this so no smart grammarical remarks ether. HURRY and I have tried linux AND I DON'T LIKE IT!!!
Zssffssz -4 Junior Poster
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
What I gather out of all this is that you want to be able to write a loader for an executable file, correct? If so, then the reference text you want is Linkers and Loaders by John Levine. It covers several executable file formats in detail, including the DOS and Windows formats. You'll also need to be able to read the file system itself, at least to the point where you can find the file you want to load in, and trying to fit that into a single 512-byte sector is tricky at best.
Mind you, if all you need to be able to do is load a raw binary image, then all you really need is the ability to find the appropriate disk sector(s) and read them into memory. This is a much easier task, and a prerequisite of loading a file in the first place. I have an old sample bootloader which is able to read in the second sector from a disk (it assumes floppy disk, unfortunately, but I'm intending to work on a more advanced version RSN) and transfer control to the loaded binary. I can post this code if you'd like, as it may help you in working out what you're trying to do.
Edited by Schol-R-LEA because: n/a
Zssffssz -4 Junior Poster
Ok that helps, if you can come up with a better/more direct solution from this (not trying to sound rude) I am trying to make an OS but to get around most of the asembly languige and other stuff have the bootloader (already have most the code for it ) load a c++ program as its first and only comand, like the system("a://watever.exe") in c++..
Edit: sorry hat sounded rude but by more direct I mean like easyer to fit in that bootsector I just want to feed my baby the adress of the thing like A:/OS.exe is there there a way to do that?
Edited by Zssffssz because: Missspelling, Clarafacation
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
Unfortunately, if you're writing the boot sector yourself, then you'll need to have some way of loading the OS image file, which means writing at least a minimal version of the loader and enough of the file system to find the file in question. The usual solution is a two-stage boot loader, with the second stage being an assembly program which is loaded from a fixed position on the partition and contains enough of the file system and loader to get the actual boot image loaded. If you are using a 32-bit C++ compiler, you'd also need the code that sets up the GDT and switches to protected mode before jumping to the C++ code, as well.
Rather than rolling your own boot loader, you might consider using an existing multi-boot loader such as GRUB. I know that you had said you didn't want to deal with Linux, but GRUB is not for Linux alone: it should be able to load any conventional operating system, assuming that the image file was compiled to ELF format, or you can use chain-booting to load something in a different format (though in that case you'd still need to be able to load the file itself from scratch). Since it does a lot of the heavy lifting with regards to the memory setup and protected mode state, you'd save a great deal of effort in doing things this way.
I would recommend that you look into the information available at The OS-Dev Wiki, as it covers a great deal of the details of OS design and implementation.
If it helps any, I'm posting my own boot loader for you, in hopes that it might help. It was written for Netwide Assembler, but it should be similar enough to Flat Assembler that the code should at least be intelligible. I tested it using both Bochs and a live floppy disk.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Verbum boot loader for FAT12
; * sets the segments for use in the boot process.
; * loads and verifies the boot image from the second sector,
; then transfers control to it.
;
; Version History (note: build versions not shown)
; pre - June 2002 to February 2004 - early test versions
; * sets segments, loads image from second sector
; v 0.01 - 28 February 2004 Joseph Osako
; * Code base cleaned up
; * Added BPB data for future FAT12 support
; * renamed "Verbum Boot Loader"
; v0.02 - 8 May 2004 Joseph Osako
; * moved existing disk handling into separate functions
; v0.03 - 7 Sept 2006 Joseph Osako
; * resumed work on project. Placed source files under
; version control (SVN)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;constants
;
%define boot_base 0x0000 ; the segment:offset pair for the
%define boot_offset 0x7C00 ; boot code entrypoint
stage2_base equ 0x1000 ; the segment:offset to load
stage2_offset equ 0x0000 ; the second stage into
stack_seg equ 0x9000
stack_top equ 0xFFFC
VBIOS equ 0x10 ; BIOS interrupt vector for video services
ttype equ 0x0E ; print character, teletype mode
NULL equ 0x00 ; end of string marker
CR equ 0x0D ; carriage return
LF equ 0x0A ; line feed
DBIOS equ 0x13 ; BIOS interrupt vector for disk services
disk_reset equ 0x00 ; disk reset service
disk_read equ 0x02 ; disk read service
tries equ 0x03 ; number of times to attempt to access the FDD
reset_failure equ 0x01 ; error code returned on disk reset failure
read_failure equ 0x02 ; error code returned on disk read failure
cyl equ 0x00 ; cylinder to read from
head equ 0x00 ; head to read from
startsector equ 0x02 ; sector to start reading at
numsectors equ 0x01 ; number of sectors to read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; macros
;
%define zero(x) xor x, x
%macro write 1
mov si, %1
call printstr
%endmacro
[bits 16]
[org boot_offset]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; entry - the entrypoint to the code. Make a short jump passed the BPB.
entry:
jmp short entry2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FAT12 Boot Parameter Block - required by filesystem
OEM_ID db "Verb0.02"
Bytes_Per_Sector dw 0x0200
Sectors_Per_Cluster dw 0x0001
Reserved_Sectors dw 0x0001
FATs db 0x02
Root_Entries dw 0x00FF
Sectors_Short dw 0x0B40
Media_Descriptor db 0xF0 ; assumes 3.5" 1.44M disk
Sectors_Per_FAT_Short dw 0x0007
Sectors_Per_Track dw 0x0012
Heads dw 0x02
Hidden_Sectors dd 0x00000000
Sectors_Long dd 0x00000000
Sectors_Per_FAT_Long dd 0x00000000
Extension_Flags dw 0x0000
; extended BPB section
Drive_Number db 0x00
Current_Head db 0x00
BPB_Signature db 0x28
Serial_Number dd 0x000001
Disk_Label db "Verbum Boot" ; must be exactly 11 characters
File_System db "FAT12 " ; must be exactly 8 characters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; entry2 - do a far jump to ensure that you have the desired
; segment:offset location
entry2:
jmp boot_base:start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; start
; This is the real begining of the code. The first order of
; business is clearing the interrupts, then setting the
; segment registers and the stack pointer.
start:
mov ax, stack_seg
cli
mov ss, ax ; and the stack at an arbitrarily high point past ES.
mov sp, stack_top ; put the stack pointer to the top of SS
sti ; reset ints so BIOS calls can be used
mov ax, cs
mov ds, ax ; set DS == CS
write testnumber
mov [bootdrv], dl ; save boot drive info for later use
write reset
; read in the data from disk and load it to ES:BX (already initalized)
write loading
call read_disk
cmp ax, reset_failure
jne good_reset
write reset_failed
jmp short shutdown
good_reset:
cmp ax, read_failure
jne good_read
write read_failed
jmp short shutdown
good_read:
write done
; set up fake return frame for code returning from second stage
mov ax, cs
push ax
mov ax, re_enter
push ax
; fake a jump to the second stage entry point
mov ax, stage2_base
mov es, ax
mov bx, stage2_offset
push es
push bx
write snd_stage
retf
re_enter:
mov ax, cs
mov ds, ax
write returned
shutdown:
write exit
jmp short $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auxilliary functions
;; printstr - prints the string point to by SI
printstr:
push ax
mov ah, ttype ; set function to 'teletype mode'
.print_char:
lodsb ; update byte to print
cmp al, NULL ; test that it isn't NULL
jz short .endstr
int VBIOS ; put character in AL at next cursor position
jmp short .print_char
.endstr:
pop ax
ret
; reset_disk
reset_disk:
mov dl, [bootdrv]
zero (ah)
mov al, disk_reset
int DBIOS
ret
; read_disk
read_disk:
mov cx, tries ; set count of attempts for disk reads
.try_read:
push cx
mov cx, tries ; set count of attempts to reset disk
.try_reset:
call reset_disk
jnc short .read
loop .try_reset ; if the reset fails, try up to three times
mov ax, reset_failure ; if all three fail, set an error code and return
pop cx ; make sure that the stack is correctly aligned
jmp short .end_fail
.read:
mov ax, stage2_base
mov es, ax
mov dl, [bootdrv]
mov ch, cyl ; cylinder
mov dh, head ; head
mov cl, startsector ; first sector
mov al, numsectors ; number of sectors to load
mov ah, disk_read
mov bx, stage2_offset
int DBIOS
jnc short .end_success
pop cx
loop .try_read
mov ax, read_failure ; if attempts to read the disk fail, report error code
jmp short .end_fail
.end_success:
pop cx ; make sure that the stack is correctly aligned
zero(ax)
.end_fail:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; data
testnumber db 'Verbum bootloader v0.03.0', CR, LF, NULL
reset db 'Resetting disk drive.', CR, LF, NULL
loading db 'Loading stage two... ', NULL
done db 'done.', CR, LF, NULL
snd_stage db 'Second stage loaded, proceeding to switch context.', CR, LF, NULL
returned db 'Control returned to first stage, ', NULL
reset_failed db 'Could not reset drive,', NULL
read_failed db 'Could not read second stage, ', NULL
exit db 'system halted.', NULL
bootdrv resb 1 ; byte reserved for boot drive ID number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pad out to 510, and then add the last two bytes needed for a boot disk
space times (0x0200 - 2) - ($-$$) db 0
bootsig dw 0xAA55
The test second stage I used with this to make sure it worked was this:
;;;;;;;;;;;;;;;;;
;; stagetwo.asm - second stage boot loader
;;
;; v 0.01 Joseph Osako 3 June 2002
;; v 0.02 Joseph Osako 7 Sept 2006
;; * restarted project, files place under source control.
;; * Modifications for FAT12 based loader begun.
;;
;;
%define stage2_base 0x1000 ; the segment:offset to load
%define stage2_offset 0x0000 ; the second stage into
VBIOS equ 0x10 ; BIOS interrupt vector for video services
ttype equ 0x0E ; print character, teletype mode
NULL equ 0x00 ; end of string marker
CR equ 0x0D ; carriage return
LF equ 0x0A ; line feed
DBIOS equ 0x13 ; BIOS interrupt vector for disk services
disk_reset equ 0x00 ; disk reset service
disk_read equ 0x02 ; disk read service
tries equ 0x03 ; number of times to attempt to access the FDD
reset_failure equ 0x01 ; error code returned on disk reset failure
read_failure equ 0x02 ; error code returned on disk read failure
cyl equ 0x00 ; cylinder to read from
head equ 0x00 ; head to read from
startsector equ 0x02 ; sector to start reading at
numsectors equ 0x01 ; number of sectors to read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; macros
;
%define zero(x) xor x, x
%macro write 1
mov si, %1
call printstr
%endmacro
[bits 16]
[org stage2_offset]
entry:
mov ax, cs
mov ds, ax
write success
; jmp $
; 'return' to the first stage via a faked call frame set up earlier
retf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auxilliary functions
;; printstr - prints the string point to by SI
printstr:
push ax
mov ah, ttype ; set function to 'teletype mode'
.print_char:
lodsb ; update byte to print
cmp al, NULL ; test that it isn't NULL
jz short .endstr
int VBIOS ; put character in AL at next cursor position
jmp short .print_char
.endstr:
pop ax
ret
; reset_disk
reset_disk:
mov dl, [bootdrv]
zero (ah)
mov al, disk_reset
int DBIOS
ret
;;;;;;;;;;;;;;;;;;;;;;;;;
;; data
success db 'Control successfully transferred to second stage.', CR, LF, NULL
bootdrv db 0x00 ; byte reserved for boot drive ID number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pad out to 512
space times 0x0200 - ($-$$) db 0
Edited by Schol-R-LEA because: n/a
Zssffssz -4 Junior Poster
Ok just one more question my c++ write to bootsector program had sOme probles during a test the other day (I have literaly 100 floppy disks and got them cheap so getting it to boot from usb/cd is not my consern) Is there a standered 3rd-party (like 7zip above a day to day program but If theres a micrsoft one I'll take it also I don't want to modiphy the MS-DOS files on my computer I know I sound picky but I just love DOS. So... Can't wait to hear......
Edit:Sorry as you can clearly see I am made for c++ and not asembly but do I put the .bin or the .asm on my floppy too I have not found an answer on the other question ether and thanks in advance!!
Edited by Zssffssz because: To not double post
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
There are two programs available for this purpose, RawWrite and DD. both can be gotten from chrysocome.net for free, and while dd is a bit of a pain to use, RawWrite is fairly easy.
Mind you, even with large numbers of floppies, you might want to do some testing using Bochs and a file image, which would give a much faster turn-around during debugging. You can't use RawWrite with disk images, AFAIK, but dd will do the trick fairly easily.
As for which to load to the boot sector, you definitely want the binary file, not the source file.
Edited by Schol-R-LEA because: n/a
Zssffssz -4 Junior Poster
Ok I thought I had software for this but I dont where do I get a simple img creater/converter for floppies the one I have is to iso. I know I dont need one for one file but for the other programs n stuff.. Oh and if there is an exe2bin (why does that sound so familer) where can I get it because acording to your above post. That would be easyer. I think I got one with Digital Mars but it didn't work so thankss again in advance again.
Edited by Zssffssz because: Fixed then unfixed, to not double post
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
As it happens, the dd utility I mentioned earlier is convenient for this purpose as well, as you can use it to copy individual files into another file which can act as an image file.
Exe2Bin should be part of the MASM package, if you have that, at least it used to be. As I said, I use NASM, which can generate binaries for different formats directly, so I haven't needed that particular utility.
Zssffssz -4 Junior Poster
Well as Flat Asembler is givging me grif so I hqve to use the flat asembler for getting the asm file then half of nasam to get the bin file <usless info| So how would I do that in dd?
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
I'm not sure what you're asking, but I assume you mean, how would you create a disk image using dd? As it happens, the home page for the Windows version describes exactly how to do this. First, you need to make a blank image file, which can easily be done by copying the image of an empty floppy:
dd if=\\.\a: of=blankdisk.img bs=1440k
You would probably want to save this blank original and make copies of it for your actual disk images. Assuming you've made a copy named 'boot.img', you can then copy your binary to the beginning of the file like so:
dd if=kernel.bin of=boot.img
Finally, you can write this image file to the floppy like so:
dd if=boot.img of=\\.\a: bs=1440k
I hope this is what you needed, your previous post wasn't terribly clear.
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
You can also use the bximage utility which comes with Bochs to create blank floppy disk images. I'd nearly forgotten about that.
Also, what sort of trouble are you having with FASM? Is it with the assembler itself (the command-line tool, that is) or the editor that comes with it?
Edited by Schol-R-LEA because: n/a
Zssffssz -4 Junior Poster
Ok the problem is in flat asembler it has a problem with the way your boot program is written so I just save the asm file and put it through nasm (not fasm... mabey) asm to bin thing and it works. In twelve hours I will post this as answred so all comments should be posted by then!
Zssffssz -4 Junior Poster
Ok all this is fine and dandy but how do I start the exe after your bootstuff is on the diskett and do I combine your two boots to One bin?
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
To answer the second question first, yes, you'll want to copy both of the binary sections into the boot image, then copy that to the floppy. Assuming you have a blank image file already, and have already assembled the source files to the binaries, the following batch file should do the trick:
copy blankdisk.img boot.img
dd count=1 if=verbum.bin of=boot.img seek=0
dd count=1 if=stagetwo.bin of=boot.img seek=1
This copies the blank disk image to the file being created, then copies the first binary into the boot sector, then copies the second stage into the second sector of the disk image. You can then use the following batch command to copy the boot.img file to the floppy:
dd if=boot.img of=\\.\a: bs=1440k
I recommend keeping them as separate batch files, as you may want to create disk images without writing to a disk immediately (e.g., if you are using an emulator such as Bochs for testing), and conversely you might want to be able to write to a disk without rebuilding the whole file every time.
As for the first question, well, as I've said before, what I have here is just the starting point. You'll need to have code in the second part of the boot loader which can read the filesystem on the disk to find the location of the file being loaded, then be able to not only read the file into memory, but be able to interpret the file format and load the linked file into a suitable location in memory. That's assuming you find a real-mode C++ compiler to work with which can produce executable files without the normal headers; if you are using a 32-bit compiler, then the boot loader will need to set up high memory and switch the system into protected mode before you load the file, otherwise it won't run correctly.
All of these steps depend on a lot of decisions which you need to make about the kind of system you want to design. As the OS Dev wiki says, there are no tutorials for this sort of thing; it is your operating system, so you have to set the rules. At the very least, you need to know what file system you're going to use, and what executable format you are using.
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster
Given your stated preference for MS-DOS, you might want to start with FAT12 as your floppy disk filesystem, and go from there. FAT12 has the advantage of being easy to implement and designed for bootable systems, and has the added advantage that the files would be readable by Windows, if you do it right.
Edited by Schol-R-LEA because: n/a
Zssffssz -4 Junior Poster
Thank you with all my heart! You should be promoted! I downloaded a asembly IO header (%define) so thanks from the posts Ive read you are the smartest person on this fourm in asembly languige!!
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.