[haiku-commits] r42104 - in haiku/trunk: build/jam src/add-ons/kernel/partitioning_systems/intel src/apps/aboutsystem src/bin/writembr

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 11 Jun 2011 21:14:50 +0200 (CEST)

Author: anevilyak
Date: 2011-06-11 21:14:49 +0200 (Sat, 11 Jun 2011)
New Revision: 42104
Changeset: https://dev.haiku-os.org/changeset/42104
Ticket: https://dev.haiku-os.org/ticket/3441

Modified:
   haiku/trunk/build/jam/AnybootImage
   
haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp
   haiku/trunk/src/apps/aboutsystem/AboutSystem.cpp
   haiku/trunk/src/bin/writembr/mbr.S
Log:
Applied patch by Jean-Lo?\195?\175c Charroud that reworks the anyboot MBR to 
fix boot
problems on various systems. Resolves #3441. Thanks!

+alpha3



Modified: haiku/trunk/build/jam/AnybootImage
===================================================================
--- haiku/trunk/build/jam/AnybootImage  2011-06-11 18:38:15 UTC (rev 42103)
+++ haiku/trunk/build/jam/AnybootImage  2011-06-11 19:14:49 UTC (rev 42104)
@@ -14,7 +14,7 @@
 
 actions BuildAnybootMBR1 {
        $(RM) $(1)
-       $(TARGET_CC) $(MBR_SOURCE) -o $(1) -nostdlib -Xlinker --oformat=binary 
-Xlinker -S -Xlinker -N -Xlinker "-e start" -Xlinker "-Ttext=0x600"
+       $(HAIKU_YASM) -f bin $(MBR_SOURCE) -O5 -o $(1)
 }
 
 rule BuildAnybootImage anybootImage : mbrPart : isoPart : imageFile {

Modified: 
haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp
===================================================================
--- 
haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp
    2011-06-11 18:38:15 UTC (rev 42103)
+++ 
haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp
    2011-06-11 19:14:49 UTC (rev 42104)
@@ -37,44 +37,34 @@
 #endif
 
 
-// compiled form of hybrid FreeBSD pmbr and mbr loader done by André Braga
+// compiled mbr boot loader code
 static const uint8 kBootCode[] = {
-       0xfc, 0xe8, 0x05, 0x01, 0xbc, 0x00, 0x0e, 0xbe, 0x15, 0x7c, 0xbf, 0x15,
-       0x06, 0xb9, 0xeb, 0x01, 0xf3, 0xa4, 0xe9, 0x00, 0x8a, 0xe8, 0xfc, 0x00,
-       0xbb, 0x00, 0x0e, 0xbe, 0xb0, 0x07, 0xb9, 0x01, 0x00, 0xe8, 0x03, 0x01,
-       0x66, 0x81, 0x3e, 0x00, 0x0e, 0x45, 0x46, 0x49, 0x20, 0x75, 0x5c, 0x66,
-       0x81, 0x3e, 0x04, 0x0e, 0x50, 0x41, 0x52, 0x54, 0x75, 0x51, 0xbe, 0x48,
-       0x0e, 0xbb, 0x00, 0x10, 0xb9, 0x01, 0x00, 0xe8, 0xe1, 0x00, 0x89, 0xde,
-       0xbf, 0xa0, 0x07, 0xb1, 0x10, 0xf3, 0xa6, 0x75, 0x1b, 0x89, 0xdf, 0x8d,
-       0x75, 0x20, 0xbb, 0xc0, 0x07, 0x8e, 0xc3, 0x31, 0xdb, 0x56, 0x8a, 0x0e,
-       0x9f, 0x07, 0xe8, 0xc2, 0x00, 0x31, 0xc0, 0x8e, 0xc0, 0xe9, 0x94, 0x75,
-       0x66, 0xff, 0x0e, 0x50, 0x0e, 0x74, 0x18, 0xa1, 0x54, 0x0e, 0x01, 0xc3,
-       0x81, 0xfb, 0x00, 0x12, 0x72, 0xc8, 0x66, 0xff, 0x06, 0x48, 0x0e, 0x66,
-       0x83, 0x16, 0x4c, 0x0e, 0x00, 0xeb, 0xaf, 0xe8, 0x7b, 0x00, 0xbc, 0x00,
-       0x7c, 0x31, 0xf6, 0xbb, 0xbe, 0x07, 0xb1, 0x04, 0x38, 0x2f, 0x74, 0x0c,
-       0x0f, 0x8f, 0xa2, 0x00, 0x85, 0xf6, 0x0f, 0x85, 0x9c, 0x00, 0x89, 0xde,
-       0x80, 0xc3, 0x10, 0xe2, 0xeb, 0x85, 0xf6, 0x75, 0x02, 0xcd, 0x18, 0xe8,
-       0x5e, 0x00, 0x89, 0xe7, 0x8a, 0x74, 0x01, 0x8b, 0x4c, 0x02, 0xbb, 0x00,
-       0x7c, 0xf6, 0x06, 0x9e, 0x07, 0x80, 0x74, 0x2d, 0x51, 0x53, 0xbb, 0xaa,
-       0x55, 0xb4, 0x41, 0xcd, 0x13, 0x72, 0x20, 0x81, 0xfb, 0x55, 0xaa, 0x75,
-       0x1a, 0xf6, 0xc1, 0x01, 0x74, 0x15, 0x5b, 0x66, 0x6a, 0x00, 0x66, 0xff,
-       0x74, 0x08, 0x06, 0x53, 0x6a, 0x01, 0x6a, 0x10, 0x89, 0xe6, 0xb8, 0x00,
-       0x42, 0xeb, 0x05, 0x5b, 0x59, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x89, 0xfc,
-       0x72, 0x49, 0x81, 0xbf, 0xfe, 0x01, 0x55, 0xaa, 0x75, 0x46, 0xe9, 0x5c,
-       0xff, 0x31, 0xc9, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xc3,
-       0x80, 0xfa, 0x80, 0x72, 0x0b, 0x8a, 0x36, 0x75, 0x04, 0x80, 0xc6, 0x80,
-       0x38, 0xf2, 0x72, 0x02, 0xb2, 0x80, 0xc3, 0x66, 0xff, 0x74, 0x04, 0x66,
-       0xff, 0x34, 0x06, 0x53, 0x51, 0x6a, 0x10, 0x89, 0xe6, 0xb8, 0x00, 0x42,
-       0xcd, 0x13, 0x83, 0xc4, 0x10, 0x0f, 0x82, 0x4a, 0xff, 0xc3, 0xbe, 0x60,
-       0x07, 0xeb, 0x11, 0xbe, 0x74, 0x07, 0xeb, 0x0c, 0xbe, 0x7d, 0x07, 0xeb,
-       0x07, 0xbb, 0x07, 0x00, 0xb4, 0x0e, 0xcd, 0x10, 0xac, 0x84, 0xc0, 0x75,
-       0xf4, 0xf4, 0xeb, 0xfd, 0x42, 0x61, 0x64, 0x20, 0x50, 0x61, 0x72, 0x74,
-       0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x00,
-       0x49, 0x4f, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x4d, 0x69, 0x73,
-       0x73, 0x69, 0x6e, 0x67, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
-       0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x00, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x02, 0x31, 0x53, 0x46, 0x42,
-       0xa3, 0x3b, 0xf1, 0x10, 0x80, 0x2a, 0x48, 0x61, 0x69, 0x6b, 0x75, 0x21
+       // compiled form of //haiku/trunk/src/bin/writembr/mbr.S
+       // yasm -f bin -O5 -o mbrcode.bin mbr.S -dMBR_CODE_ONLY=1
+       // bin2h <mbrcode.bin 12
+       0xfa, 0xfc, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xbc, 0x00,
+       0x7c, 0xbf, 0x00, 0x08, 0xb9, 0x18, 0x00, 0xf3, 0xaa, 0xbe, 0x00, 0x7c,
+       0x89, 0x36, 0x0c, 0x08, 0xc6, 0x06, 0x08, 0x08, 0x10, 0xc6, 0x06, 0x0a,
+       0x08, 0x01, 0xbf, 0x00, 0x06, 0xb5, 0x01, 0xf3, 0xa5, 0xea, 0x32, 0x06,
+       0x00, 0x00, 0xfb, 0xbe, 0xbe, 0x07, 0xb0, 0x04, 0x80, 0x3c, 0x80, 0x74,
+       0x09, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xeb, 0x6d, 0x89, 0x36,
+       0x04, 0x08, 0x66, 0x8b, 0x44, 0x08, 0x66, 0xa3, 0x10, 0x08, 0x66, 0x85,
+       0xc0, 0x74, 0x27, 0xb4, 0x41, 0xbb, 0xaa, 0x55, 0xcd, 0x13, 0x72, 0x1e,
+       0xbe, 0x08, 0x08, 0xb4, 0x42, 0xcd, 0x13, 0x72, 0x15, 0x81, 0x3e, 0xfe,
+       0x7d, 0x55, 0xaa, 0x75, 0x42, 0xbe, 0xfb, 0x06, 0xe8, 0x52, 0x00, 0x8b,
+       0x36, 0x04, 0x08, 0xe9, 0x82, 0x75, 0x8b, 0x36, 0x04, 0x08, 0x8a, 0x74,
+       0x01, 0x8b, 0x4c, 0x02, 0x88, 0xc8, 0x24, 0x3f, 0x84, 0xc0, 0x74, 0x23,
+       0x3c, 0x3f, 0x75, 0x14, 0x89, 0xc8, 0xc0, 0xec, 0x06, 0x3d, 0xff, 0x03,
+       0x75, 0x0a, 0x80, 0xfe, 0xff, 0x75, 0x05, 0x80, 0xfe, 0xfe, 0x74, 0x0b,
+       0xbb, 0x00, 0x7c, 0xb0, 0x01, 0xb4, 0x02, 0xcd, 0x13, 0x73, 0xb6, 0xbe,
+       0xdf, 0x06, 0xe8, 0x10, 0x00, 0xe8, 0x08, 0x00, 0xbe, 0xd5, 0x06, 0xe8,
+       0x07, 0x00, 0xcd, 0x18, 0xb4, 0x00, 0xcd, 0x16, 0xc3, 0x31, 0xdb, 0xac,
+       0xb4, 0x0e, 0xcd, 0x10, 0x08, 0xc0, 0x75, 0xf7, 0xc3, 0x52, 0x4f, 0x4d,
+       0x20, 0x42, 0x41, 0x53, 0x49, 0x43, 0x00, 0x4e, 0x6f, 0x20, 0x62, 0x6f,
+       0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76,
+       0x65, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x0d, 0x0a, 0x00, 0x4c,
+       0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
+       0x6d, 0x0a, 0x0d, 0x00
 };
 
 

Modified: haiku/trunk/src/apps/aboutsystem/AboutSystem.cpp
===================================================================
--- haiku/trunk/src/apps/aboutsystem/AboutSystem.cpp    2011-06-11 18:38:15 UTC 
(rev 42103)
+++ haiku/trunk/src/apps/aboutsystem/AboutSystem.cpp    2011-06-11 19:14:49 UTC 
(rev 42104)
@@ -1051,6 +1051,7 @@
                "Andre Braga\n"
                "Michael Bulash\n"
                "Bruce Cameron\n"
+               "Jean-Loïc Charroud\n"
                "Greg Crain\n"
                "Michael Davidson\n"
                "David Dengg\n"

Modified: haiku/trunk/src/bin/writembr/mbr.S
===================================================================
--- haiku/trunk/src/bin/writembr/mbr.S  2011-06-11 18:38:15 UTC (rev 42103)
+++ haiku/trunk/src/bin/writembr/mbr.S  2011-06-11 19:14:49 UTC (rev 42104)
@@ -1,164 +1,399 @@
-/*
-** Copyright (c) 1999 Robert Nordier
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms are freely
-** permitted provided that the above copyright notice and this
-** paragraph and the following disclaimer are duplicated in all
-** such forms.
-**
-** This software is provided "AS IS" and without any express or
-** implied warranties, including, without limitation, the implied
-** warranties of merchantability and fitness for a particular
-** purpose.
-/*
+; Copyright 2011, Jean-Loïc Charroud, jcharroud@xxxxxxx
+; Distributed under the terms of the MIT License or LGPL v3
+;
+; Haiku (C) Copyright Haiku 2011
+; MBR Boot code
+;
+; assemble the Master boot record with:
+;      yasm -f bin -O5 -o mbr.bin mbr.S
+;
+; assemble the MBR's code (does not contain the partiton table
+; nor the MAGIC code) with:
+;      yasm -f bin -O5 -o mbrcode.bin mbr.S -dMBR_CODE_ONLY=1
 
-/* A 512 byte MBR boot manager that simply boots the active partition. */
 
-               .set LOAD, 0x7c00                               // Load address
-               .set EXEC, 0x600                                // Execution 
address
-               .set PT_OFF, 0x1be                              // Partition 
table
-               .set MAGIC, 0xaa55                              // Magic: 
bootable
+;%define       DEBUG                   1
+;%define       MBR_CODE_ONLY   1
 
-               .set NUM_HARD_DRIVES, 0x475             // Number of hard drives
 
-               .globl start                                    // Entry point
-               .code16
+;CONST
+       %assign DISKSIG                 440                             ; Disk 
signature offset
+       %assign PT_OFF                  0x1be                   ; Partition 
table offset
+       %assign MAGIC_OFF               0x1fe                   ; Magic offset
+       %assign MAGIC                   0xaa55                  ; Magic 
bootable signature
+       %assign SECSIZE                 0x200                   ; Size of a 
single disk sector
+       %assign FLG_ACTIVE              0x80                    ; active 
partition flag
+       %assign SECTOR_COUNT    0x01                    ; Number of record to 
load from
+                                                                               
        ; the ctive partition
 
-/*
- * Setup the segment registers for flat addressing and setup the stack.
- */
-start: cld                                                             // 
String ops inc
-               xorw %ax, %ax                                   // Zero
-               movw %ax, %es                                   // Address
-               movw %ax, %ds                                   // data
-               movw %ax, %ss                                   // Set up stack
-               movw $LOAD, %sp                                 //
-/*
- * Relocate ourself to a lower address so that we are out of the way when
- * we load in the bootstrap from the partition to boot.
- */
-               movw $main-EXEC+LOAD, %si               // Source
-               movw $main, %di                                 // Destination
-               movw $0x200-(main-start), %cx   // Byte count
-               rep                                                             
// Relocate code
-               movsb                                                   //
-/*
- * Jump to the relocated code.
- */
-               jmp main-LOAD+EXEC                              // Jump to 
relocated code
+       %assign LOAD                    0x7c00                  ; Load address
+       %assign EXEC                    0x600                   ; Execution 
address
+       %assign HEAP                    EXEC+SECSIZE    ; Execution address
 
-/*
- * Scan the partition table looking for an active entry.  Note that %ch is
- * zero from the repeated string instruction above.  We save the offset of
- * the active partition in %si and scan the entire table to ensure that only
- * one partition is marked active.
- */
+;BIOS calls
+       %assign BIOS_VIDEO_SERVICES                     0x10; ah - function
+       %assign BIOS_DISK_SERVICES                      0x13
+       %assign BIOS_KEYBOARD_SERVICES          0X16
+       %assign BIOS_BASIC                                      0X18
+       %assign BIOS_REBOOT                                     0X19
 
-main:  xorw %si, %si                                   // No active partition
-               movw $partition_table, %bx              // Partition table
-               movb $0x4, %cl                                  // Number of 
entries
-main.1: cmpb %ch, (%bx)                                        // Null entry?
-               je main.2                                               // Yes
-               jg err_partition_table                  // If 0x1..0x7f
-               testw %si, %si                                  // Active 
already found?
-               jnz err_partition_table                 // Yes
-               movw %bx, %si                                   // Point to 
active
-main.2: addb $0x10, %bl                                        // Till
-               loop main.1                                             //  done
-               testw %si, %si                                  // Active found?
-               jnz main.3                                              // Yes
-               int $0x18                                               // 
BIOS: Diskless boot
-/*
- * Ok, we've found a possible active partition.  Check to see that the drive
- * is a valid hard drive number.
- */
-main.3: cmpb $0x80, %dl                                        // Drive valid?
-               jb main.4                                               // No
-               movb NUM_HARD_DRIVES, %dh               // Calculate the highest
-               addb $0x80, %dh                                 //   drive 
number available
-               cmpb %dh, %dl                                   // Within range?
-               jb main.5                                               // Yes
-main.4: movb (%si), %dl                                        // Load drive
-/*
- * Ok, now that we have a valid drive and partition entry, load the CHS from
- * the partition entry and read the sector from the disk.
- */
-main.5:        movw %sp, %di                                   // Save stack 
pointer
-               movb 0x1(%si), %dh                              // Load head
-               movw 0x2(%si), %cx                              // Load 
cylinder:sector
-               movw $LOAD, %bx                                 // Transfer 
buffer
-               cmpb $0xff, %dh                                 // Might we 
need to use LBA?
-               jnz main.7                                              // No.
-               cmpw $0xffff, %cx                               // Do we need 
to use LBA?
-               jnz main.7                                              // No.
-               pushw %cx                                               // Save 
%cx
-               pushw %bx                                               // Save 
%bx
-               movw $0x55aa, %bx                               // Reversed 
Magic
-               movb $0x41, %ah                                 // BIOS:        
EDD extensions present?
-               int $0x13                                               //
-               jc main.6                                               // No.
-               cmpw $MAGIC, %bx                                // Magic ok?
-               jne main.6                                              // No.
-               testb $0x1, %cl                                 // Packet mode 
present?
-               jz main.6                                               // No.
-               popw %bx                                                // 
Restore %bx
-               pushl $0x0                                              // Set 
the LBA
-               pushl 0x8(%si)                                  //  address
-               pushw %es                                               // Set 
the address of
-               pushw %bx                                               //  the 
transfer buffer
-               pushw $0x1                                              // Read 
1 sector
-               pushw $0x10                                             // 
Packet length
-               movw %sp, %si                                   // Packet 
pointer
-               movw $0x4200, %ax                               // BIOS:        
LBA Read from disk
-               jmp main.8                                              // Skip 
the CHS setup
-main.6:        popw %bx                                                // 
Restore %bx
-               popw %cx                                                // 
Restore %cx
-main.7:        movw $0x201, %ax                                // BIOS: Read 
from disk
-main.8:        int $0x13                                               // Call 
the BIOS
-               movw %di,%sp                                    // Restore stack
-               jc err_loading_os                               // If error
-/*
- * Now that we've loaded the bootstrap, check for the magic 0xaa55 signature.
- * If it is present, execute the bootstrap we just loaded.
- */
-               cmpw $MAGIC, 0x1fe(%bx)                 // Bootable?
-               jne err_missing_os                              // No
-               jmp *%bx                                                // 
Invoke bootstrap
-/*
- * Various error message entry points.
- */
-err_partition_table:
-               movw $msg_partition_table, %si  // "Invalid partition table"
-               jmp putString                                   //
+       ;BIOS calls parameters
+               ; video services
+                       %assign WRITE_CHAR                      0x0e; al - char
+                                                                               
        ; bh - page?
 
-err_loading_os:
-               movw $msg_loading_os, %si               // "Error loading 
operating system"
-               jmp putString                                   //
+               ; disk services
+                       %assign READ_DISK_SECTORS       0x02; dl        - drive
+                                                                               
        ; es:bx - buffer
+                                                                               
        ; dh    - head
+                                                                               
        ; ch7:0 - track7:0
+                                                                               
        ; cl7:6 - track9:8
+                                                                               
        ;       5:0     - sector
+                                                                               
        ; al    - sector count
+                                                                               
        ; -> al - sectors read
+                       %assign READ_DRV_PARAMETERS     0x08; dl - drive
+                                                                               
        ; -> cl - max cylinder 9:8
+                                                                               
        ;               - sectors per track
+                                                                               
        ;    ch - max cylinder 7:0
+                                                                               
        ;    dh - max head
+                                                                               
        ;    dl - number of drives (?)
+                       %assign CHK_DISK_EXTENTIONS     0x41; bx - 0x55aa
+                                                                               
        ; dl - drive
+                                                                               
        ; -> success: carry clear
+                                                                               
        ;    ah - extension version
+                                                                               
        ;    bx - 0xaa55
+                                                                               
        ;    cx - support bit mask
+                                                                               
        ;               1 - Device Access using the
+                                                                               
        ;                       packet structure
+                                                                               
        ;               2 - Drive Locking and
+                                                                               
        ;                       Ejecting
+                                                                               
        ;               4 - Enhanced Disk Drive
+                                                                               
        ;                       Support (EDD)
+                                                                               
        ; -> error: carry set
+                       %assign EXTENDED_READ           0x42; dl - drive
+                                                                               
        ; ds:si - address packet
+                                                                               
        ; -> success: carry clear
+                                                                               
        ; -> error: carry set
 
-err_missing_os:
-               movw $msg_missing_os, %si               // "Missing operating 
system"
-               jmp putString                                   //
-/*
- * Output an ASCIZ string to the console via the BIOS.
- */
-putString.0:
-               movw $0x7, %bx                                  // 
Page:attribute
-               movb $0xe, %ah                                  // BIOS: 
Display character
-               int $0x10                                               //
-putString:
-               lodsb                                                   // Get 
character
-               testb %al,%al                                   // End of 
string?
-               jnz putString.0                                 // No
-putString.1:
-               jmp putString.1                                 // Await reset
+                       %assign FIXED_DSK_SUPPORT       0x1     ; flag 
indicating fixed disk
+                                                                               
        ; extension command subset
 
-msg_partition_table:   .asciz "Invalid partition table"
-msg_loading_os:                .asciz "Error loading operating system"
-msg_missing_os:                .asciz "Missing operating system"
+               ; keyboard services
+                       %assign READ_CHAR                       0x00; -> al - 
ASCII char
 
-               .org PT_OFF
+;MACRO
+       ; nicer way to get the size of a structure
+       %define sizeof(s)       s %+ _size
 
-partition_table:
-               .fill 0x10,0x4,0x0                              // Partition 
table
-               .word MAGIC                                             // 
Magic number
+       ; using a structure in a another structure definition
+       %macro  nstruc  1-2             1
+               resb    sizeof(%1) * %2
+       %endmacro
+
+       ; nicer way to access GlobalVariables
+       %macro  declare_var     1
+               %define %1      HEAP + GlobalVariables. %+ %1
+       %endmacro
+
+       %macro  puts    1
+               mov             si,             %1
+               call    _puts
+       %endmacro
+
+       %macro  error   1
+               mov             si, %1
+               jmp             _error
+       %endmacro
+
+;TYPEDEFS
+       ; 64 bit value
+       struc   quadword
+               .lower                  resd    1
+               .upper                  resd    1
+       endstruc
+
+       struc   CHS_addr
+               .head                   resb    1
+               .sector                 resb    1
+               .cylindre               resb    1
+       endstruc
+
+       struc   PartitionEntry
+               .status                 resb    1
+               .CHS_first              nstruc  CHS_addr
+               .type                   resb    1
+               .CHS_last               nstruc  CHS_addr
+               .LBA_start              resd    1
+               .LBA_size               resd    1
+       endstruc
+               
+       ; address packet as required by the EXTENDED_READ BIOS call
+       struc   AddressPacket
+               .packet_size    resb    1
+               .reserved               resb    1
+               .block_count    resw    1
+               .buffer                 resd    1
+               .sector                 nstruc  quadword
+               ;.long_buffer   nstruc  quadword
+               ;       We don't need the 64 bit buffer pointer. The 32 bit 
.buffer is more
+               ;       than sufficient.
+       endstruc
+
+       ; Structure containing the variables that don't need pre-initialization.
+       ; this structure will be allocated onto our "heap".
+       struc   GlobalVariables
+               .boot_drive_id                          resd    1
+               .boot_partition                         resd    1
+               .address_packet                         nstruc  AddressPacket
+       endstruc
+
+;alias for easy access to our global variables
+       declare_var     boot_drive_id
+       declare_var     boot_partition
+       declare_var     address_packet
+
+;/////////////////////////////////////////////////////////////////////////
+;// A 512 byte MBR boot manager that simply boots the active partition. //
+;/////////////////////////////////////////////////////////////////////////
+; 16 bit code
+SECTION .text
+BITS 16
+ORG EXEC                                               ; MBR is loaded at 
0x7c00 but relocated at 0x600
+start:                                                 ; we run the LOADed code
+               cli                                             ; disable 
interrupts
+               cld                                             ; clear 
direction flag (for string operations)
+       init:
+               xor             ax,             ax              ; Zero
+               mov             es,             ax              ; Set up extra 
segment
+               mov             ds,             ax              ; Set up data 
segment
+               mov             ss,             ax              ; Set up stack 
segment
+               mov             sp,             LOAD    ; Set up stack pointer
+
+               ;init our heap allocated variables with zeros
+               mov             di,             HEAP    ;start adress
+               mov             cx,             sizeof(GlobalVariables) ;size
+               rep                                             ; while(cx--)
+                       stosb                           ;       es[di++]:=al;
+
+       ; Relocate ourself to a lower address so that we are out of the way
+       ; when we load in the bootstrap from the partition to boot.
+       reloc:
+               mov             si,             LOAD    ; Source
+               ; init AddressPacket.buffer now since LOAD is in 'si'
+               mov [address_packet+AddressPacket.buffer],si
+               mov 
byte[address_packet+AddressPacket.packet_size],sizeof(AddressPacket)
+               mov byte[address_packet+AddressPacket.block_count],SECTOR_COUNT
+
+               mov             di,             EXEC    ; Destination
+               mov             ch,             1               ; count cx:=256 
(cl cleared by precedent rep call)
+               rep                                             ; while(cx--)
+                       movsw                           ;   es[di++]:=ds[si++] 
+                                                               ; //di and si 
are incremented by sizeof(word)
+               jmp word 0x0000:continue; FAR jump to the relocated "continue" 
(some
+                                                               ; BIOSes 
initialise CS to 0x07c0 so we must set
+                                                               ; CS correctly)
+
+continue:                                              ; Now we run EXEC_based 
relocated code
+               sti                                             ; enable 
interrupts
+               %ifdef DEBUG
+               puts    kMsgStart
+               %endif
+
+search_active_partition:
+               mov             si,EXEC+PT_OFF                          ; point 
to first table entry
+               mov             al,04                                           
; there are 4 table entries
+       .loop:                                                                  
; SEARCH FOR AN ACTIVE ENTRY
+               cmp             byte[si],FLG_ACTIVE                     ; is 
this the active entry?
+               je              found_active                            ; yes
+               add             si,     sizeof(PartitionEntry)  ; next 
PartitionEntry
+               dec             al                                              
        ; decrease remaining entry count
+               jnz             .loop                                           
; loop if entry count > 0
+               jmp             no_bootable_active_partition; last partition 
reached
+
+found_active:                                                          ; 
active partition (pointed by si)
+               mov             [boot_partition],si                     ; Save 
active partition pointer
+
+       .get_read_sector:                                               ; 
initialise address_packet:
+               mov eax,[si + PartitionEntry.LBA_start]
+               mov [address_packet+AddressPacket.sector],eax
+
+               ; if LBA_adress equals 0 then it's not a valid PBR (it is the 
MBR)
+               ; this can append when we only have a CHS adress in the 
partition entry
+               test    eax,            eax                             ;if ( 
LBA_adress == 0 )
+               jz              no_disk_extentions                      ;then 
no_disk_extentions()
+
+check_disk_extensions:
+               ; Note: this test may be unnecessary since EXTENDED_READ also
+               ; set the carry flag when extended calls are not supported
+               %ifdef DEBUG
+               puts    kMsgCheckEx
+               %endif
+
+               mov             ah, CHK_DISK_EXTENTIONS         ; set command
+               mov             bx, 0x55aa                                      
; set parameter : hton(MAGIC)
+               ; dl has not changed yet, still contains the drive ID
+               int             BIOS_DISK_SERVICES                      ; if( 
do_command() <> OK )
+               jc              no_disk_extentions                      ; then 
use simple read operation 
+                                                                               
        ; else use extended read
