BBS水木清华站∶精华区

发信人: reden (鱼 ~ 君子律己以利人), 信区: Linux 
标  题: Boot Manager of FreeBSD 
发信站: BBS 水木清华站 (Tue Oct  6 20:23:03 1998) WWW-POST 
 
发信人: arbiter (仲裁者), 信区: FreeBSD 
标  题: Boot Manager 
发信站: 华南网木棉站 (Tue Oct  6 13:17:35 1998), 转信 
 
发信人: Satan (魔头), 信区: BestOS 
标  题: Boot Manager 
发信站: 安徽大学逍遥津站 (Mon Aug  3 16:13:55 1998), 转信 
 
FreeBSD自带的Boot Manager虽然不如Linux的lilo功能强大,但它只需按一个键就可以 
引导,界面直观,所以还是比较适合一些懒人的:-),但是有一个问题就是你如果重新安装 
win95什么的把MBR覆盖掉后,会发现不知道怎么再把Booteasy装上了,sysinstall也不行 

 
为此把Booteasy反汇编出来分析了一把,不料却被这段小代码吸引住了,真是....真是 
太精彩了,使我忍不住要把它贴出来奉献gei大家,让大家一起来享受编程世界的美妙乐趣 

小小的四百多个字节,可以gei你一个简单明了的启动选择界面,它能记住你上次的选择, 
能够认得十四种操作系统,而且能够启动第二硬盘!唯一遗憾的是,它的尺寸放不下起动 
扩展分区的代码.但这也不能阻止它成为一个优秀的Boot Manager. 
 
Booteasy的源码附在后面,安装它你需要在dos下用msas6.11编译一下,也许masm5.x也 
可以,但不要用tasm,因为它自做聪明地在代码里插入了一些nop,而我们的代码里面使 
用了绝对地址来寻址一些变量.然后你需要把生成的exe文件拷到linux或bsd下,用dd 
把其中的代码过虑出来.代码在exe文件里的位置可以通过exe文件头查到,如果你不熟 
悉,可以用十六进制编辑器查找33C0,这是程序的第一条语句. 
 
假如你生成了booteasy.exe,代码在偏移200h处 
dd if=booteasy.exe of=mbr bs=1 count=446 skip=512 
生成的mbr就是booteasy的代码,然后把它放到硬盘的第一个扇区 
dd if=mbr of=/dev/wd0 bs=1 count=446 
在做这步之前最好把你的MBR做个备份 
dd if=/dev/wd0 of=mbr.old bs=1 count=512 
 
重新启动机器,看看是不是好用了?如果你的机器起不来了,可不要来砍我哦~~~ 
我自己试的是没问题的,有空再做个简单的安装程序吧. 
本来还想把这个程序用AT&T的汇编语法改写,以便能用as编译,可是Unix在X86机上起 
家就是386,所以编译出的代码多了好些前缀(66h,67h),找了半天也没有找到生成8086 
代码的选项,只得做罢.如果有人能把它完善一下让它可以完全在dos下安装,也是造 
福众生的好事一件:-) 
 
--------------------------------cut here------------------------------< 
CODE    SEGMENT PUBLIC  'CODE' 
        ASSUME  CS:CODE,DS:CODE,ES:CODE,SS:CODE 
 
START: 
        XOR     AX,AX           ; 开机boot,booteasy被装入0:7c00h处 
        MOV     ES,AX 
        MOV     DS,AX 
        MOV     SS,AX 
        MOV     SP,07C00H 
        CLD 
        MOV     SI,SP 
        MOV     DI,0600H        ; 将自身移到0:600h处 
        MOV     CX,0100H 
        DB      0F2H,0A5H               ; repnz movsw 
                                        ; 不知道为什么masm6.11不许在movsw前 
                                        ; 加repnz前缀,不过用rep应该也可以... 
        DB      0EAH            ; jmp 0000:0600h 
        DB      060H,06H        ; 万恶的鬼子不许我们用直接远跳转,但是人民 
        DB      00H,00H         ; 的创造力是无穷的... 
_011B: 
        MOV     DX,BP 
        POP     AX 
        DB      0A2H            ; mov [0748],al 
        DB      48H,07H         ; #$@$^&$&#$@!这种直接寻址也不可以... 
        CMP     AL,035H 
        JZ      _0141           ; 从第二硬盘启动(用"另一个硬盘"比较恰当) 
        MOV     AH,010H 
        MUL     AH              ; ax=3?0h,?=1,2,3,4 
        ADD     AX,04AEH        ; ax=所选分区表项起始地址 
        XCHG    SI,AX 
        TEST    BYTE PTR [SI+04],0FFH   ; 无效分区?不知道有什么含义 
        JZ      _0171 
        MOV     BYTE PTR [SI],080H      ; 激活该分区 
        CALL    _0213                   ; 写回 
        MOV     DH,[SI+01]              ; 分区起始头 
        MOV     CX,[SI+02]              ; 分区起始扇区和起始柱面 
        JMP     _0149 
