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/jumpboot.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 !       jumpboot 1.0 - Jump to another bootstrap        Author: Kees J. Bot
    2 !                                                               14 Apr 1999
    3 !
    4 ! This code may be placed into any free boot sector, like the first sector
    5 ! of an extended partition, a file system partition other than the root,
    6 ! or even the master bootstrap.  It will load and run another bootstrap whose
    7 ! disk, partition, and slice number (not necessarily all three) are patched
    8 ! into this code by installboot.  If the ALT key is held down when this code
    9 ! is booted then you can type the disk, partition, and slice numbers manually.
   10 ! The manual interface is default if no numbers are patched in by installboot.
   11 !
   12 
   13         o32        =      0x66  ! This assembler doesn't know 386 extensions
   14         LOADOFF    =    0x7C00  ! 0x0000:LOADOFF is where this code is loaded
   15         BUFFER     =    0x0600  ! First free memory
   16         PART_TABLE =       446  ! Location of partition table within master
   17         PENTRYSIZE =        16  ! Size of one partition table entry
   18         MAGIC      =       510  ! Location of the AA55 magic number
   19 
   20         ! <ibm/partition.h>:
   21         MINIX_PART =      0x81
   22         sysind     =         4
   23         lowsec     =         8
   24 
   25 
   26 .text
   27 
   28 ! Find and load another bootstrap and jump to it.
   29 jumpboot:
   30         xor     ax, ax
   31         mov     ds, ax
   32         mov     es, ax
   33         cli
   34         mov     ss, ax                  ! ds = es = ss = Vector segment
   35         mov     sp, #LOADOFF
   36         sti
   37 
   38 ! Move this code to safety, then jump to it.
   39         mov     si, sp                  ! si = start of this code
   40         mov     di, #BUFFER             ! di = Buffer area
   41         mov     cx, #512/2              ! One sector
   42         cld
   43   rep   movs
   44         jmpf    BUFFER+migrate, 0       ! To safety
   45 migrate:
   46 
   47         mov     bp, #BUFFER+guide       ! Patched guiding characters
   48 altkey:
   49         movb    ah, #0x02               ! Keyboard shift status
   50         int     0x16
   51         testb   al, #0x08               ! Bit 3 = ALT key
   52         jz      noalt                   ! ALT key pressed?
   53 again:
   54         mov     bp, #zero               ! Ignore patched stuff
   55 noalt:
   56 
   57 ! Follow guide characters to find the boot partition.
   58         call    print
   59         .ascii  "d?\b\0"                ! Initial greeting
   60 
   61 ! Disk number?
   62 disk:
   63         movb    dl, #0x80 - 0x30        ! Prepare to add an ASCII digit
   64         call    getch                   ! Get number to tell which disk
   65         addb    dl, al                  ! dl = 0x80 + (al - '0')
   66         jns     n0nboot                 ! Result should be >= 0x80
   67         mov     si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
   68         cmpb    (bp), #0x23             ! Next guide character is '#'?
   69         jne     notlogical
   70         lea     si, 1-lowsec(bp)        ! Logical sector offset follows '#'
   71 notlogical:
   72         call    load                    ! Load chosen sector of chosen disk
   73         cmpb    (bp), #0x23
   74         je      boot                    ! Run bootstrap if a logical is chosen
   75 
   76         call    print                   ! Intro to partition number
   77         .ascii  "p?\b\0"
   78 
   79 part:
   80         call    getch                   ! Get character to tell partition
   81         call    gettable                ! Get partition table
   82         call    sort                    ! Sort partition table
   83         call    choose_load             ! Compute chosen entry and load
   84 
   85         cmpb    sysind(si), #MINIX_PART ! Minix subpartition table possible?
   86         jne     waitboot
   87 
   88         call    print                   ! Intro to slice number
   89         .ascii  "s?\b\0"
   90 
   91 slice:
   92         call    getch                   ! Get character to tell slice
   93         call    gettable                ! Get partition table
   94         call    choose_load             ! Compute chosen entry and load
   95 
   96 waitboot:
   97         call    print                   ! Intro to nothing
   98         .ascii  " ?\b\0"
   99         call    getch                   ! Supposed to type RETURN now
  100 n0nboot:jmp     nonboot                 ! Sorry, can't go further
  101 
  102 ! Get a character, either the patched-in, or one from the keyboard.
  103 getch:
  104         movb    al, (bp)        ! Get patched-in character
  105         testb   al, al
  106         jz      getkey
  107         inc     bp
  108         jmp     gotkey
  109 getkey: xorb    ah, ah          ! Wait for keypress
  110         int     0x16
  111 gotkey: testb   dl, dl          ! Ignore CR if disk number not yet set
  112         jns     putch
  113         cmpb    al, #0x0D       ! Carriage return?
  114         je      boot
  115         !jmp    putch
  116 
  117 ! Print a character
  118 putch:  movb    ah, #0x0E       ! Print character in teletype mode
  119         mov     bx, #0x0001     ! Page 0, foreground color
  120         int     0x10
  121         ret
  122 
  123 ! Print a message.
  124 print:  mov     cx, si          ! Save si
  125         pop     si              ! si = String following 'call print'
  126 prnext: lodsb                   ! al = *si++ is char to be printed
  127         testb   al, al          ! Null marks end
  128         jz      prdone
  129         call    putch
  130         jmp     prnext
  131 prdone: xchg    si, cx          ! Restore si
  132         jmp     (cx)            ! Continue after the string
  133 
  134 ! Return typed (or in patched data) means to run the bootstrap now in core!
  135 boot:
  136         call    print           ! Make line on screen look proper
  137         .ascii  "\b  \r\n\0"
  138         jmp     LOADOFF-BUFFER  ! Jump to LOADOFF
  139 
  140 ! Compute address of chosen partition entry from choice al into si, then
  141 ! continue to load the boot sector of that partition.
  142 choose_load:
  143         subb    al, #0x30               ! al -= '0'
  144         cmpb    al, #4                  ! Only four partitions
  145         ja      n0nboot
  146         movb    ah, #PENTRYSIZE
  147         mulb    ah                      ! al *= PENTRYSIZE
  148         add     ax, #BUFFER+PART_TABLE
  149         mov     si, ax                  ! si = &part_table[al - '0']
  150         movb    al, sysind(si)          ! System indicator
  151         testb   al, al                  ! Unused partition?
  152         jz      n0nboot
  153         !jmp    load                    ! Continue to load boot sector
  154 
  155 ! Load boot sector of the current partition.
  156 load:
  157         push    dx              ! Save drive code
  158         push    es              ! Next call sets es
  159         movb    ah, #0x08       ! Code for drive parameters
  160         int     0x13
  161         pop     es
  162         andb    cl, #0x3F       ! cl = max sector number (1-origin)
  163         incb    dh              ! dh = 1 + max head number (0-origin)
  164         movb    al, cl          ! al = cl = sectors per track
  165         mulb    dh              ! dh = heads, ax = heads * sectors
  166         mov     bx, ax          ! bx = sectors per cylinder = heads * sectors
  167         mov     ax, lowsec+0(si)
  168         mov     dx, lowsec+2(si) ! dx:ax = sector within drive
  169         cmp     dx, #[1024*255*63-255]>>16  ! Near 8G limit?
  170         jae     bigdisk
  171         div     bx              ! ax = cylinder, dx = sector within cylinder
  172         xchg    ax, dx          ! ax = sector within cylinder, dx = cylinder
  173         movb    ch, dl          ! ch = low 8 bits of cylinder
  174         divb    cl              ! al = head, ah = sector (0-origin)
  175         xorb    dl, dl          ! About to shift bits 8-9 of cylinder into dl
  176         shr     dx, #1
  177         shr     dx, #1          ! dl[6..7] = high cylinder
  178         orb     dl, ah          ! dl[0..5] = sector (0-origin)
  179         movb    cl, dl          ! cl[0..5] = sector, cl[6..7] = high cyl
  180         incb    cl              ! cl[0..5] = sector (1-origin)
  181         pop     dx              ! Restore drive code in dl
  182         movb    dh, al          ! dh = al = head
  183         mov     bx, #LOADOFF    ! es:bx = where sector is loaded
  184         mov     ax, #0x0201     ! ah = Code for read / al = one sector
  185         int     0x13
  186         jmp     rdeval          ! Evaluate read result
  187 bigdisk:
  188         mov     bx, dx          ! bx:ax = dx:ax = sector to read
  189         pop     dx              ! Restore drive code in dl
  190         push    si              ! Save si
  191         mov     si, #BUFFER+ext_rw ! si = extended read/write parameter packet
  192         mov     8(si), ax       ! Starting block number = bx:ax
  193         mov     10(si), bx
  194         movb    ah, #0x42       ! Extended read
  195         int     0x13
  196         pop     si              ! Restore si to point to partition entry
  197         !jmp    rdeval
  198 rdeval:
  199         jnc     rdok
  200 rderr:
  201         call    print
  202         .ascii  "\r\nRead error\r\n\0"
  203         jmp     again
  204 rdok:
  205         cmp     LOADOFF+MAGIC, #0xAA55
  206         je      sigok           ! Signature ok?
  207 nonboot:
  208         call    print
  209         .ascii  "\r\nNot bootable\r\n\0"
  210         jmp     again
  211 sigok:
  212         ret
  213 
  214 ! Get the partition table into my space.
  215 gettable:
  216         mov     si, #LOADOFF+PART_TABLE
  217         mov     di, #BUFFER+PART_TABLE
  218         mov     cx, #4*PENTRYSIZE/2
  219   rep   movs
  220         ret
  221 
  222 ! Sort the partition table.
  223 sort:
  224         mov     cx, #4                  ! Four times is enough to sort
  225 bubble: mov     si, #BUFFER+PART_TABLE  ! First table entry
  226 bubble1:lea     di, PENTRYSIZE(si)      ! Next entry
  227         cmpb    sysind(si), ch          ! Partition type, nonzero when in use
  228         jz      exchg                   ! Unused entries sort to the end
  229 inuse:  mov     bx, lowsec+0(di)
  230         sub     bx, lowsec+0(si)        ! Compute di->lowsec - si->lowsec
  231         mov     bx, lowsec+2(di)
  232         sbb     bx, lowsec+2(si)
  233         jae     order                   ! In order if si->lowsec <= di->lowsec
  234 exchg:  movb    bl, (si)
  235         xchgb   bl, PENTRYSIZE(si)      ! Exchange entries byte by byte
  236         movb    (si), bl
  237         inc     si
  238         cmp     si, di
  239         jb      exchg
  240 order:  mov     si, di
  241         cmp     si, #BUFFER+PART_TABLE+3*PENTRYSIZE
  242         jb      bubble1
  243         loop    bubble
  244         ret
  245 
  246 .data
  247 
  248 ! Extended read/write commands require a parameter packet.
  249 ext_rw:
  250         .data1  0x10            ! Length of extended r/w packet
  251         .data1  0               ! Reserved
  252         .data2  1               ! Blocks to transfer (just one)
  253         .data2  LOADOFF         ! Buffer address offset
  254         .data2  0               ! Buffer address segment
  255         .data4  0               ! Starting block number low 32 bits (tbfi)
  256 zero:   .data4  0               ! Starting block number high 32 bits
  257 
  258         .align  2
  259 guide:
  260 ! Guide characters and possibly a logical partition number patched here by
  261 ! installboot, up to 6 bytes maximum.

Cache object: ac5c5872aff3f4d1fa93f7f696c654fa


[ 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.