+disk_extentions:
+               %ifdef DEBUG
+               puts    kMsgRead_Ex
+               %endif
+
+               ; load first bloc active partition
+               ; dl has not changed yet, still contains the drive ID
+               mov             si,     address_packet                  ; set 
command parameters
+               mov             ah, EXTENDED_READ                       ; set 
command
+       .read_PBR:
+               int             BIOS_DISK_SERVICES                      ; if ( 
do_command() <> OK )
+               jc              no_disk_extentions                      ; then 
try CHS_read();
+
+check_for_bootable_partition:
+               cmp             word[LOAD+MAGIC_OFF],MAGIC      ; if ( ! 
volume.isBootable() )
+               jne             no_bootable_active_partition; then error();
+
+jump_PBR:
+               %ifdef DEBUG
+               puts    kMsgBootPBR
+               call    _pause
+               %else
+               puts    kMsgStart
+               %endif
+
+               ; jump to 0x7c00 with :
+               ;       - CS=0
+               ;       - DL=drive number
+               ;       - DS:SI=pointer to the selected partition table
+               ;                       entry (required by some PBR)
+
+               ; dl has not changed yet, still contains the drive ID
+               mov             si,             [boot_partition]
+               jmp             LOAD                                            
; jump into partition boot loader
+
+no_disk_extentions:
+               %ifdef DEBUG
+               puts    kMsgNoExtentions
+               %endif
+
+               mov             si,             [boot_partition]        ; 
Restore active partition pointer
+
+               ;load CHS PBR sector info
+               mov             dh,             [si+1]                          
; dh 7:0 = head 7:0   (0 - 255)
+               mov             cx,             [si+2]                          
; cl 5:0 = sector 7:0 (1 - 63)
+                                                                               
        ; cl 7:6 = cylinder 9:8 (0 - 1023)
