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水木清华站∶精华区