书承上文: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: # endif31: #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 251: # else
52: # define VIDEO_ENABLE 2 53: # endif54: #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 & params75: #else
76: .word 0 ! no size indication77: #endif
78: .org 6 79: 80: ! Boot device parameters. They are set by the installer. 81: 82: sig: .ascii "LILO"
83: vers: .word VERSION84: 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 flags96: 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 = 8108: ;;; .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.S118: 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 be126: ! 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 = 0x07C0132: /***************************************************/
133: 134: mov ss,ax135: 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 on146: #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: # endif161: # 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 mode165: int 0x10
166: cbw167: # else /* VIDEO_ENABLE==2 */
168: mov ax,#0x1200 ! enable video (VGA) 169: mov bl,#0x36 ! (probably a nop on EGA or MDA) 170: # endif171: int 0x10 ! video call
172: # if VIDEO_ENABLE==2
173: popa ! restore DX 174: # endif175: #endif
176: 177: #if (VIDEO_ENABLE&1) == 0
178: mov al,#0x0d ! gimme a CR ... 179: call display180: ; the suspect call for trashing DX on one BIOS:
181: mov al,#0x0a ! ... an LF ... 182: call display183: #endif
184: 185: #if defined(DEBUG_NEW)
186: mov ah,dl 187: call bout ! code in AH188: #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 code212: 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 DL222: 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 ! paranoia231: 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=0239: #else
240: mov dx,#LBA32_FLAG*256+0x80-1 ! device 80, flags=LBA32241: #endif
242: 243: vagain: 244: inc dx 245: xor eax,eax246: #if GEOMETRIC
247: inc ax ! geometric addressing248: #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 code256: ! 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 code270: 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 es278: #else
279: mov ax,ds ! get segment 280: add ax,#SETUP_STACKSIZE/16 ! + SECTOR_SIZE/16*2 281: mov es,ax282: #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 error304: #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 bout330: #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 start343: #endif
344: 345: 346: zzz:347: #ifndef DEBUG_NEW
348: hlt349: #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 ds360: #endif
361: pusha 362: 363: #ifndef JRC_DS_EQ_SS
364: push ss 365: pop ds366: #endif
367: 368: push bp ! BP==0 369: push bp ! BP==0 370: 371: push eax ! low order disk address372: #ifdef DEBUG_LARGE
373: xchg ax,dx 374: call wout 375: xchg ax,dx 376: call dout ! print out disk address377: #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,#0x41394: 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 geometry405: 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 cx416: #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/sect436: #if CYL1023
437: cmp ax,#1023438: #else
439: cmp ax,di440: #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: pusha465: int 0x13
466: #if 0
467: stc 468: mov ah,#0x9C469: #endif
470: jnc disk_okay 471: 472: dec bp ! does not alter CF, already 0473: jz disk_error3 ! go to "jc" with CF=1 & ZF=1
474: 475: xor ax,ax ! reset the disk controller476: 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 checked497: lea sp,(si+16) ! do not touch carry;
498: popa499: #ifndef JRC_DS_EQ_SS
500: pop ds501: #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,#0xF0529: adc al,#0x40 ! is now a hex char 0..9A..F
530: #endif
531: ; display - write byte in AL to console532: ; 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,#14541: int 0x10
542: popa ! restore all the registers543: #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: ret568: #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 area576: ! 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 16588: #ifdef FIRST
589: .org *-2590: .long FIRST ! boot block check
591: #else
592: .word 0xAA55 ! boot block signature593: #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的具体实现。