+                                                                               
        ; ch 7:0 = cylinder 7:0
+       .check_Sector:
+               mov             al,             cl
+               and             al,             0x3F                            
; extract sector
+               test    al,             al;                                     
; if (sector==0) 
+               jz              no_bootable_active_partition; then 
error("invalid sector");
+               cmp             al,             0x3F                            
; if(  (Sector == 63)
+               jne             .CHS_valid                                      
;
+       .check_Cylinder:
+               mov             ax,             cx
+               shr             ah,             6
+               cmp             ax,             0x03FF                          
;       and      (Cylinder == 1023)
+               jne             .CHS_valid
+       .check_Head:
+               cmp             dh,             0xFF                            
;       and  ( (Head == 255)
+               jne             .CHS_valid
+               cmp             dh,             0xFE                            
;           or (Head == 254) )  )
+               je              no_bootable_active_partition; then 
error("invalid CHS_adress");
+
+       .CHS_valid:
+               ; dl has not changed yet, still contains the drive ID
+               mov             bx,             LOAD                            
; set buffer
+               mov             al,             SECTOR_COUNT            ; set 
Size
+               mov             ah,             READ_DISK_SECTORS       ; set 
read command
+               int             BIOS_DISK_SERVICES                      ; if ( 
do_command() == OK )
+               jnc             check_for_bootable_partition; then 
resume(normal boot sequence)
+                                                                               
        ; else continue;