_0141: 
        CALL    _0213 
        MOV     CX,0001         ; 扇区号从1而不是从0开始 
        XOR     DL,CL           ; dl=80,执行后为81;dl=81,执行后为80 
_0149: 
        MOV     BX,07C00H       ; 装入地址 
        MOV     AX,0201H        ; ah=2,读扇区; al:读扇区数目 
        INT     13H             ; 装入 
        JB      _0171 
        CMP     WORD PTR [BX+01FEH],0AA55H      ; 该硬盘有效? 
        JNZ     _0171 
        DB      0EAH            ; 
        DB      00H,07CH        ; jmp 0:7c00h 
        DB      00H,00H         ; 
_0160: 
        CMP     DL,081H         ; 第二硬盘? 
        JZ      _0167 
        MOV     DL,080H         ; 第一硬盘? 
_0167: 
        MOV     BP,DX 
        INC     DX 
        XOR     DL,0B3H 
        DB      88H,16H         ; mov [073ah],dl 
        DB      3AH,07H         ; disk ?; 81h^b3h=32h,82h^b3h=31h 
_0171: 
        MOV     DI,07BEH        ; 分区表起始地址 
        MOV     CX,0004         ; 分区数目 
        DB      0C6H,06H        ; 
        DB      2DH,07H         ; mov [072dh],31h 
        DB      31H             ; 
        XOR     DH,DH 
_017E: 
        MOV     [DI],CH 
        MOV     AL,[DI+04]      ; 分区类型 
        CMP     AL,00           ; 空表项,跳过 
        JZ      _01AA 
        CMP     AL,05           ; 扩展分区,跳过 
        JZ      _01AA 
        INC     DH 
        MOV     SI,072AH        ; 显示: F# . . . 
        CALL    _0204 
        MOV     SI,0748H        ; 装入OS名字索引表地址 
_0196: 
        INC     SI 
        INC     SI 
        MOV     BX,[SI] 
        OR      BH,BH 
        JZ      _01A3           ; OS名字搜索完,未找到,显示: ?? 
        XOR     BH,[DI+04]      ; 分区类型代码与该OS代码比较 
        JNZ     _0196 
_01A3: 
        LEA     SI,[BX+0772H]   ; 显示该分区类型OS名称 
        CALL    _0204 
_01AA: 
        ADD     DI,010H         ; 下一个表项 
        DB      0FEH,06H        ; inc [072dh] 
        DB      2DH,07H         ; 当前分区增量 
        LOOP    _017E 
        DB      80H,3EH         ; 
        DB      75H,04H         ; cmp byte ptr [0475h],02 
        DB      02H             ; BIOS数据区0:475h存放硬盘数量 
        JZ      _01C5 
        MOV     SI,073BH 
        OR      DH,DH 
        JNZ     _01CB 
        INT     18H             ; 没有一个分区有效,进入ROM BASIC 
        JMP     _0171 
_01C5: 
        MOV     SI,072AH        ; 若是两个硬盘,显示: F5 . . . disk 2(or 1) 
        CALL    _0204 
_01CB: 
        CALL    _0204           ; 显示: Default F# 
_01CE: 
        XOR     AH,AH 
        INT     1AH             ; 读实时时钟 
        MOV     BX,DX 
        ADD     BX,060H         ; 设置等待时间(约3秒) 
_01D7: 
        MOV     AH,01 
        INT     16H             ; 是否有键盘输入? 
        MOV     AH,00           ; 把这条语句放在这里节省了一条指令:-) 
        JNZ     _01EA           ; 有,跳转 
        INT     1AH             ; 无,读时钟 
        CMP     DX,BX           ; 等待时间到? 
        JB      _01D7           ; 没有,继续循环 
_01E5: 
        DB      0A0H            ; mov al,[0748h] 
        DB      48H,07H         ; 默认启动分区 
        JMP     _01F4 
_01EA: 
        INT     16H 
        MOV     AL,AH           ; 返回: al:ascii码,ah:扫描码 
        CMP     AL,01CH         ; 回车? 
        JZ      _01E5           ; 是,转Default 
        ADD     AL,0F6H         ; F1的扫描码:3bh,加f6h为31,对应ascii码1... 
