一.usbzip简介
ZIP一种软驱,在U盘广泛普及的今天很少用了,但是U盘也需要格式,象量产出的usb-cdrom光盘格式,格式化出的hdd硬盘格式,当然还有zip软盘格式.
zip是一个软盘,他的结构是hdd的一个子集,很象hdd硬盘的一个卷,但没有mbr,不能分区,形式和硬盘其中的一个分区fat32分区完全一样.
二、usbzip+原理
usbzip+的目标是兼容usbzip和usbhdd两种格式,他的技术核心是启动扇区同时拥有硬盘分区和卷bpb表,这样他看起来即是一个硬盘,又是一个软盘,
目的就是欺骗bios,试图(只是试图)让bios把他当软盘和硬盘都可以引导。这个设计是很棒的,但是实际测试效果却不太好。因为bios版本种类太多, 不是个个bios都会上当的。
注:BPB是Bios Paramater Block的缩写,在分区的第一个扇区,保存着卷的资料,有大量信息。
usbzip+的核心技术就是hdd硬盘分区表和软盘(卷)bpb表双格式,其他没有对zip增强什么。
三、usbzip+和usbhdd+的区别( 二者完全不同)
usbzip+兼容zip和hdd,但usbhdd+反过来并不兼容zip,他们是完全不同的技术。
usbhdd+是对usbhdd的加强,他是一个c/h/s(磁头/道/扇区)老的硬盘访问方式和lba扩展访问方式的隐身中转者(拦截int 13),让老的读盘程序不知不觉的使用了新的读盘技术,并没有试图去兼容zip(不过如果有的bios只检验了引导区的55aa标志,usbhdd+还是有可能以zip方式启动的, 不过这时usbhdd也可以)
而usbzip+是在引导区格式上下功夫,兼容usbhdd,算是不同领域、各显其能。
四、usbzip+的来源
usbzip+在ultroiso中出现很晚,其实grub早就实现了这个双格式。很久前软盘流行的时候,grub由于比较大,不能安装在软盘,是一个缺点.
grub就在设计上支持分区表和bpb双格式,目的是把软盘格式化硬盘分区的结构,以安装体积较大的grub,正好和现在的zip+技术不谋而合(但是在windows版本的安装程序Grubinst中并没有实现这个安装功能),usbzip+的始作佣应该是Grub。
五、我们什么时候需要usbzip+
从核心技术来看,zip+远没有hdd+精彩,而zip+的启动率也远没有hdd/hdd+高。但是某台机器需要U盘引导,但是只支持zip的情况下,就要用到usbzip,
当你不想把usbhdd闪存重新格式化,就可以用ultroiso便捷启动写入usbzip+的MBR,以尝试兼容性启动。
附:分析代码
seg000:7C00 jmp short loc_7C5E
;按照分区引导代码的约定,下面是bpb表,存放着分区卷的各种数据.可以参考ms fat12/16/32说明查看,同时可以看到熟悉的mswin4.1标志
seg000:7C00 EB 5C 90 4D 53 57 49 4E 34 2E 31 00 02 02 41 00 隲怣SWIN4.1.A.
seg000:7C10 02 00 02 00 00 F8 FB 00 3F 00 FF 00 00 00 00 00 ... .?. ....
seg000:7C20 C1 F7 01 00 00 01 29 C2 5F BE 90 4E 4F 20 4E 41 流..)耞緪NO NA
seg000:7C30 4D 45 20 20 20 20 46 41 54 31 36 20 20 20 00 00 ME FAT16 ..
seg000:7C40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
seg000:7C50 00 00 00 00 00 00 00 00 00 00 55 53 42 2B FA 31 ..........USB+?
;bpb表结束
seg000:7C5E
seg000:7C5E loc_7C5E: ; CODE XREF: seg000:7C00j
seg000:7C5E cli ;关中断
seg000:7C5F xor ax, ax
seg000:7C61 mov ds, ax
seg000:7C63 mov es, ax
seg000:7C65 mov ss, ax
seg000:7C67 mov sp, 7C00h
seg000:7C6A sti
seg000:7C6B cld
seg000:7C6C mov si, sp
seg000:7C6E mov di, 600h
seg000:7C71 mov cx, 100h
seg000:7C74 rep movsw
seg000:7C76 jmp far ptr 0:67Bh ;传送自身全部200字节去600处,把此处空间留给分区引导代码
-------------------------------
seg000:067B mov ds:byte_65D, dl ;备份bios参数,dl代表驱动器类型
seg000:067F mov si, 787h ;调用显示子程序显示启动信息
seg000:0682 call sub_72D
seg000:0685 test dl, 80h ;00H~7FH:软盘;80H~0FFH:硬盘
seg000:0688 jz short loc_6A8 ;是硬盘则转6a8
seg000:068A mov ah, 8 ;否则取磁盘参数
seg000:068C stc
seg000:068D int 13h ; DISK - DISK - GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)
seg000:068D ; DL = drive number
seg000:068D ; Return: CF set on error, AH = status code, BL = drive type
seg000:068D ; DL = number of consecutive drives
seg000:068D ; DH = maximum value for head number, ES:DI -> drive parameter
seg000:068F jb short loc_6A8 ;这段是zip方式启动的处理
seg000:0691 and ah, ah
seg000:0693 jnz short loc_6A8
seg000:0695 mov al, dh
seg000:0697 inc al
seg000:0699 jz short loc_6A8
seg000:069B and cx, 3Fh
seg000:069F jz short loc_6A8
seg000:06A1 mov ds:word_61A, ax
seg000:06A4 mov ds:word_618, cx
seg000:06A8
seg000:06A8 loc_6A8: ; CODE XREF: seg000:0688j
seg000:06A8 ; seg000:068Fj ...
seg000:06A8 mov si, 7BEh ;si指向分区表
seg000:06AB xor ax, ax ;ax清0
seg000:06AD mov cx, 4 ;分区表项计数器
seg000:06B0
seg000:06B0 loc_6B0: ; CODE XREF: seg000:06BCj
seg000:06B0 test byte ptr [si], 80h ;是活动分区吗
seg000:06B3 jz short loc_6B8 ;是转6b8
seg000:06B5 inc ax ;不是,计数器+1,继续查
seg000:06B6 mov bp, si
seg000:06B8
seg000:06B8 loc_6B8: ; CODE XREF: seg000:06B3j
seg000:06B8 add si, 10h ;指向下一个分区项
seg000:06BC loop loc_6B0 ;循环查
seg000:06BE dec ax ;ax-1=0的话,只有一个活动分区,正常,转6c3
seg000:06BF jz short loc_6C3 ;否则报告bios boot异常
seg000:06C1 int 18h ; TRANSFER TO ROM BASIC
seg000:06C1 ; causes transfer to ROM-based BASIC (IBM-PC)
seg000:06C1 ; often reboots a compatible; often has no effect at all
seg000:06C3
seg000:06C3 loc_6C3: ; CODE XREF: seg000:06BFj
;查测扩展int 13功能是否存在 AH = 41h; BX = 55AAh; DL = 驱动器号
seg000:06C3 mov dl, ds:byte_65D
seg000:06C7 mov ah, 41h ; 'A'
seg000:06C9 mov bx, 55AAh
seg000:06CC int 13h ; DISK -
seg000:06CE jb short loc_6E1
seg000:06D0 cmp bx, 0AA55h ;如果BX = AA55h则存在
seg000:06D4 jnz short loc_6E1 ;不存在转6e1
seg000:06D6 test cl, 1 ;cl是返回的每磁道扇区数
seg000:06D9 jz short loc_6E1 ;为1转6e1
seg000:06DB mov ax, 4200h ;这里是用lba方式读盘
seg000:06DE mov ds:word_782, ax ;[782]存成0042
seg000:06E1
seg000:06E1 loc_6E1: ; CODE XREF: seg000:06CEj
seg000:06E1 ; seg000:06D4j ...
seg000:06E1 call loc_73C ;73c是读分区引导公用子程序,
;由于zip是软盘方式,不一定支持lba int 13,不支持的话刚才跳过2条指令
seg000:06E4 jb short loc_725 ;读盘失败,进行死循环
seg000:06E6 mov ax, ds:7DFEh ;
seg000:06E9 cmp ax, 0AA55h ;判断是不是正常分区标志
seg000:06EC jnz short loc_725 ;没有标志55aa,死循环
seg000:06EE mov ax, ds:word_61A ;传递一些bpb参数给读出来的分区扇区bpb表中
seg000:06F1 mov ds:7C1Ah, ax
seg000:06F4 mov ax, ds:word_618
seg000:06F7 mov ds:7C18h, ax
seg000:06FA mov dl, ds:byte_65D
seg000:06FE mov si, 7C24h
seg000:0701 cmp byte ptr ds:7C10h, 0
seg000:0706 jz short loc_713
seg000:0708 cmp word ptr ds:7C16h, 0
seg000:070E jnz short loc_713
seg000:0710 mov si, 7C40h
seg000:0713
seg000:0713 loc_713: ; CODE XREF: seg000:0706j
seg000:0713 ; seg000:070Ej
seg000:0713 mov [si], dl
seg000:0715 or byte ptr ds:word_782+1, 1
seg000:071A call loc_73C
seg000:071D mov si, bp
seg000:071F cli
seg000:0720 jmp far ptr 0:7C00h ;放出控制权
seg000:0725 ; ---------------------------------------------------------------------------
seg000:0725
seg000:0725 loc_725: ; CODE XREF: seg000:06E4j
seg000:0725 ; seg000:06ECj
seg000:0725 mov si, 7AAh
seg000:0728 call sub_72D
seg000:072B
seg000:072B loc_72B: ; CODE XREF: seg000:loc_72Bj
seg000:072B jmp short loc_72B
seg000:072D
seg000:072D ; =============== S U B R O U T I N E =======================================
seg000:072D ;显示功能子程序
seg000:072D
seg000:072D sub_72D proc near ; CODE XREF: seg000:0682p
seg000:072D ; seg000:0728p ...
seg000:072D lodsb
seg000:072E and al, al
seg000:0730 jz short locret_73B;al如果为零,不显示返回
seg000:0732 mov ah, 0Eh
seg000:0734 mov bx, 7
seg000:0737 int 10h ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
seg000:0737 ; AL = character, BH = display page (alpha modes)
seg000:0737 ; BL = foreground color (graphics modes)
seg000:0739 jmp short sub_72D
seg000:073B ; ---------------------------------------------------------------------------
seg000:073B
seg000:073B locret_73B: ; CODE XREF: sub_72D+3j
seg000:073B retn
seg000:073B sub_72D endp
seg000:073B
seg000:073C ; ---------------------------------------------------------------------------
seg000:073C ;由于zip/hdd兼容方式的局限,有可能是不支持的lba 读盘的,
;这里把读盘子程序独立出来,作为公用
seg000:073C loc_73C: ; CODE XREF: seg000:loc_6E1p
seg000:073C ; seg000:071Ap
seg000:073C mov si, 624h ;si->624
seg000:073F mov word ptr [si], 10h
seg000:0743 xor eax, eax
seg000:0746 mov [si+6], ax
seg000:0749 mov [si+0Ch], eax
seg000:074D mov es, ax
seg000:074F inc ax
seg000:0750 mov [si+2], ax
seg000:0753 mov ax, [bp+8]
seg000:0756 mov dx, [bp+0Ah]
seg000:0759 mov [si+8], ax
seg000:075C mov [si+0Ah], dx
seg000:075F div ds:word_618
seg000:0763 inc dx
seg000:0764 mov cx, dx
seg000:0766 xor dx, dx
seg000:0768 div ds:word_61A
seg000:076C mov ch, al
seg000:076E shr ax, 2
seg000:0771 and al, 0C0h
seg000:0773 or cl, al
seg000:0775 mov dh, dl
seg000:0777 mov bx, 7C00h
seg000:077A mov [si+4], bx
seg000:077D mov dl, ds:byte_65D
seg000:0781 mov ax, 201h ; DATA XREF: seg000:06DEw
seg000:0781 ; seg000:0715w
seg000:0784 int 13h ; DISK - READ SECTORS INTO MEMORY
seg000:0784 ; AL = number of sectors to read, CH = track, CL = sector
seg000:0784 ; DH = head, DL = drive, ES:BX -> buffer to fill
seg000:0784 ; Return: CF set on error, AH = status, AL = number of sectors read
seg000:0786 retn
seg000:0780 06 B8 01 02 CD 13 C3 53 74 61 72 74 20 62 6F 6F ??肧tart boo
seg000:0790 74 69 6E 67 20 66 72 6F 6D 20 55 53 42 20 64 65 ting from USB de
seg000:07A0 76 69 63 65 2E 2E 2E 0D 0A 00 42 6F 6F 74 20 66 vice...
.Boot f
seg000:07B0 61 69 6C 65 64 00 00 00 01 8B 09 00 00 00 00 00 ailed...?.....
seg000:07C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
seg000:07D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
seg000:07E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01 ..............
seg000:07F0 01 00 0E FE 3F 07 3F 00 00 00 C1 F7 01 00 55 AA .? ?...流.U