[haiku-development] GPT boot loader for Haiku (the start of)

  • From: André Braga <meianoite@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Wed, 10 Jun 2009 02:34:17 -0300

I modified the sys/boot/i386/pmbr/pmbr.s that I've mentioned a number
of times before to load stage1 from a makebootable-ed Haiku partition.
For those who don't run FreeBSD (boo!), here's a pointer to their SVN:
http://svn.freebsd.org/base/head/sys/boot/i386/pmbr/pmbr.s

For ease of reference, please consult
http://fxr.watson.org/fxr/source/boot/i386/pmbr/pmbr.s for the rest of
this email.

I patched pmbr.s so that it looks for the BFS UUID and reads only two
sectors from beginning of the Haiku partition (i.e., stage1) instead
of the whole boot partition as in the original code, and boots from
it. It worked Just Fine(tm).

However, I couldn't manage make it read those two sectors cleanly. I
intended to modify the 'read' subroutine (#L162) to request for two
sectors on the Extended Read packet (#L166, changing the parameter to
$0x2); subsequently, I killed lines #L126-#L132 and #L134-#L141, as
they were no longer necessary.

Or so I thought, because if I did that I ended up with just a blinking
cursor on my screen. So I resorted to the ugliest hack, that is, I
duplicated the code for reading one sector. Which works. :P

Actually, I intended to pass the number of sectors to be read as a
parameter on the stack, but since I couldn't even get it to work with
2 sectors hardcoded on the packet...

I have only a superficial understanding of x86 assembly, and BIOS
calls are just not an area I have any knowledge of. Could some kind
soul please check what the hell am I missing here?


Thanks,
A.



-- 
One last piece of advice: "ice".

----------------------------------------------------------------------------

After patching, compile with:
as -o haikugpt.o haikugpt.s
ld -N -e start -Ttext 0x600 -S --oformat binary -nostdlib -o haikugpt haikugpt.o

------------------------------------ 8< ------------------------------------

--- pmbr.s      2009-06-10 02:07:13.000000000 -0300
+++ haikugpt.s  2009-06-10 02:26:12.000000000 -0300
@@ -31,7 +31,12 @@
 #
 # Partly from: src/sys/boot/i386/mbr/mbr.s 1.7

-# A 512 byte PMBR boot manager that looks for a FreeBSD boot GPT partition
+
+# Modified for booting Haiku by Andre' Braga (andrebraga@xxxxxxxxx)
+# The modifications contained herein are released into the Public Domain.
+
+
+# A 512 byte PMBR boot loader that looks for the UUID of a Haiku GPT partition
 # and boots it.

                .set LOAD,0x7c00                # Load address
@@ -101,19 +106,19 @@
                cmpl $GPT_SIG_1,GPT_ADDR+GPT_SIG+4
                jnz err_pt
 #
-# Load a partition table sector from disk and look for a FreeBSD boot
+# Load a partition table sector from disk and look for a Haiku
 # partition.
 #
 load_part:     movw $GPT_ADDR+GPT_PART_LBA,%si
                movw $PART_ADDR,%bx
                call read
 scan:          movw %bx,%si                    # Compare partition UUID
-               movw $boot_uuid,%di             #  with FreeBSD boot UUID
+               movw $boot_uuid,%di             #  with Haiku boot UUID
                movb $0x10,%cl
                repe cmpsb
                jnz next_part                   # Didn't match, next partition
 #
-# We found a boot partition.  Load it into RAM starting at 0x7c00.
+# We found a partition. Load it into RAM starting at 0x7c00.
 #
                movw %bx,%di                    # Save partition pointer in %di
                leaw PART_START_LBA(%di),%si
@@ -123,26 +128,24 @@
 load_boot:     push %si                        # Save %si
                call read
                pop %si                         # Restore
-               movl PART_END_LBA(%di),%eax     # See if this was the last LBA
-               cmpl (%si),%eax
-               jnz next_boot
-               movl PART_END_LBA+4(%di),%eax
-               cmpl 4(%si),%eax
-               jnz next_boot
+
+               incl (%si)                      # Setup for next LBA
+               adcl $0,4(%si)
+
+               mov %es,%ax                     #
+               addw $SECSIZE/16,%ax            # Adjust segment for next sector
+               mov %ax,%es                     #
+
+               push %si                        # Save %si
+               call read
+               pop %si                         # Restore
+
                mov %bx,%es                     # Reset %es to zero
+
                jmp LOAD                        # Jump to boot code
-next_boot:     incl (%si)                      # Next LBA
-               adcl $0,4(%si)
-               mov %es,%ax                     # Adjust segment for next
-               addw $SECSIZE/16,%ax            #  sector
-               cmp $0x9000,%ax                 # Don't load past 0x90000,
-               jae err_big                     #  545k should be enough for
-               mov %ax,%es                     #  any boot code. :)
-               jmp load_boot
 #
 # Move to the next partition.  If we walk off the end of the sector, load
-# the next sector.  We assume that partition entries are smaller than 64k
-# and that they won't span a sector boundary.
+# the next sector.
 #
 # XXX: Should we int 0x18 instead of err_noboot if we hit the end of the table?
 #
@@ -174,9 +177,6 @@
 #
 # Various error message entry points.
 #
-err_big:       movw $msg_big,%si               # "Boot loader too
-               jmp putstr                      #  large"
-
 err_pt:        movw $msg_pt,%si                # "Invalid partition
                jmp putstr                      #  table"

@@ -196,24 +196,24 @@
                jnz putstr.0                    # No
 putstr.1:      jmp putstr.1                    # Await reset

-msg_big:       .asciz "Boot loader too large"
 msg_pt:        .asciz "Invalid partition table"
 msg_rd:        .asciz "I/O error loading boot loader"
 msg_noboot:    .asciz "Missing boot loader"

 lba:           .quad 1                         # LBA of GPT header

-boot_uuid:     .long 0x83bd6b9d
-               .word 0x7f41
-               .word 0x11dc
-               .byte 0xbe
-               .byte 0x0b
-               .byte 0x00
-               .byte 0x15
-               .byte 0x60
-               .byte 0xb8
-               .byte 0x4f
-               .byte 0x0f
+boot_uuid:     .long 0x42465331
+               .word 0x3ba3
+               .word 0x10f1
+               .byte 0x80
+               .byte 0x2a
+               .byte 0x48
+               .byte 0x61
+               .byte 0x69
+               .byte 0x6b
+               .byte 0x75
+               .byte 0x21
+

                .org DISKSIG,0x90
 sig:           .long 0                         # OS Disk Signature

------------------------------------ 8< ------------------------------------

Other related posts: