Page 1 of 1

Bootloader + OS... Creates disk image to boot from bochs.

Posted: Wed Nov 30, 2016 8:55 am
by rgmf
Helle folks,

I created a very simple bootloader. The only thing this bootloader does is show a message.

To run with Bochs this bootloader I create a bin file:
as --32 -o bootloader.o bootloader.s
ld -Ttext=0x7c00 -melf_i386 bootloader.o -o bootloader.elf
objcopy -O binary bootloader.elf bootloader.bin

Now I am trying to load a really simple OS from this bootloader using BIOS int. The stupid OS is:

Code: Select all

   .code16

  .section .text
  mov $0x5, %dx
The question is. How can I create a disk image with bootloader inside the first 512 bytes (first sector) and the OS in the second sector?

From bootloader I am trying to load the second sector (the OS) in 0x1000 memory position.

Thank you.

PS/ I am trying follow this example: https://github.com/appusajeev/os-dev-16 but I get "Error loading OS sector".

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Wed Nov 30, 2016 9:06 am
by SpyderTL
There's really no reason to build an ELF executable, link it, and then strip it away with objcopy.

You can just compile your assembly file directly into a bin file. Then just copy the bytes from that file to the first sector of your disk (or disk image).

You can also just compile your kernel into a bin file, and copy the bytes from it to the second sector of your disk.

Using an ELF executable is jumping about 4 steps ahead of where you are, right now.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Wed Nov 30, 2016 11:37 am
by Octocontrabass
rgmf wrote:PS/ I am trying follow this example: https://github.com/appusajeev/os-dev-16 but I get "Error loading OS sector".
That's not a very good example. It uses a hardcoded disk number instead of the disk number passed by the BIOS, so it will fail when the disk number is different. It doesn't have a BPB or partition table, so some BIOSes will corrupt the code if it's on a USB flash drive. It never sets SS:SP, so there may be stack issues on some systems. It never clears DF, so the string instructions may not run in the correct direction.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Wed Nov 30, 2016 11:54 am
by Schol-R-LEA
To answer the specific question, my recommendation is to first create a blank image file (e.g., one filled with zeroes) of the desired disk size, then use dd or something similar to copy the sectors into the image file.

Code: Select all

dd if=my_boot_sector.bin of=my_boot_image.img
dd if=my_second_stage.bin of=my_boot_image.img seek=1 obs=<size-of-your-second-stage-in-bytes>
the 'seek=n' option tells it to write to the file starting at an offset of n sectors.

You can also use dd to create the file itself, though Bochs has a utility (bximage) for this purpose anyway. This how-to explains the process in detail.

That having been said, both Spyder and Octocontrabass are dead on about the assembler and the tutorial.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Wed Nov 30, 2016 3:01 pm
by rgmf
SpyderTL wrote:There's really no reason to build an ELF executable, link it, and then strip it away with objcopy.

You can just compile your assembly file directly into a bin file. Then just copy the bytes from that file to the first sector of your disk (or disk image).

You can also just compile your kernel into a bin file, and copy the bytes from it to the second sector of your disk.

Using an ELF executable is jumping about 4 steps ahead of where you are, right now.
Ok, I understand. Thank you very much.

Now I compile my assembly file directoy into a bin file (or think so):

Code: Select all

as --32 -o bootloader.o bootloader.s
ld -Ttext=0x7c00 --oformat binary -melf_i386 bootloader.o -o bootloader.bin
 
Octocontrabass wrote:
rgmf wrote:PS/ I am trying follow this example: https://github.com/appusajeev/os-dev-16 but I get "Error loading OS sector".
That's not a very good example. It uses a hardcoded disk number instead of the disk number passed by the BIOS, so it will fail when the disk number is different. It doesn't have a BPB or partition table, so some BIOSes will corrupt the code if it's on a USB flash drive. It never sets SS:SP, so there may be stack issues on some systems. It never clears DF, so the string instructions may not run in the correct direction.
The only thing I know about your comment is that I need to study and work a lot if I want to write a hobby bootloader+OS :lol:

Anyway you gave me an idea of the problem.

Thank you :D
Schol-R-LEA wrote:To answer the specific question, my recommendation is to first create a blank image file (e.g., one filled with zeroes) of the desired disk size, then use dd or something similar to copy the sectors into the image file.

Code: Select all

dd if=my_boot_sector.bin of=my_boot_image.img
dd if=my_second_stage.bin of=my_boot_image.img seek=1 obs=<size-of-your-second-stage-in-bytes>
the 'seek=n' option tells it to write to the file starting at an offset of n sectors.

You can also use dd to create the file itself, though Bochs has a utility (bximage) for this purpose anyway. This how-to explains the process in detail.

That having been said, both Spyder and Octocontrabass are dead on about the assembler and the tutorial.
I am going to do it with dd. Thank you for the example and for the link ;) That answers my question :D

Regards.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 9:01 am
by rgmf
SpyderTL wrote:There's really no reason to build an ELF executable, link it, and then strip it away with objcopy...
Octocontrabass wrote: That's not a very good example...
Schol-R-LEA wrote:To answer the specific question...
I'm pretty frustated because I cannot solve the problem :oops: . Can you help out? This is my bootstrap... It should load the second sector to 0x2000 address. Why "load error" is raise?

Code: Select all

  .code16

  .section .text
  .globl _start
