The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/masterboot.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 !       masterboot 2.0 - Master boot block code         Author: Kees J. Bot
    2 !
    3 ! This code may be placed in the first sector (the boot sector) of a floppy,
    4 ! hard disk or hard disk primary partition.  There it will perform the
    5 ! following actions at boot time:
    6 !
    7 ! - If the booted device is a hard disk and one of the partitions is active
    8 !   then the active partition is booted.
    9 !
   10 ! - Otherwise the next floppy or hard disk device is booted, trying them one
   11 !   by one.
   12 !
   13 ! To make things a little clearer, the boot path might be:
   14 !       /dev/fd0        - Floppy disk containing data, tries fd1 then d0
   15 !       [/dev/fd1]      - Drive empty
   16 !       /dev/c0d0       - Master boot block, selects active partition 2
   17 !       /dev/c0d0p2     - Submaster, selects active subpartition 0
   18 !       /dev/c0d0p2s0   - Minix bootblock, reads Boot Monitor /boot
   19 !       Minix           - Started by /boot from a kernel image in /minix
   20 
   21         LOADOFF    =    0x7C00  ! 0x0000:LOADOFF is where this code is loaded
   22         BUFFER     =    0x0600  ! First free memory
   23         PART_TABLE =       446  ! Location of partition table within this code
   24         PENTRYSIZE =        16  ! Size of one partition table entry
   25         MAGIC      =       510  ! Location of the AA55 magic number
   26 
   27         ! <ibm/partition>.h:
   28         bootind    =         0
   29         sysind     =         4
   30         lowsec     =         8
   31 
   32 
   33 .text
   34 
   35 ! Find active (sub)partition, load its first sector, run it.
   36 
   37 master:
   38         xor     ax, ax
   39         mov     ds, ax
   40         mov     es, ax
   41         cli
   42         mov     ss, ax                  ! ds = es = ss = Vector segment
   43         mov     sp, #LOADOFF
   44         sti
   45 
   46 ! Copy this code to safety, then jump to it.
   47         mov     si, sp                  ! si = start of this code
   48         push    si                      ! Also where we'll return to eventually
   49         mov     di, #BUFFER             ! Buffer area
   50         mov     cx, #512/2              ! One sector
   51         cld
   52   rep   movs
   53         jmpf    BUFFER+migrate, 0       ! To safety
   54 migrate:
   55 
   56 ! Find the active partition
   57 findactive:
   58         testb   dl, dl
   59         jns     nextdisk                ! No bootable partitions on floppies
   60         mov     si, #BUFFER+PART_TABLE
   61 find:   cmpb    sysind(si), #0          ! Partition type, nonzero when in use
   62         jz      nextpart
   63         testb   bootind(si), #0x80      ! Active partition flag in bit 7
   64         jz      nextpart                ! It's not active
   65 loadpart:
   66         call    load                    ! Load partition bootstrap
   67         jc      error1                  ! Not supposed to fail
   68 bootstrap:
   69         ret                             ! Jump to the master bootstrap
   70 nextpart:
   71         add     si, #PENTRYSIZE
   72         cmp     si, #BUFFER+PART_TABLE+4*PENTRYSIZE
   73         jb      find
   74 ! No active partition, tell 'em
   75         call    print
   76         .ascii  "No active partition\0"
   77         jmp     reboot
   78 
   79 ! There are no active partitions on this drive, try the next drive.
   80 nextdisk:
   81         incb    dl                      ! Increment dl for the next drive
   82         testb   dl, dl
   83         js      nexthd                  ! Hard disk if negative
   84         int     0x11                    ! Get equipment configuration
   85         shl     ax, #1                  ! Highest floppy drive # in bits 6-7
   86         shl     ax, #1                  ! Now in bits 0-1 of ah
   87         andb    ah, #0x03               ! Extract bits
   88         cmpb    dl, ah                  ! Must be dl <= ah for drive to exist
   89         ja      nextdisk                ! Otherwise try disk 0 eventually
   90         call    load0                   ! Read the next floppy bootstrap
   91         jc      nextdisk                ! It failed, next disk please
   92         ret                             ! Jump to the next master bootstrap
   93 nexthd: call    load0                   ! Read the hard disk bootstrap
   94 error1: jc      error                   ! No disk?
   95         ret
   96 
   97 
   98 ! Load sector 0 from the current device.  It's either a floppy bootstrap or
   99 ! a hard disk master bootstrap.
  100 load0:
  101         mov     si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
  102         !jmp    load
  103 
  104 ! Load sector lowsec(si) from the current device.  The obvious head, sector,
  105 ! and cylinder numbers are ignored in favour of the more trustworthy absolute
  106 ! start of partition.
  107 load:
  108         mov     di, #3          ! Three retries for floppy spinup
  109 retry:  push    dx              ! Save drive code
  110         push    es
  111         push    di              ! Next call destroys es and di
  112         movb    ah, #0x08       ! Code for drive parameters
  113         int     0x13
  114         pop     di
  115         pop     es
  116         andb    cl, #0x3F       ! cl = max sector number (1-origin)
  117         incb    dh              ! dh = 1 + max head number (0-origin)
  118         movb    al, cl          ! al = cl = sectors per track
  119         mulb    dh              ! dh = heads, ax = heads * sectors
  120         mov     bx, ax          ! bx = sectors per cylinder = heads * sectors
  121         mov     ax, lowsec+0(si)
  122         mov     dx, lowsec+2(si)! dx:ax = sector within drive
  123         cmp     dx, #[1024*255*63-255]>>16  ! Near 8G limit?
  124         jae     bigdisk
  125         div     bx              ! ax = cylinder, dx = sector within cylinder
  126         xchg    ax, dx          ! ax = sector within cylinder, dx = cylinder
  127         movb    ch, dl          ! ch = low 8 bits of cylinder
  128         divb    cl              ! al = head, ah = sector (0-origin)
  129         xorb    dl, dl          ! About to shift bits 8-9 of cylinder into dl
  130         shr     dx, #1
  131         shr     dx, #1          ! dl[6..7] = high cylinder
  132         orb     dl, ah          ! dl[0..5] = sector (0-origin)
  133         movb    cl, dl          ! cl[0..5] = sector, cl[6..7] = high cyl
  134         incb    cl              ! cl[0..5] = sector (1-origin)
  135         pop     dx              ! Restore drive code in dl
  136         movb    dh, al          ! dh = al = head
  137         mov     bx, #LOADOFF    ! es:bx = where sector is loaded
  138         mov     ax, #0x0201     ! Code for read, just one sector
  139         int     0x13            ! Call the BIOS for a read
  140         jmp     rdeval          ! Evaluate read result
  141 bigdisk:
  142         mov     bx, dx          ! bx:ax = dx:ax = sector to read
  143         pop     dx              ! Restore drive code in dl
  144         push    si              ! Save si
  145         mov     si, #BUFFER+ext_rw ! si = extended read/write parameter packet
  146         mov     8(si), ax       ! Starting block number = bx:ax
  147         mov     10(si), bx
  148         movb    ah, #0x42       ! Extended read
  149         int     0x13
  150         pop     si              ! Restore si to point to partition entry
  151         !jmp    rdeval
  152 rdeval:
  153         jnc     rdok            ! Read succeeded
  154         cmpb    ah, #0x80       ! Disk timed out?  (Floppy drive empty)
  155         je      rdbad
  156         dec     di
  157         jl      rdbad           ! Retry count expired
  158         xorb    ah, ah
  159         int     0x13            ! Reset
  160         jnc     retry           ! Try again
  161 rdbad:  stc                     ! Set carry flag
  162         ret
  163 rdok:   cmp     LOADOFF+MAGIC, #0xAA55
  164         jne     nosig           ! Error if signature wrong
  165         ret                     ! Return with carry still clear
  166 nosig:  call    print
  167         .ascii  "Not bootable\0"
  168         jmp     reboot
  169 
  170 ! A read error occurred, complain and hang
  171 error:
  172         mov     si, #LOADOFF+errno+1
  173 prnum:  movb    al, ah          ! Error number in ah
  174         andb    al, #0x0F       ! Low 4 bits
  175         cmpb    al, #10         ! A-F?
  176         jb      digit           ! 0-9!
  177         addb    al, #7          ! 'A' - ':'
  178 digit:  addb    (si), al        ! Modify '0' in string
  179         dec     si
  180         movb    cl, #4          ! Next 4 bits
  181         shrb    ah, cl
  182         jnz     prnum           ! Again if digit > 0
  183         call    print
  184         .ascii  "Read error "
  185 errno:  .ascii  "00\0"
  186         !jmp    reboot
  187 
  188 reboot:
  189         call    print
  190         .ascii  ".  Hit any key to reboot.\0"
  191         xorb    ah, ah          ! Wait for keypress
  192         int     0x16
  193         call    print
  194         .ascii  "\r\n\0"
  195         int     0x19
  196 
  197 ! Print a message.
  198 print:  pop     si              ! si = String following 'call print'
  199 prnext: lodsb                   ! al = *si++ is char to be printed
  200         testb   al, al          ! Null marks end
  201         jz      prdone
  202         movb    ah, #0x0E       ! Print character in teletype mode
  203         mov     bx, #0x0001     ! Page 0, foreground color
  204         int     0x10
  205         jmp     prnext
  206 prdone: jmp     (si)            ! Continue after the string
  207 
  208 .data
  209 
  210 ! Extended read/write commands require a parameter packet.
  211 ext_rw:
  212         .data1  0x10            ! Length of extended r/w packet
  213         .data1  0               ! Reserved
  214         .data2  1               ! Blocks to transfer (just one)
  215         .data2  LOADOFF         ! Buffer address offset
  216         .data2  0               ! Buffer address segment
  217         .data4  0               ! Starting block number low 32 bits (tbfi)
  218 zero:   .data4  0               ! Starting block number high 32 bits

Cache object: 455470110cb4d7a2af756c7b87d15f20


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.