_01F4: 
        CMP     AL,031H 
        JB      _01CE 
        CMP     AL,035H 
        JA      _01CE           ; 非F1-F5,重新开始读 
        PUSH    AX 
        MOV     SI,0728H 
        MOV     BX,061BH 
        PUSH    BX              ; 跳到_011B 
_0204: 
        CLD                     ; 显示字符串子程序 
        LODSB 
        PUSH    AX 
        AND     AL,07FH 
        MOV     AH,0EH 
        INT     10H 
        POP     AX 
        TEST    AL,080H         ; 大于等于80h的字符为结束字符 
        JZ      _0204           ; 为什么要这么做看了OS名称表你就知道了:-) 
        RET 
_0213: 
        PUSH    SI 
        MOV     AX,0301H        ; 写一个扇区 
        MOV     BX,0600H        ; 缓冲区地址 
        MOV     CX,0001         ; 柱面号和扇区号 
        XOR     DH,DH           ; 磁头号 
        INT     13H 
        POP     SI 
        POP     SI 
        DB      0C6H,06H        ; 
        DB      48H,07H         ; mov byte ptr [0748h],3fh 
        DB      3FH             ; 
        RET 
 
_0228:  DB      0DH,8AH 
_022A:  DB      0DH,0AH 
_022C:  DB      "F? . . .",0A0H 
_0235:  DB      "disk 2",0DH,0AH,0AH 
_023E:  DB      "Default: F?",0A0H 
 
_024A:  DB      00H,01H,00H,04H,00H,06H         ; OS名称索引表: 
_0250:  DB      03H,07H                         ; 每一表项两个字节,第一 
_0252:  DB      07H,0AH                         ; 字节为偏移量,第二字节 
_0254:  DB      0AH,063H                        ; 如: Linux的类型码为82h 
_0256:  DB      0EH,064H,0EH,065H               ; 查得偏移量为19h,在OS名 
_025A:  DB      014H,080H,014H,081H             ; 称表里可以查到名字为 
_025E:  DB      019H,082H                       ; Linux 
_0260:  DB      01EH,093H 
_0262:  DB      024H,0A5H 
_0264:  DB      027H,09FH 
_0266:  DB      02BH,075H 
_0268:  DB      02FH,052H,02FH,0DBH 
_026C:  DB      032H,040H 
_026E:  DB      037H,0F2H 
_0270:  DB      03DH,00H 
                                                ; OS名称表: 
_0272:  DB      "DO",0D3H                       ; DOS 
_0275:  DB      "HPF",0D3H                      ; HPFS 
_0279:  DB      "Os",0B2H                       ; Os2 
_027C:  DB      "Uni",0F8H                      ; Unix 
_0280:  DB      "Novel",0ECH                    ; Novell 
_0286:  DB      "Mini",0F8H                     ; Minix 
_028B:  DB      "Linu",0F8H                     ; Linux 
_0290:  DB      "Amoeb",0E1H                    ; Amoeba 
_0296:  DB      "BS",0C4H                       ; BSD 
_0299:  DB      "BSD",0E9H                      ; BSDI 
_029D:  DB      "PCI",0D8H                      ; PCIX 
_02A1:  DB      "CP",0CDH                       ; CPM 
_02A4:  DB      "Veni",0F8H                     ; Venix 
_02A9:  DB      "Dosse",0E3H                    ; Dossec 
_02AF:  DB      "?",0BFH                        ; Unknown 
                                                ; 你会奇怪为什么每个名字的 
                                                ; 最后一个字符都不对? 
                                                ; 你把它xor 80h看看:-) 
                                                ; 这样做的好处是每个名字的 
                                                ; 最后一个字符同时又做了结 
                                                ; 束符,你可以算算省了多少 
                                                ; 字节 
 
_02B1:  DB      13 DUP(0)                       ; 剩下的字节填零 
 
CODE    ENDS 
        END     START 
 
----------------------------------end-------------------------------------< 
 
  
-- 
    白马带著她一步步的回到中原。白马已经老了,只能慢慢的走, 
但终是能回到中原的。江南有杨柳、桃花,有燕子、金鱼…… 
汉人中有的是英俊勇武的少年,倜傥潇洒的少年……但这个美 
丽的姑娘就像古高昌国人那样固执: 
 
    「那都是很好很好的,可是我偏不喜欢。」  
 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 159.226.21.168]  

BBS水木清华站∶精华区