_start:
  cli

  # Reading sector...
  mov $0x02, %ah     # Second sector.
  mov $0x01, %al
  mov $0x00, %ch
  mov $0x02, %cl
  mov $0x00, %dh
  mov $0x00, %dl
  mov $0x2000, %bx  # Address where sector will be loaded.
  mov %bx, %es
  mov 0x0000, %bx
readsector:
  int $0x13
  jc error

  mov $0x2000, %ax
  mov %ax, %es

  jmp %es:0x0000

done:
  hlt

error:
  mov $msg_loadsector_err, %si
  call print
  ret

# Print with BIOS int.
print:
  mov %sp, %bp
  mov $0x0e, %ah
print_loop:
  lodsb
  or %al, %al 
  jz print_done

  int $0x10
  jmp print_loop
print_done:
  mov %bp, %sp
  ret

  # Messages.
msg_loadsector_err:
  .ascii "Error loading sector\n\r\0"


  # MBR signature.
  .org 510
  .word 0xAA55
Thank you.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 10:59 am
by Octocontrabass
Octocontrabass wrote:It uses a hardcoded disk number instead of the disk number passed by the BIOS, so it will fail when the disk number is different. It doesn't have a BPB or partition table, so some BIOSes will corrupt the code if it's on a USB flash drive. It never sets SS:SP, so there may be stack issues on some systems. It never clears DF, so the string instructions may not run in the correct direction.
You copied all of these bugs from the example. I wouldn't be surprised if one of them is the cause of your problem.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 11:10 am
by Schol-R-LEA
Before addressing the possible cause of the problem, I would like to recommend using the .set or .equ directives to give names to all the magic numbers you are using now. Her are the relevant ones I used in Verbum (my own practice boot loader) converted to AT&T syntax (at least, I hope I did that correctly):

Code: Select all

         .equ stage2_base, 0x2000      # the segment:offset to load 
         .equ stage2_offset, 0x0000	# the second stage into

         .equ DBIOS, 0x13        # BIOS interrupt vector for disk services
         .equ disk_reset, 0x00        # disk reset service
         .equ disk_read, 0x02        # disk read service 
         .equ tries, 0x03        # number of times to attempt to access the FDD
         .equ reset_failure, 0x01        # error code returned on disk reset failure
         .equ read_failure, 0x02        # error code returned on disk read failure

         .equ stage2_cyl , 0x00        # cylinder to read from
         .equ stage2_head, 0x00        # head to read from
         .equ start_sector, 0x02        # sector to start reading at
         .equ num_sectors, 0x01        # number of sectors to read
When applied to your code, it would be:

Code: Select all

  # Reading sector...
        mov $disk_read, %ah     # Second sector.
        mov $num_sectors, %al
        mov $stage2_cyl, %ch
        mov $start_sector, %cl
        mov $stage2_head, %dh
        mov $0x00, %dl
        mov $stage2_base, %bx  # Address where sector will be loaded.
        mov %bx, %es
        mov $stage2_offset, %bx
readsector:
        int $DBIOS
        jc error

        mov $stage2_base, %ax
        mov %ax, %es
As for the error, I suspect it is because you are hard-coding the drive identifier rather than getting it from the initial value that the BIOS put into %dl on loading - you can't say for certain which drive it will be, but AFAIK that ID number will never be zero. If you can't be certain that the value of DL hasn't been changed before you use it, you should save the value in a temporary data address for retrieval.

Code: Select all

       # in your start-up code after you have your 
        # seg registers set but before anything else
        movb $dl, (bootdrv)

       # then replace 
       #         mov $0x00, %dl
       # with
        movb (bootdrv), %dl

# add this after the end of the code to define some storage
    .section .bss
        .lcomm bootdrv, 1 
    .section
I can't say for certain if this will fix it or not, but I think it would be advisable.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 11:14 am
by bzt
Hi,

You should use the extended read function instead: http://www.ctyme.com/intr/rb-0708.htm
Here's an example on how to use it: https://github.com/bztsrc/osz/blob/mast ... 64/mbr.asm

Good luck,
bzt

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 5:38 pm
by azblue
Schol-R-LEA wrote:
As for the error, I suspect it is because you are hard-coding the drive identifier rather than getting it from the initial value that the BIOS put into %dl on loading - you can't say for certain which drive it will be, but AFAIK that ID number will never be zero.
Yes and no.
If you're dealing with a real floppy (rather than an emulated floppy on a USB or CD), I believe the ID is always zero.

But on modern hardware that doesn't have a real floppy, yes, you're right; you won't have an ID of zero.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Fri Dec 02, 2016 5:39 pm
by azblue
bzt wrote:Hi,

You should use the extended read function instead: http://www.ctyme.com/intr/rb-0708.htm
Here's an example on how to use it: https://github.com/bztsrc/osz/blob/mast ... 64/mbr.asm

Good luck,
bzt
If he's reading a floppy (real or emulated) as his code implies, he can't us LBA functions.

Re: Bootloader + OS... Creates disk image to boot from bochs

Posted: Sun Dec 04, 2016 9:11 am
by rgmf
Thank you very much to everyone.

After reading all your comments I think my problem is a knowledge issue. So I am going to read about BIOS and its interrupts and functions.
Octocontrabass wrote:You copied all of these bugs from the example. I wouldn't be surprised if one of them is the cause of your problem.
You are right, sorry. I didn't understand hardcoded meaning.

Regards.