zoukankan      html  css  js  c++  java
  • Lilo的实现

    书承上文:http://www.cnblogs.com/long123king/p/3549267.html

    我们找一份Lilo的源码来看一下

    http://freecode.com/projects/lilo

    ftp://metalab.unc.edu/pub/Linux/system/boot/lilo/lilo-22.8.src.tar.gz

    first.S就是写到MBR中的,我们刚刚分析了一部分的汇编代码文件

       1: #if 0
       2: ;  first.S  -  LILO first stage boot loader with LBA32 support */
       3: Copyright 1992-1998 Werner Almesberger.
       4: Copyright 1999-2005 John Coffman.
       5: All rights reserved.
       6:  
       7: Licensed under the terms contained in the file 'COPYING' in the 
       8: source directory.
       9:  
      10: #endif
      11: #define LILO_ASM
      12: #include "lilo.h"
      13: get common.s        /* as86 "include" will bypass the CPP */
      14:  
      15: #define DEBUG 0
      16:  
      17: #if VERSION_MINOR>=50
      18: # define DEBUG_NEW
      19:  
      20: # undef VIDEO_ENABLE
      21: # define VIDEO_ENABLE 3
      22:  
      23: # define VALIDATE !DEBUG    /* adds 0Dh bytes */
      24: # define SECOND_CHECK !DEBUG    /* adds  5h bytes */
      25: # define CYL1023 DEBUG        /* subs  8h bytes */
      26: # define GEOMETRIC !DEBUG    /* adds  1h byte  */
      27:  
      28: # if DEBUG
      29: #  define DEBUG_LARGE
      30: # endif
      31: #else
      32:  
      33: # define VALIDATE 1        /* adds 0Dh bytes */
      34: # define SECOND_CHECK 1        /* adds  5h bytes */
      35: # define CYL1023 0        /* subs  8h bytes */
      36: # define GEOMETRIC 1        /* adds  1h byte  */
      37: #endif
      38:  
      39:  
      40: !  VIDEO_ENABLE    for those systems that disable the video on boot
      41: !    = 0        first stage does not enable video
      42: !    = 1        use get vid mode/set vid mode to enable
      43: !    = 2        use VGA enable call to enable video
      44: !            (cannot use, as code gets too big)
      45: !    = 3        use direct mode set (mode 3, CGA, EGA, VGA)
      46: !    = 7        use direct mode set (mode 7, MDA)
      47: !
      48: #ifndef VIDEO_ENABLE
      49: # if VALIDATE==0
      50: #  define VIDEO_ENABLE 2
      51: # else
      52: #  define VIDEO_ENABLE 2
      53: # endif
      54: #endif
      55:  
      56: ! do not change the following -- it must correspond to the code in bsect.c
      57: #define RELOCATABLE -1
      58:  
      59:  
      60:     .text
      61:  
      62:     .globl    _main
      63:  
      64:     .org    0
      65:  
      66: zero:
      67: _main:    cli            ! NT 4 blows up if this is missing
      68:     jmp    start
      69:  
      70: stage:    .byte    STAGE_FIRST
      71:     .org    4
      72: reloc:
      73: #if RELOCATABLE
      74:     .word    theend-zero    ! size of the code & params
      75: #else
      76:     .word    0        ! no size indication
      77: #endif
      78:     .org    6
      79:  
      80: ! Boot device parameters. They are set by the installer.
      81:  
      82: sig:    .ascii    "LILO"
      83: vers:    .word    VERSION
      84: mapstamp: .long 0        ! map timestamp
      85:  
      86: length    =  *-sig        ! for the stage 1 vs stage 2 comparison
      87:  
      88: raid:    .long    0        ! raid sector offset
      89: tstamp:    .long    0        ! timestamp
      90: map_serial_no:    .long    0    ! volume S/N containing map file
      91: prompt:    .word    0        ! indicates whether to always enter prompt
      92:                 ! contains many other flags, too
      93:  
      94: d_dev:    .byte    0x80        ! map file device code
      95: d_flag:    .byte    0        ! disk addressing flags
      96: d_addr:    .long    0        ! disk addr of second stage index sector
      97:  
      98:  
      99: edd_packet    =  0
     100: ;;;    .word    16        ! size of packet
     101: ;;;    .word    1        ! count of bytes to read
     102:  
     103: edd_addr    =  4
     104: ;;;    .word    map2        ! where to read
     105: ;;;    .word    *-*        ! segment where to read
     106:  
     107: edd_d_addr    =  8
     108: ;;;    .long    1        ! low address or CX,DX (geometric)
     109:                 ! start at sector 1 for search in geo mode
     110:  
     111: ;;;    .long    0        ! hi address
     112:  
     113: #if 0
     114: !  These locations are referenced as EX_OFF 
     115: !                    (they used to be at CODE_START_1)
     116: ext_si:    .word    0        ! external interface
     117: ext_es:    .word    0        ! these locations are referenced in second.S
     118: ext_bx:    .word    0        ! do not disturb the ordering
     119: ext_dl:    .byte    0        ! second.S will check this magic number
     120: ext_dh:    .byte    0        ! not referenced, but must align stack
     121: ext_stack:
     122: #endif
     123:     
     124: /***************************************************/
     125: !    The following instruction MUST be
     126: !    first instruction after the CLI/JMP short
     127: !    at the start of the file; otherwise
     128: !    the boot sector relocation fails.
     129: !
     130: start:
     131:     mov    ax,#BOOTSEG    ! use DS,ES,SS = 0x07C0
     132: /***************************************************/
     133:  
     134:     mov    ss,ax
     135:     mov    sp,#SETUP_STACKSIZE    ! set the stack for First Stage
     136:     sti            ! now it is safe
     137:  
     138:     push    dx        ! set ext_dl (and ext_dh, which is not used)
     139:     push    bx        ! WATCH the order of pushes
     140:     push    es        ! set ext_es
     141:     push    si        ! set ext_si
     142:  
     143: #ifdef DEBUG_NEW
     144:     push    ds
     145:     push    es    ! just not enough space with debug turned on
     146: #endif
     147:  
     148: #define JRC_DS_EQ_SS
     149:  
     150:     cld            ! do not forget to do this !!!
     151:     mov    ds,ax        ! address data area
     152:     xor    bp,bp        ! shorted addressing
     153:  
     154: #if VIDEO_ENABLE
     155: ! a BIOS has been found where the video interrupt (0x10) trashes DX
     156: !   so, we had better be very paranoid about DX
     157: !
     158: # if VIDEO_ENABLE==2
     159:     pusha            ! protect DX
     160: # endif
     161: # if VIDEO_ENABLE > 2
     162:     mov    ax,#VIDEO_ENABLE    ! set video mode 3 or 7
     163: # elif VIDEO_ENABLE==1
     164:     mov    ah,#15        ! get video mode
     165:     int    0x10
     166:     cbw
     167: # else  /* VIDEO_ENABLE==2 */
     168:     mov    ax,#0x1200    ! enable video (VGA)
     169:     mov    bl,#0x36    ! (probably a nop on EGA or MDA)
     170: # endif
     171:     int    0x10        ! video call
     172: # if VIDEO_ENABLE==2
     173:     popa            ! restore DX
     174: # endif
     175: #endif
     176:  
     177: #if (VIDEO_ENABLE&1) == 0
     178:     mov    al,#0x0d    ! gimme a CR ...
     179:     call    display
     180: ; the suspect call for trashing DX on one BIOS:
     181:     mov    al,#0x0a    ! ... an LF ...
     182:     call    display
     183: #endif
     184:  
     185: #if defined(DEBUG_NEW)
     186:     mov    ah,dl
     187:     call    bout        ! code in AH
     188: #endif
     189:     mov    al,#0x4c    ! ... an 'L' ...
     190:     call    display
     191:  
     192: lagain:
     193:     pusha            ! preserve all the registers for restart
     194:  
     195:     push    ds
     196:     pop    es        ! use buffer at end of boot sector
     197:  
     198:     cmp    dl,#EX_DL_MAG    ! possible boot command line (chain.S)
     199:     jne    boot_in_dl
     200:     mov    dl,dh        ! code passed in DH instead
     201: boot_in_dl:
     202:  
     203:     mov    bx,#map2    ! buffer for volume search
     204:     mov    dh,[d_dev](bp)  ! map device to DH
     205:  
     206: #if VALIDATE
     207:     mov    ax,dx        ! copy device code to AL
     208:     and    ah,#0x80    ! AH = 00 or 80
     209:     xor    al,ah        ! hi-bits must be the same
     210:     js    use_installed
     211:     cmp    al,#MAX_BIOS_DEVICES    ! limit the device code
     212:     jae    use_installed    ! jump if DL is not valid
     213: #endif
     214:  
     215: ! map is on boot device for RAID1, and if so marked; viz.,
     216:  
     217:     test    byte ptr [prompt](bp),#FLAG_MAP_ON_BOOT
     218:     jnz    use_boot    ! as passed in from BIOS or MBR loader
     219:  
     220: use_installed:
     221:     mov    dl,dh        ! device code to DL
     222:     mov    esi,[map_serial_no](bp)    ! to search for
     223:     or    esi,esi
     224:     jz    done_search
     225:  
     226:     push    dx        ! save flags
     227:  
     228:     mov    ah,#8        ! get number of hard disks
     229:     mov    dl,#0x80
     230:     push    bx        ! paranoia
     231:     int    0x13
     232:     pop    bx
     233:     jc    error
     234:  
     235:     movzx    cx,dl        ! extend to word in CX
     236:  
     237: #if GEOMETRIC
     238:     mov    dx,#0x80-1    ! device 80, flags=0
     239: #else
     240:     mov    dx,#LBA32_FLAG*256+0x80-1    ! device 80, flags=LBA32
     241: #endif
     242:  
     243: vagain:
     244:     inc    dx
     245:     xor    eax,eax
     246: #if GEOMETRIC
     247:     inc    ax        ! geometric addressing
     248: #endif
     249:     call    disk_read    ! read 
     250:  
     251:     cmp    esi,[PART_TABLE_OFFSET-6](bx)
     252:     je    vol_found
     253:     loop    vagain
     254:  
     255:     pop    dx        ! restore specified BIOS code
     256:                 ! AX and DX are identical at this point
     257:  
     258: vol_found:
     259:         ! uses value in DX, stack may have extra value
     260:  
     261: done_search:    
     262: use_boot:
     263:     push    bx        ! save map2 for later
     264:  
     265:     mov    dh,[d_flag](bp)    ! get device flags to DH
     266:     mov    si,#d_addr
     267:     call    pread        ! increments BX
     268:  
     269:     mov    ah,#0x99    ! possible error code
     270:     cmp    dword (bx-4),#EX_MAG_HL    ! "LILO"
     271:     jne    error
     272:  
     273:     pop    si        ! point at #map2
     274:  
     275: #if 1
     276:     push    #SETUP_STACKSIZE/16 + BOOTSEG + SECTOR_SIZE/16*2
     277:     pop    es
     278: #else
     279:     mov    ax,ds        ! get segment
     280:     add    ax,#SETUP_STACKSIZE/16    !   + SECTOR_SIZE/16*2
     281:     mov    es,ax
     282: #endif
     283:     xor    bx,bx
     284:  
     285: sload:
     286:     call    pread        ! read using map at DS:SI
     287:     jnz    sload        ! into memory at ES:BX (auto increment)
     288:  
     289: ! Verify second stage loader signature
     290:     
     291:     mov    si,#sig        ! pointer to signature area
     292:     mov    di,si
     293:     mov    cx,#length    ! number of bytes to compare
     294:     mov    ah,#0x9A    ! possible error code
     295:     repe
     296:       cmpsb            ! check Signature 1 & 2
     297:     jne    error    ! check Signature 2
     298:  
     299: #if SECOND_CHECK
     300: /* it would be nice to re-incorporate this check */
     301:     mov    al,#STAGE_SECOND    ! do not touch AH (error code)
     302:     scasb
     303:     jne    error
     304: #endif
     305:  
     306: ! Start the second stage loader     DS=location of Params
     307:  
     308:     push    es        ! segment of second stage
     309:     push    bp        ! BP==0
     310:  
     311:     mov    al,#0x49    ! display an 'I'
     312:     call    display
     313:  
     314:     retf            ! Jump to ES:BP
     315:  
     316:  
     317:  
     318:  
     319: disk_error2:
     320:     mov    ah,#0x40    ; signal seek error
     321:  
     322: ! no return from error
     323: error:
     324:  
     325: #ifndef LCF_NO1STDIAG
     326:         mov    al,#32          ! display a space
     327:     call    display0
     328:  
     329:     call    bout
     330: #endif
     331:  
     332: #ifndef DEBUG_LARGE
     333:     dec    byte [zero](bp)        !  CLI == 0xFA == 250
     334:     jz    zzz
     335:  
     336: #ifndef DEBUG_NEW
     337:     mov    sp,#SETUP_STACKSIZE-4*2-8*2    ! set the stack for First Stage
     338: #else
     339:     mov    sp,#SETUP_STACKSIZE-4*2-2*2-8*2    ! set the stack for First Stage
     340: #endif
     341:     popa                ! restore registers for restart
     342:     jmp    near lagain        ! redo from start
     343: #endif
     344:  
     345:  
     346: zzz:
     347: #ifndef DEBUG_NEW
     348:     hlt
     349: #endif
     350:     jmp    zzz        ! spin; wait for Ctrl-Alt-Del
     351:  
     352:  
     353:  
     354:  
     355: ! packet read routine
     356:  
     357: disk_read:
     358: #ifndef JRC_DS_EQ_SS
     359:     push    ds
     360: #endif
     361:     pusha
     362:  
     363: #ifndef JRC_DS_EQ_SS
     364:     push    ss
     365:     pop    ds
     366: #endif
     367:  
     368:     push    bp        ! BP==0
     369:     push    bp        ! BP==0
     370:  
     371:     push    eax        ! low order disk address
     372: #ifdef DEBUG_LARGE
     373:     xchg    ax,dx
     374:     call    wout
     375:     xchg    ax,dx
     376:     call    dout        ! print out disk address
     377: #endif
     378:     push    es        ! memory segment ES
     379:     push    bx        ! memory offset BX
     380:     push    #1        ! sector count
     381:     push    #16        ! size of packet = 16 bytes
     382:     mov    si,sp        ! address of packet  DS:SI
     383:  
     384:     push    bx
     385:  
     386:     test    dh,#LINEAR_FLAG|LBA32_FLAG
     387:     jz    disk_geometric
     388:     
     389:     test    dh,#LBA32_FLAG
     390:     jz    disk_convert    ; it must be LINEAR
     391:  
     392:     mov    bx,#0x55AA    ;magic number
     393:     mov    ah,#0x41
     394:     int    0x13
     395:     jc    disk_convert
     396:     cmp    bx,#0xAA55    ;changed?
     397:     jne    disk_convert
     398:     test    cl,#EDD_PACKET    ;EDD packet calls supported
     399:     jnz    disk_edd
     400:  
     401: disk_convert:
     402:     push    dx
     403:     push    es        ! protect on floppies
     404:     mov    ah,#8        ! get geometry
     405:     int    0x13
     406:     pop    es
     407: disk_error3:            ! transfer through on CF=1
     408:     jc    error        ! disk_error12
     409:  
     410: #if !CYL1023
     411:     push    cx
     412:     shr    cl,#6        ;;;;
     413:     xchg    cl,ch       ;CX is max cylinder number
     414:     mov    di,cx       ;DI saves it
     415:     pop    cx
     416: #endif
     417:     shr    dx,#8
     418:     xchg    ax,dx        ;AX <- DX
     419:     inc    ax        ;AX is number of heads (256 allowed)
     420:  
     421: ; compensate for Davide BIOS bug
     422:     dec    cx        ; 1..63 -> 0..62;  0->63
     423:     and    cx,#0x003f    ;CX is number of sectors
     424:     inc    cx        ; allow Sectors==0 to mean 64
     425:  
     426:     mul    cx        ; kills DX also
     427:     xchg    ax,bx           ;save in BX
     428:  
     429:     mov    ax,[edd_d_addr](si)    ;low part of address
     430:     mov    dx,[edd_d_addr+2](si)    ;hi part of address
     431:  
     432:     cmp    dx,bx
     433:     jae    disk_error2    ;prevent division error
     434:  
     435:     div    bx        ;AX is cyl, DX is head/sect
     436: #if CYL1023
     437:     cmp    ax,#1023
     438: #else
     439:     cmp    ax,di
     440: #endif
     441:     ja    disk_error2    ;cyl is too big
     442:  
     443:     shl    ah,#6        ; save hi 2 bits
     444:     xchg    al,ah
     445:     xchg    ax,dx
     446:     div    cl        ;AH = sec-1, AL = head
     447:     or    dl,ah       ;form Cyl/Sec
     448:     mov    cx,dx
     449:     inc    cx        ; sector is 1 based
     450:  
     451:     pop    dx        ! restore device code
     452:     mov    dh,al        ! set head#
     453:     jmp    disk_read2
     454:  
     455:  
     456:  
     457: disk_edd:
     458:     mov    ah,#0x42
     459: disk_int13:
     460:     pop    bx
     461:  
     462:     mov    bp,#5
     463: disk_retry:
     464:     pusha
     465:     int    0x13
     466: #if 0
     467:     stc
     468:     mov    ah,#0x9C
     469: #endif
     470:     jnc    disk_okay
     471:  
     472:     dec    bp        ! does not alter CF, already 0
     473:     jz    disk_error3    ! go to "jc" with CF=1 & ZF=1
     474:  
     475:     xor    ax,ax        ! reset the disk controller
     476:     int    0x13
     477:     popa            ! reset AX,BX,CX,DX,SI
     478:     dec    bp        ! fix up BP count
     479:     jmp    disk_retry
     480:  
     481:  
     482: disk_geometric:
     483:     push    eax
     484:     pop    cx
     485:     pop    ax
     486:     mov    dh,ah
     487:  
     488: disk_read2:
     489:     mov    ax,#0x201    ;read, count of 1
     490:     jmp    disk_int13
     491:  
     492:  
     493: disk_okay:
     494: ; the pusha block is implicitly removed below
     495: ;;;    mov    (si+2*16-1),ah    ! set error code
     496: ;   the error code is never checked
     497:     lea    sp,(si+16)    ! do not touch carry; 
     498:     popa
     499: #ifndef JRC_DS_EQ_SS
     500:     pop    ds
     501: #endif
     502:     ret
     503:  
     504:  
     505:  
     506: ! Pointer Read -- read using pointer in DS:SI
     507:  
     508: pread:
     509:     lodsd            ! get address
     510:     or    eax,eax
     511:     jz    done
     512:     add    eax,[raid](bp)    ! reloc is 0 on non-raid
     513:     call    disk_read    
     514:  
     515:     add    bh,#SECTOR_SIZE/256        ! next sector
     516: done:
     517:     ret
     518:  
     519:  
     520:  
     521:  
     522: #if !defined(LCF_NO1STDIAG) || defined(DEBUG_NEW)
     523: bout:    rol     ax,#4        ! bring hi-nibble to position
     524:     call    nout
     525:     rol     ax,#4        ! bring lo-nibble to position
     526: nout:    and    al,#0x0F    ! display one nibble
     527:     daa            ! shorter conversion routine
     528:     add    al,#0xF0
     529:     adc    al,#0x40    ! is now a hex char 0..9A..F
     530: #endif
     531: ; display - write byte in AL to console
     532: ;    preserves all register contents
     533: ; 
     534: display0:
     535: #ifndef LCF_NOVGA
     536: display:
     537: #endif
     538:     pusha        ! make sure no register is changed
     539:     mov    bx,#7        !  BH=0, BL=07
     540:     mov    ah,#14
     541:     int    0x10
     542:     popa        ! restore all the registers
     543: #ifdef LCF_NOVGA
     544: display:
     545: #endif
     546:     ret
     547:  
     548: #ifdef DEBUG_LARGE
     549:  
     550: dout:    pushad
     551:     ror    eax,#16
     552:     call    wout
     553:     ror    eax,#16
     554:     call    wout
     555:     mov    al,#0x20    ! space
     556:     call    display
     557:     popad
     558:     ret
     559:  
     560: wout:    push    ax
     561:     call    bout    ! put out AH
     562:     pop    ax
     563:     push    ax
     564:     xchg    al,ah
     565:     call    bout    ! put out AL (now in AH)
     566:     pop    ax
     567:     ret
     568: #endif
     569:  
     570: theend:
     571:  
     572: !
     573: !   If 'first' loads as the MBR, then there must be space for the partition
     574: !   table.  If 'first' loads as the boot record of some partition, then
     575: !   the space reserved below is not used.  But we must reserve the area
     576: !   as a hedge against the first case.
     577: !
     578: !
     579:     .org    MAX_BOOT_SIZE    !
     580:     .word    0,0,0,0        ! space for NT, DRDOS, and LiLO volume S/N
     581:  
     582: !    .org    0x1be        ! spot for the partition table
     583: p_table:
     584:     .blkb    16
     585:     .blkb    16
     586:     .blkb    16
     587:     .blkb    16
     588: #ifdef FIRST
     589:     .org    *-2
     590:     .long    FIRST        ! boot block check
     591: #else
     592:     .word    0xAA55        ! boot block signature
     593: #endif
     594:  
     595: ! Better be exactly 0x200
     596:  
     597: map2    equ    *        ! addressed as ES:[map2]

        .text

        .globl    _main

        .org    0

    zero:
    _main:    cli            ! NT 4 blows up if this is missing
        jmp    start

    #if (VIDEO_ENABLE&1) == 0
        mov    al,#0x0d    ! gimme a CR ...
        call    display
    ; the suspect call for trashing DX on one BIOS:
        mov    al,#0x0a    ! ... an LF ...
        call    display
    #endif

    #if defined(DEBUG_NEW)
        mov    ah,dl
        call    bout        ! code in AH
    #endif
        mov    al,#0x4c    ! ... an 'L' ...
        call    display

    second.S是主要的加载文件

    我们找到下面代码:

    jmpi    0,SETUPSEG        ; segment part is a variable

    SYSSEG    =  0x1000    ; DEF_SYSSEG
    SETUPSEG = 0x9020    ; DEF_SETUPSEG

    因此:

       1: lb 0x90200
       2: c

    因此,对于调试Linux内核来说,只要在0x90200处设置断点,即可以直接进入到Setup程序部分,而不需要考虑Lilo的具体实现。

  • 相关阅读:
    去掉滚动条
    一些input用法
    jquery-ui datepicker
    js修改样式
    js时间
    跳转到页面的某个anchor
    事件传递
    flex对象.show()的时候display变成block
    html中传递信息
    button disable and enable
  • 原文地址:https://www.cnblogs.com/long123king/p/3549649.html
Copyright © 2011-2022 走看看