+
+no_bootable_active_partition:
+               mov             si, kMsgNoBootable
+               ;jmp _error                                                     
; _error is the next line !
+
+_error:
+       ; display a non-empty null-terminated string on the screen,
+       ; wait for a key pressed and go back to the bios
+       ; IN :
+       ;       - si = address of string to display
+       ; OUT :
+       ; DIRTY :
+       ;       - ax
+       ;       - si
+               call    _puts
+               call    _pause
+               puts    kMsgROMBASIC
+               int             BIOS_BASIC                                      
; BIOS_BASIC give the control back
+                                                                               
        ; to the BIOS. Doing so, let some
+                                                                               
        ; BIOSes try to boot an alternate 
+                                                                               
        ; device (PXE/CD/HDD : see your 
+                                                                               
        ; BIOS' boot device order )
+_pause:
+       ; wait for a key pressed
+       ; IN :
+       ; OUT :
+       ; DIRTY :
+       ;       - ax
+               mov             ah,             READ_CHAR
+               int             BIOS_KEYBOARD_SERVICES
+               ret
+
+_puts:
+       ; display a non-empty null-terminated string on the screen
+       ; IN :
+       ;       - si = address of string to display
+       ; OUT :
+       ; DIRTY :
+       ;       - ax
+       ;       - bx
+       ;       - si
+               xor             bx,             bx                              
        ; bx:=0
+       .loop:                                                                  
; do {
+               lodsb                                                           
;       al=[si++];
+               mov             ah,             WRITE_CHAR                      
;       
+               int             BIOS_VIDEO_SERVICES                     ;       
WRITE_CHAR(al)
+               or              al, al                                          
; } while (al<>0);
+               jnz             .loop
+               ret
+
+data:
+               kMsgROMBASIC    db      'ROM BASIC',0
+               kMsgNoBootable  db      'No bootable active volume',13,10,0
+               kMsgStart               db      'Loading system',10,13,0
+
+       %ifdef DEBUG
+               kMsgBootPBR             db      'JMP PBR',13,10,0
+               kMsgRead_Ex             db      'Read_ex block',13,10,0
+               kMsgCheckEx             db      'CheckEx',13,10,0
+               kMsgNoExtentions db     'Read block',13,10,0
+               kMsgReloc               db      'reloc MBR',13,10,0
+       %endif
+
+; check whether the code is small enough to fit in the boot code area
+end:
+               ;use nasm instead of yasm to check  the code size
+               ;%if end - start > DISKSIG
+               ;       %error "Code exceeds master boot code area!"
+               ;%endif
+
+%ifdef MBR_CODE_ONLY
+       ;just build the code.
+       ;Do not generate the datas
+%else
+               ;use nasm instead of yasm => use %rep instead of times
+               ;%rep start + DISKSIG - end
+               ;       db      0                                       ;fill 
the rest of the code area
+               ;%endrep
+               times start + DISKSIG - end db 0
+               kMbrDiskID      dd      0                       ;Disk signature
+               dw 0                                            ;reserved
+               PartitionTable times PartitionEntry_size * 4 db 0
+DiskSignature:
+               ;use nasm instead of yasm to check  the MAGIC offset
+               ;%if DiskSignature - start <> MAGIC_OFF
+               ;       %error "incorrect Disk Signature offset"
+               ;%endif
+               kMbrSignature   db      0x55, 0xAA
+%endif


Other related posts: