无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 24089|回复: 53

试着解读 0PE 的专用菜单文件

[复制链接]
发表于 2009-8-27 23:38:58 | 显示全部楼层 |阅读模式
`
 
 
 
试着解读 0PE 的专用菜单文件 MENU.0PE

 
 
 
  这个菜单文件是从 〇peZip扩展版二合一090620.ISO 的 grldr 中提取出来的,根据自己的理解加了一些注释(理解不一定正确),还有很多看不懂的地方,希望 Pseudo 大侠指点迷津,也希望大家多发表自己的看法,让大家更深入的了解 0PE。
  
    看了一下 Grub4Dos 的 Readme 文件,知道了 Grub4Dos 的一些高级用法,把注释补充完整了,如有错误,恳请指正。

    关于 Grub4Dos 的高级用法,可以参考这个帖子,里面有很详细的说明:
    http://bbs.znpc.net/viewthread.php?tid=5587&extra=page%3D2&page=1
 
 
 
 
------------------------------------------------------------

; 注:字符串/0PE/0PE.ISO定位0PE.ISO.菜单<4KB

; 设置屏幕颜色
color white/blue blue/yellow light-red/blue 10

; pseudo 大侠发明的写法,指定一个不存在的配置文件“NoExist”
; 让 PXE 启动时不去搜索 PXE 服务器上的其他配置文件,加快启动速度。
pxe detect NotExist

; 关闭 Debug
debug off

; 取内存做变量使用,6000:0000开始的 1K 空间作为用户自己的变量区

; 存放出错标记 | ErrorFlag
write 0x60000 0

; 存放 PXE 启动标记 | PXEBoot
write 0x60064 0

; 存放选中的菜单项序号 | MenuNum
write 0x60068 0

; 存放 Debug 状态 | DebugFlag
write 0x60110 0

; 保存当前根分区号 | RootDriveID
write 0x60130 0

; 保存当前根驱动器 | RootDrive
write 0x60134 0

; 这个好象未使用
write 0x602A0 0

; 标记是 XP 还是 2003 | SysVer
write 0x60300 0

; 这里大概是判断 Grub4Dos 版本是否匹配(read 返回值 0 为假,非 0 为真)
cat --locate-align=1 (md)+1,1 || write 0x60000 1
read 0x60000 && Error:GRUB4DOS Version Mismatched! Press any key to reboot...
read 0x60000 && reboot

; 判断是否是 PXE 启动
checkrange 0x21 read 0x8280 && write 0x60064 1

; 默认第一个菜单
default 1
; 超时时间 5 秒
timeout 5



; 菜单0
title                      0PE for Windows XP/2003    by Pseudo 2009.6.20
; 空菜单
clear



; 菜单1
title                 [1] For XP, with SRS1.ZIP.\n   Main S&R&S Drivers Library.
; 设置菜单选择标记
write 0x60068 1
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单2
title                 [2] For XP, with SRS2.ZIP.\n   Secondary S&R&S Drivers Library.
; 设置菜单选择标记
write 0x60068 2
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单3
title                 [3] For XP, with F6.ZIP.\n   OEM S&R&S Drivers Floppy Disk Emulation (press F6/autodetect).
; 设置菜单选择标记
write 0x60068 3
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 空菜单,夹在其它菜单中间,则无效,放在第一个菜单之前,则会让 TimeOut 失效。
; 疑为作者笔误
title



; 菜单4
title                 [4] User Menu with F6.ZIP.\n   OEM S&R&S Drivers Floppy Disk Emulation (press F6/autodetect).
; 设置菜单选择标记
write 0x60068 4
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单5
title                 [5] For 2K3, with SRS1.ZIP.\n   Main S&R&S Drivers Library.
; 设置菜单选择标记
write 0x60068 5
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单6
title                 [6] For 2K3, with SRS2.ZIP.\n   Secondary S&R&S Drivers Library.
; 设置菜单选择标记
write 0x60068 6
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单7
title                 [7] For 2K3, with F6.ZIP.\n   OEM S&R&S Drivers Floppy Disk Emulation (press F6/autodetect).
; 设置菜单选择标记
write 0x60068 7
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单8
title                 [8] MS DOS 7.1
; 设置菜单选择标记
write 0x60068 8
; 通过错误语句跳转到菜单 10
fallback 10
kernel



; 菜单9
title                 [9] Grub4Dos Debug On/Off.\nTurn on/off debug status.
; 清屏
clear
; 关闭 Debug
debug off


; 如果 DebugFlag 为 0,则设置 DebugFlag 2
read 0x60110 || write 0x60110 2
; 如果 DebugFlag 为 1,则设置 DebugFlag 0
checkrange 1 read 0x60110 && write 0x60110 0
; 如果 DebugFlag 为非 0(比如为 2),则设置 DebugFlag 1
read 0x60110 && write 0x60110 1

; 根据 DebugFlag,设置提示信息
read 0x60110 || pause Debug is now off...
read 0x60110 && pause Debug is now on...
; 根据 DebugFlag,设置 Debug 状态
read 0x60110 || debug off
read 0x60110 && debug on
; 添加 Kernel 命令,使菜单生效,否则菜单不可选
kernel || clear



; 菜单10,处理选择的系统类型 SysVer
title

; 提示 root 位置,用于调试脚本
pause --wait=0 Boot drive:
debug on
root
debug off

; 恢复 Debug  状态
read 0x60110 && debug on

; 判断选择的菜单是否是 2003 系统 ( 菜单 5-7 )
checkrange 5:7 read 0x60068 && write 0x60300 1

; 如果不是 2003 系统,将跳转到 菜单 11
fallback 11
; 如果是 2003 系统,将跳转到菜单 12
read 0x60300 && fallback 12
; 开始跳转
fallback F



; 菜单11,处理 XP 系统,SysVer = 0
title


;
fallback 14

; 复位 ErrorFlag
write 0x60000 1

; 如果未找到 root 下面的 /0PE/BUFXP.GZ 则设置 ErrorFlag 为 0
ls /0PE/BUFXP.GZ || write 0x60000 0

; 如果是 PXE 启动,则设置 ErrorFlag 为 0
read 0x60064 && write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 14
read 0x60000 && kernel

; 复位 ErrorFlag
write 0x60000 1

; 查找所有盘的 /0PE/BUFXP.GZ 文件,找不到则设置 ErrorFlag 为 0
find --set-root /0PE/BUFXP.GZ || write 0x60000 0

; 如果 ErrorFlag 不为 0 ,则跳转到菜单 14
read 0x60000 && kernel


;
fallback 13

; 复位 ErrorFlag
write 0x60000 1

; 如果未找到 root 下面的 /0PE/0PE.ISO 则设置 ErrorFlag 为 0
ls /0PE/0PE.ISO || write 0x60000 0

; 如果是 PXE 启动,则设置 ErrorFlag 为 0
read 0x60064 && write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 13
read 0x60000 && kernel

; 复位 ErrorFlag
write 0x60000 1

; 查找所有盘的 /0PE/0PE.ISO 文件,找不到则设置 ErrorFlag 为 0
find --set-root /0PE/0PE.ISO || write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 13
read 0x60000 && kernel


; 如果是 PXE 启动,则设置 root 为 PXE 服务器
read 0x60064 && rootnoverify (pd)

; 设置标志:不自动解压 gzip 格式的文件
write 0x82A4 1


;
fallback 14
; 如果 PXE 中存在 /0PE/BUFXP.GZ (判断文件大小是否为 0)则跳转到 菜单14
cat --length=0 /0PE/BUFXP.GZ && kernel

; 设置标志:自动解压 gzip 格式的文件
write 0x82A4 0


;
fallback 13

; 如果 PXE 中存在 /0PE/0PE.ISO 则跳转到 菜单13
cat --length=0 /0PE/0PE.ISO && kernel

; 判断选择的是否是用户自定义菜单,如果是,则设置 SysVer 为 1
checkrange 4 read 0x60068 && write 0x60300 1


;
fallback 12

; 如果是是用户自定义菜单,则跳转到菜单 12 继续处理
read 0x60300 && kernel

; 提示未找到 /0PE/BUFXP.GZ 和 /0PE/0PE.ISO
pause Error:/0PE/BUFXP.GZ and /0PE/0PE.ISO not found!



; 菜单12,处理 2003 系统,SysVer = 1,过程同 XP 系统
title

;
fallback 14

; 复位 ErrorFlag
write 0x60000 1

; 如果未找到 root 下面的 /0PE/BUF2K3.GZ 则设置 ErrorFlag 为 0
ls /0PE/BUF2K3.GZ || write 0x60000 0

; 如果是 PXE 启动,则设置 ErrorFlag 为 0
read 0x60064 && write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 14
read 0x60000 && kernel

; 复位 ErrorFlag
write 0x60000 1

; 查找所有盘的 /0PE/BUF2K3.GZ 文件,找不到则设置 ErrorFlag 为 0
find --set-root /0PE/BUF2K3.GZ || write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 14
read 0x60000 && kernel


;
fallback 13

; 复位 ErrorFlag
write 0x60000 1

; 如果未找到 root 下面的 /0PE/0PE.ISO 则设置 ErrorFlag 为 0
ls /0PE/0PE.ISO || write 0x60000 0

; 如果是 PXE 启动,则设置 ErrorFlag 为 0
read 0x60064 && write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 13
read 0x60000 && kernel

; 复位 ErrorFlag
write 0x60000 1

; 查找所有盘的 /0PE/0PE.ISO 文件,找不到则设置 ErrorFlag 为 0
find --set-root /0PE/0PE.ISO || write 0x60000 0

; 如果 ErrorFlag 不为 0,则跳转到菜单 13
read 0x60000 && kernel

; 如果是 PXE 启动,则设置 root 为 PXE 服务器
read 0x60064 && rootnoverify (pd)

; 设置标志:不自动解压 gzip 格式的文件
write 0x82A4 1


;
fallback 14

; 如果 PXE 中存在 /0PE/BUF2K3.GZ 则跳转到菜单 14
cat --length=0 /0PE/BUF2K3.GZ && kernel

; 设置标志:自动解压 gzip 格式的文件
write 0x82A4 0


;
fallback 13

; 如果 PXE 中存在 /0PE/0PE.ISO 则跳转到菜单 13
cat --length=0 /0PE/0PE.ISO && kernel

; 提示未找到 /0PE/BUF2K3.GZ 和 /0PE/0PE.ISO
pause Error:/0PE/BUF2K3.GZ and /0PE/0PE.ISO not found!



; 菜单13,装载 0PE.ISO,然后跳转到 菜单14 继续启动
title

; 提示 root 位置,用于调试脚本
pause --wait=0 Current drive of 0PE.ISO:
debug on
root
debug off

; 恢复 Debug  状态
read 0x60110 && debug on

; 提示 装载0PE.ISO
pause --wait=0 Loading /0PE/0PE.ISO...

; 磁盘装载 0PE.ISO,如果不成功,则内存装载 0PE.ISO
map /0PE/0PE.ISO (0xff) || map --mem /0PE/0PE.ISO (0xff)

; 激活 map 的结果
map --hook

; 设置 root 为 0PE.ISO 的装载位置
rootnoverify (0xff)

; 跳转到 菜单14 继续处理
fallback 14 && kernel



; 菜单14,启动系统
title

; 设置标志:自动解压 gzip 格式的文件
write 0x82A4 0

; 保存当前根分区号,和当前根所在驱动器
dd if=(md) of=(md) bs=1 count=8 skip=0x829c seek=0x60130

; 提示 root 位置,用于调试脚本
pause --wait=0 Current drive of BUF*.GZ:
debug on
root
debug off

; 恢复 Debug  状态
read 0x60110 && debug on

; 根据 SysVer 提示并装载 XP 系统 Buf 到 (hd7)
read 0x60300 || pause --wait=0 Loading /0PE/BUFXP.GZ...
read 0x60300 || map --mem ()/0PE/BUFXP.GZ (hd7)

; 根据 SysVer 提示并装载 2003 系统 Buf 到 (hd7)
read 0x60300 && pause --wait=0 Loading /0PE/BUF2K3.GZ...
read 0x60300 && map --mem ()/0PE/BUF2K3.GZ (hd7)

; 激活 map 结果
map --hook

; 向 (hd7,0)/BAT/_ENV.BAT 中写入 set PEISO=/0PE/0PE.ISO\r\n,并继续从(hd7,0)/BAT/MENU.GZ 中的菜单启动
write --offset=200 (hd7,0)/BAT/_ENV.BAT set PEISO=/0PE/0PE.ISO\r\n && configfile (hd7,0)/BAT/MENU.GZ


------------------------------------------------------------
 
 
 
`


[ 本帖最后由 stevenldj 于 2009-9-2 16:59 编辑 ]

评分

参与人数 1无忧币 +10 收起 理由
zhhsh + 10

查看全部评分

 楼主| 发表于 2009-8-28 00:42:47 | 显示全部楼层
`


MENU.GZ 中的菜单内容



    此菜单接着 MENU.0PE 继续启动。

    看完整个 0PE 专用菜单,才知道,整个菜单只是根据用户不同的选择,将相应的 PE 所需文件包读入 DOS 所在的虚拟磁盘中,然后由 DOS 来处理这些文件,构建 PE 启动所需要的环境。

    这个菜单看懂了,接下来的 DOS 批处理文件可没那么容易理解了。



MENU in MENU.GZ
--------------------------------------------------------------------------------


;0PE menu by Pseudo 2009.6.6
; 1、本地优先、解开的优先。有利于减少网络流量和内存占用。
;    根据首次找到的/0PE/BUFXP.GZ(BUF2K3.GZ)确定初始目录。先本地,后PXE服务器(PXE启动时);
;    先找解开的文件,后找/0PE/0PE.ISO,将其仿真为光盘并在其内找。
; 2、初始目录优先(先入为主)。初始目录优先有利于各组件版本一致,并减少搜索代价。
;    找其它文件次序:初始目录,本地盘(含仿真光盘),PXE服务器(PXE启动时)。
; 3、根驱动优先。根驱动一般是为本机定制的驱动。
;    如果存在磁盘驱动/OEM_SRS.ZIP,则不再找其它磁盘驱动,即使选了相应菜单。
; 由于初始目录优先,混合启动时,本地(包括0PE.ISO里)若有BUFXP.GZ(BUF2K3.GZ),则倾向于使用本地文件,缺文件才找PXE服务器上的。
; 本地若无BUFXP.GZ(BUF2K3.GZ),则倾向于使用PXE服务器上的文件,缺文件才从本地找。






; 设置 Debug 状态
read 0x60110 || debug off

; 将 Debug 状态传递到 Dos 启动过程中
read 0x60110 && write --offset=480 (hd7,0)/BAT/_ENV.BAT set DEBUGON=1\r\n

; 根据选择的菜单项,设置启动类别(XP,2003,DOS,用户自定义菜单)
write --offset=50 (hd7,0)/BAT/_ENV.BAT set SYS.VER=XP\r\n
checkrange 5:7 read 0x60068 && write --offset=50 (hd7,0)/BAT/_ENV.BAT set SYS.VER=2003\r\n
checkrange 8 read 0x60068 && write --offset=50 (hd7,0)/BAT/_ENV.BAT set SYS.VER=DOS\r\n
checkrange 4 read 0x60068 && write --offset=150 (hd7,0)/BAT/_ENV.BAT set MENU.USR=1\r\n

; 0x602A0 之前好象都未使用,怎么能在这里做判断呢?传递环境变量到 DOS:set BTM=ISO
read 0x602A0 && write (hd7,0)/BAT/_ENV.BAT set BTM=ISO\r\n

; 如果是 PXE 启动,传递环境变量到 DOS:set BTM=PXE
read 0x60064 && write (hd7,0)/BAT/_ENV.BAT set BTM=PXE\r\n

; 如果是 PXE 启动,则在 DOS 启动时加载 undi_drv.exe
read 0x60064 && write (hd7,0)/config.sys device=bin\\undi_drv.exe\r\n

; 如果是 PXE 启动,则将 PXE 的“客户端IP”,“服务端IP”,“网关IP” 写入 PXE_XIP.COM 中。
; PXE_XIP.COM 可能是 Pseudo 写的一个小程序
read 0x60064 && dd if=(md) of=(hd7,0)/BIN/PXE_XIP.COM bs=1 count=12 skip=0x8284 seek=0x166

; 流程控制变量
write 0x60234 0



default 0
timeout 0

; 隐藏菜单
hiddenmenu



; 菜单 [0] 流程控制
title

; [1] 0x60234 初始值就为 0,所以首先进入菜单 1 执行
checkrange 0 read 0x60234 && fallback 1

; [2]-[3]KERNEL.ZIP 可能返回 3 或者 出错后进入GRUB的命令行
checkrange 1 read 0x60234 && fallback 2

; [4]-[5]OEM_SRS.ZIP 可能返回 4,5,6,7,8
checkrange 3 read 0x60234 && fallback 4

; [6]-[7]SRS1.ZIP 返回 8
checkrange 4 read 0x60234 && fallback 6

; [8]-[9]SRS2.ZIP 返回 8
checkrange 5 read 0x60234 && fallback 8

; [10]-[11]F6.ZIP 可能返回 8,7
checkrange 6 read 0x60234 && fallback 10

; [12]xp/03switch 可能返回 9,10
checkrange 8 read 0x60234 && fallback 12

; [13]-[14]xp-ext1 可能返回 11(需要 xpext2),12(不需要 xpext2)
checkrange 9 read 0x60234 && fallback 13

; [15]-[16]2k3-ext1 可能返回 13(需要 2k3ext2),14(不需要 2k3ext2)
checkrange 10 read 0x60234 && fallback 15

; [17]-[18]xp-EXT2.WIM 可能返回 15(需要 NET.WIM),16(不需要)
checkrange 11 read 0x60234 && fallback 17

; [19]-[20]2k3-EXT2.WIM 可能返回 17(需要 NET.WIM),18(不需要)
checkrange 13 read 0x60234 && fallback 19

; [21]-[22]xp-NET.WIM 可能返回 19(需要 DEF.CAB),20(不需要)
checkrange 15 read 0x60234 && fallback 21

; [23]-[24]2k3-NET.WIM 可能返回 21(需要 DEF.CAB),22(不需要)
checkrange 17 read 0x60234 && fallback 23

; [25]-[26]DEF.CAB 可能返回 23
checkrange 19,21 read 0x60234 && fallback 25

; [27]BOOT
checkrange 7,12,14,16,18,20,22,23 read 0x60234 && fallback 27
fallback Force



; 菜单 [1] 进入 MS-DOS,失败则返回流程控制菜单(然后进入下一个启动项)
title

fallback 0

; 如果用户选择的不是 MS-DOS 启动,则(通过菜单0后)跳转到 菜单2,处理 KERNEL.ZIP
checkrange 8 read 0x60068 || write 0x60234 1
checkrange 8 read 0x60068 || kernel



; 如果是 MS-DOS 启动,则将 (hd7, 0) 映射为软盘(fd0)
map --mem (hd7,0)+1 (fd0)

; 卸载 虚拟软盘 (fd1,fd2,fd3),虚拟设备 0x80 到 0xff。
map --unmap=1,2,3,0x80:0xff
map --rehook

; 设置 root 目录为 (fd0),并设置引导文件
rootnoverify (fd0) && chainloader /io.sys

; 开始启动
; boot



; 菜单 [2] 处理 KERNEL.ZIP,将 KERNEL.ZIP 装入内存 (rd),以便写入到 _KERNEL.ZIP 中
title


; 提示信息 Loading /0PE/KERNEL.ZIP...
pause --wait=0 Loading /0PE/KERNEL.ZIP...

fallback 3



; 找初始目录

; 复位 ErrorFlag
write 0x60000 1

; 恢复初始目录,并设置 root 为根目录
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()

; 装载 KERNEL.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
map --mem=0x8000 /0PE/KERNEL.ZIP (rd) || write 0x60000 0

; 成功则跳转到 菜单3,继续处理 KERNEL.ZIP,失败则继续查找 KERNEL.ZIP
read 0x60000 && kernel



; 找所有磁盘

; 复位 ErrorFlag
write 0x60000 1

; 搜索所有磁盘的 KERNEL.ZIP 然后装载到内存 (rd)
find --set-root /0PE/KERNEL.ZIP || write 0x60000 0

; 成功则装载 KERNEL.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
read 0x60000 && map --mem=0x8000 /0PE/KERNEL.ZIP (rd)

; 成功则跳转到 菜单3,继续处理 KERNEL.ZIP,失败则继续查找 KERNEL.ZIP
read 0x60000 && kernel



; 找 PXE

; 复位 ErrorFlag
write 0x60000 1

; 如果是 PXE 启动,则设置 root 为 PXE 服务器
read 0x60064 && rootnoverify (pd)

; 装载 KERNEL.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
map --mem=0x8000 /0PE/KERNEL.ZIP (rd) || write 0x60000 0

; 成功则跳转到 菜单3,继续处理 KERNEL.ZIP
read 0x60000 && kernel

; 失败则进入 GRUB 命令行模式
pause Error: File /0PE/KERNEL.ZIP not found!!! && commandline



; 菜单 [3] 将 KERNEL.ZIP 写入 _KERNEL.ZIP,以便 DOS 处理
title


; 获取 (rd) 的大小并写入 _KERNEL.ZIP 的文件头中(_KERNEL.ZIP 原本为 3M 全0文件)
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_KERNEL.ZIP bs=1 count=4 skip=0x8290

; 将 (rd) 的内容写入 _KERNEL.ZIP 的剩余空间中
dd if=(rd)+1 of=(hd7,0)/BUF/_KERNEL.ZIP bs=1 seek=4

; 提示 KERNEL.ZIP 准备完毕
pause --wait=0 KERNEL.ZIP is ready.

; (通过菜单0后)跳转到 菜单4,继续处理 OEM_SRS.ZIP
fallback 0
write 0x60234 3 && kernel



; 菜单 [4] 处理 OEM_SRS.ZIP,将 OEM_SRS.ZIP 装入内存 (rd),以便写入到 _SRS.ZIP 中
title


; 提示信息 Loading /OEM_SRS.ZIP...
pause --wait=0 Loading /OEM_SRS.ZIP...


; 如果选择了与 F6.ZIP 相关的启动项,则载入 1M 大小的 _srs.zip 到 (fd2) 中
checkrange 3,4,7 read 0x60068 && map --mem (hd7,0)/F6.GZ (fd2)

; 如果未选择与 F6.ZIP 相关的启动项,则载入 3M 大小的 _srs.zip 到 (fd2) 中
checkrange 3,4,7 read 0x60068 || map --mem (hd7,0)/A.GZ (fd2)
map --hook

fallback 5


; 找初始目录

; 复位 ErrorFlag
write 0x60000 1

; 恢复初始目录,并设置 root 为根目录
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()

; 装载 OEM_SRS.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
map --mem=0x8000 /OEM_SRS.ZIP (rd) || write 0x60000 0

; 成功则跳转到 菜单5,继续处理 KERNEL.ZIP,失败则继续查找 OEM_SRS.ZIP
read 0x60000 && kernel



; 找本地磁盘

; 复位 ErrorFlag
write 0x60000 1

; 搜索所有磁盘的 KERNEL.ZIP 然后装载到内存 (rd),忽略软盘和光盘
find --set-root --ignore-floppies --ignore-cd /OEM_SRS.ZIP || write 0x60000 0

; 成功则装载 OEM_SRS.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
read 0x60000 && map --mem=0x8000 /OEM_SRS.ZIP (rd)

; 成功则跳转到 菜单5,继续处理 OEM_SRS.ZIP,失败则继续查找 OEM_SRS.ZIP
read 0x60000 && kernel


; 找PXE

; 复位 ErrorFlag
write 0x60000 1

; 如果是 PXE 启动,则设置 root 为 PXE 服务器
read 0x60064 && rootnoverify (pd)

; 装载 OEM_SRS.ZIP 到内存 (rd),(rd) 起始于 16M(0x8000 * 512) 处
map --mem=0x8000 /OEM_SRS.ZIP (rd) || write 0x60000 0

; 成功则跳转到 菜单3,继续处理 OEM_SRS.ZIP
read 0x60000 && kernel

; 失败则提示 OEM_SRS.ZIP not found.
pause --wait=0 OEM_SRS.ZIP not found.

; 如果选择了与 SRS1.ZIP 相关的菜单项目,则(通过菜单0)跳转到 菜单6 处理 SRS1.ZIP
checkrange 1,5 read 0x60068 && write 0x60234 4

; 如果选择了与 SRS2.ZIP 相关的菜单项目,则(通过菜单0)跳转到 菜单8 处理 SRS2.ZIP
checkrange 2,6 read 0x60068 && write 0x60234 5

; 如果选择了与 F6.ZIP 相关的菜单项目,则(通过菜单0)跳转到 菜单10 处理 F6.ZIP
checkrange 3,4,7 read 0x60068 && write 0x60234 6

; 开始跳转
fallback 0 && kernel



; 菜单 [5] 将 OEM_SRS.ZIP 写入 _SRS.ZIP,以便 DOS 处理
title


; 传递环境变量到 DOS:set OEMF6=TRUE
write --offset=450 (hd7,0)/BAT/_ENV.BAT set OEMF6=TRUE\r\n

; 获取 (rd) 的大小并写入 _SRS.ZIP 的文件头中(_SRS.ZIP 原本为 1.4M 全0文件,或 3M 全0文件)
cat --length=0 (rd)+1 && dd if=(md) of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x8290

; 将 (rd) 的内容写入 _SRS.ZIP 的剩余空间中
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4

; 提示 OEM_SRS.ZIP 准备完毕
pause --wait=0 OEM_SRS.ZIP is ready.

; 如果选择的是“用户自定义菜单”,则(通过菜单0)跳转到 菜单27 直接启动
; 否则跳转到 菜单12 根据所选择的不同系统,继续处理 EXT1.GZ
write 0x60234 8
checkrange 4 read 0x60068 && write 0x60234 7

; 开始跳转
fallback 0 && kernel



; 菜单 [6] 处理 SRS1.ZIP,将 SRS1.ZIP 装入内存 (rd),以便写入到 _SRS.ZIP 中
title


; 提示信息 Loading /0PE/SRS/SRS1.ZIP...
pause --wait=0 Loading /0PE/SRS/SRS1.ZIP...

fallback 7


; 找初始目录
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/SRS/SRS1.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/SRS/SRS1.ZIP || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/SRS/SRS1.ZIP (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/SRS/SRS1.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 失败则(通过菜单0)跳转到菜单12,根据所选择的不同系统,继续处理 EXT1.GZ
pause --wait=0 SRS1.ZIP not found.
write 0x60234 8
fallback 0 && kernel



; 菜单 [7] 将 SRS1.ZIP 写入 _SRS.ZIP,以便 DOS 处理
title
write --offset=400 (hd7,0)/BAT/_ENV.BAT set scsiImg=TRUE\r\n

; (_SRS.ZIP 原本为 3M 全0文件)
cat --length=0 (rd)+1 && dd if=(md) of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4
pause --wait=0 SRS1.ZIP is ready.

; (通过菜单0)跳转到 菜单12 根据所选择的不同系统,继续处理 EXT1.GZ
write 0x60234 8
fallback 0 && kernel



; 菜单 [8] 处理 SRS2.ZIP,将 SRS2.ZIP 装入内存 (rd),以便写入到 _SRS.ZIP 中
title
pause --wait=0 Loading /0PE/SRS/SRS2.ZIP...
fallback 9

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/SRS/SRS2.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/SRS/SRS2.ZIP || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/SRS/SRS2.ZIP (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/SRS/SRS2.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 失败则(通过菜单0)跳转到菜单12,根据所选择的不同系统,继续处理 EXT1.GZ
pause --wait=0 SRS2.ZIP not found.
write 0x60234 8
fallback 0 && kernel



; 菜单 [9] 将 SRS2.ZIP 写入 _SRS.ZIP,以便 DOS 处理
title
write --offset=400 (hd7,0)/BAT/_ENV.BAT set scsiImg=TRUE\r\n

; (_SRS.ZIP 原本为 3M 全0文件)
cat --length=0 (rd)+1 && dd if=(md) of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4

; (通过菜单0)跳转到 菜单12 根据所选择的不同系统,继续处理 EXT1.GZ
pause --wait=0 SRS2.ZIP is ready.
write 0x60234 8
fallback 0 && kernel



; 菜单 [10] 处理 F6.ZIP,将 F6.ZIP 装入内存 (rd),以便写入到 _SRS.ZIP 中
title
pause --wait=0 Loading /0PE/SRS/F6.ZIP...
fallback 11

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/SRS/F6.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/SRS/F6.ZIP || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/SRS/F6.ZIP (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/SRS/F6.ZIP (rd) || write 0x60000 0
read 0x60000 && kernel

; 如果选择的是“用户自定义菜单”,则(通过菜单0)跳转到 菜单27 直接启动
; 否则跳转到 菜单12 根据所选择的不同系统,继续处理 EXT1.GZ
pause --wait=0 F6.ZIP not found.
write 0x60234 8
checkrange 4 read 0x60068 && write 0x60234 7
fallback 0 && kernel



; 菜单 [11] 将 F6.ZIP 写入 _SRS.ZIP,以便 DOS 处理
title
write --offset=450 (hd7,0)/BAT/_ENV.BAT set OEMF6=TRUE\r\n

; (_SRS.ZIP 原本为 1.4M 全0文件)
cat --length=0 (rd)+1 && dd if=(md) of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4

; 如果选择的是“用户自定义菜单”,则(通过菜单0)跳转到 菜单27 直接启动
; 否则跳转到 菜单12 根据所选择的不同系统,继续处理 EXT1.GZ
pause --wait=0 F6.ZIP is ready.
write 0x60234 8
checkrange 4 read 0x60068 && write 0x60234 7
fallback 0 && kernel



; 菜单 [12] 根据所选择的不同系统(XP/03),处理不同的 EXT1.GZ
title
write 0x60234 9
read 0x60300 && write 0x60234 10
fallback 0 && kernel



; 菜单 [13] 处理 XP 的 EXT1.GZ,将 XP 的 EXT1.GZ 装入内存 (rd),以便快速释放到虚拟软盘 (fd3)
title
pause --wait=0 Loading /0PE/XP/EXT1.GZ...

; 不自动解压 gzip 文件,将 EXT1.GZ 整个装入内存 (rd)
write 0x82A4 1
fallback 14

; 找初始目录
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/XP/EXT1.GZ (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/XP/EXT1.GZ || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/XP/EXT1.GZ (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/XP/EXT1.GZ (rd) || write 0x60000 0
read 0x60000 && kernel

; 失败则将 B.GZ 虚拟为 (fd3),B.GZ 为 3M 空磁盘映像
pause --wait=0 EXT1.GZ not found.
write 0x82A4 0
map --mem (hd7,0)/B.GZ (fd3)
map --hook

; 如果是 PXE 启动,或 ISO 启动,则继续处理 EXT2.WIM,否则直接启动
write 0x60234 12
read 0x60064 && write 0x60234 11
read 0x602A0 && write 0x60234 11
fallback 0 && kernel



; 菜单 [14] 将 EXT1.GZ 释放到虚拟软盘 (fd3)
title
write --offset=300 (hd7,0)/BAT/_ENV.BAT set EXT1=TRUE\r\n
write 0x82A4 0
map --mem (rd)+1 (fd3) && map --hook
pause --wait=0 EXT1.GZ is ready.

; 如果是 PXE 启动,或 ISO 启动,则继续处理 EXT2.WIM,否则直接启动
write 0x60234 12
read 0x60064 && write 0x60234 11
read 0x602A0 && write 0x60234 11
fallback 0 && kernel



; 菜单 [15] 处理 2003 的 EXT1.GZ,将 2003 的 EXT1.GZ 装入内存 (rd),以便快速释放到虚拟软盘 (fd3)
title
pause --wait=0 Loading /0PE/2003/EXT1.GZ...
write 0x82A4 1
fallback 16

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/2003/EXT1.GZ (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/2003/EXT1.GZ || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/2003/EXT1.GZ (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/2003/EXT1.GZ (rd) || write 0x60000 0
read 0x60000 && kernel

; 失败则将 B.GZ 虚拟为 (fd3),B.GZ 为 3M 空磁盘映像
pause --wait=0 EXT1.GZ not found.
write 0x82A4 0
map --mem (hd7,0)/B.GZ (fd3)
map --hook

; 如果是 PXE 启动,或 ISO 启动,则继续处理 EXT2.WIM,否则直接启动
write 0x60234 14
read 0x60064 && write 0x60234 13
read 0x602A0 && write 0x60234 13
fallback 0 && kernel



; 菜单 [16] 将 EXT1.GZ 释放到虚拟软盘 (fd3)
title
write --offset=300 (hd7,0)/BAT/_ENV.BAT set EXT1=TRUE\r\n
write 0x82A4 0
map --mem (rd)+1 (fd3) && map --hook

; 如果是 PXE 启动,或 ISO 启动,则继续处理 EXT2.WIM,否则直接启动
pause --wait=0 EXT1.GZ is ready.
write 0x60234 14
read 0x60064 && write 0x60234 13
read 0x602A0 && write 0x60234 13
fallback 0 && kernel



; 菜单 [17] 处理 XP 的 EXT2.WIM,将 XP 的 EXT2.WIM 装入内存 (rd),以便写入到 _EXT2.WIM 中
title
pause --wait=0 Loading /0PE/XP/EXT2.WIM...
fallback 18

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/XP/EXT2.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/XP/EXT2.WIM || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/XP/EXT2.WIM (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/XP/EXT2.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 如果是 PXE 启动,或 ISO 启动,则继续处理 @0#NET_.WIM,否则直接启动
pause --wait=0 EXT2.WIM not found.
write 0x60234 16
read 0x60064 && write 0x60234 15
read 0x602A0 && write 0x60234 15
fallback 0 && kernel



; 菜单 [18] 将 XP 的 EXT2.WIM 写入 _EXT2.WIM,以便 DOS 处理
title
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_EXT2.WIM bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(hd7,0)/BUF/_EXT2.WIM bs=1 seek=4
pause --wait=0 EXT2.WIM is ready.
write 0x60234 16
read 0x60064 && write 0x60234 15
read 0x602A0 && write 0x60234 15
fallback 0 && kernel



; 菜单 [19] 处理 2003 的 EXT2.WIM,将 2003 的 EXT2.WIM 装入内存 (rd),以便写入到 _EXT2.WIM 中
title
pause --wait=0 Loading /0PE/2003/EXT2.WIM...
fallback 20

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/2003/EXT2.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/2003/EXT2.WIM || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/2003/EXT2.WIM (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/2003/EXT2.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 如果是 PXE 启动,或 ISO 启动,则继续处理 @0#NET_.WIM,否则直接启动
pause --wait=0 EXT2.WIM not found.
write 0x60234 18
read 0x60064 && write 0x60234 17
read 0x602A0 && write 0x60234 17
fallback 0 && kernel



; 菜单 [20] 将 2003 的 EXT2.WIM 写入 _EXT2.WIM,以便 DOS 处理
title
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_EXT2.WIM bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(hd7,0)/BUF/_EXT2.WIM bs=1 seek=4

; 如果是 PXE 启动,或 ISO 启动,则继续处理 @0#NET_.WIM,否则直接启动
pause --wait=0 EXT2.WIM is ready.
write 0x60234 18
read 0x60064 && write 0x60234 17
read 0x602A0 && write 0x60234 17
fallback 0 && kernel



; 菜单 [21] 处理 @0#NET_.WIM,将 @0#NET_.WIM 装入内存 (rd),以便写入到 _NET.WIM 中
title
pause --wait=0 Loading /0PE/AUTORUNS/@0#NET_.WIM...
fallback 22

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/AUTORUNS/@0#NET_.WIM || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 如果是 PXE 启动,则继续处理 DEF.CAB,否则直接启动
pause --wait=0 @0#NET_.WIM not found.
write 0x60234 20
read 0x60064 && write 0x60234 19
fallback 0 && kernel



; 菜单 [22] 将 @0#NET_.WIM 写入 _NET.WIM,以便 DOS 处理
title
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_NET.WIM bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(hd7,0)/BUF/_NET.WIM bs=1 seek=4

; 如果是 PXE 启动,则继续处理 DEF.CAB,否则直接启动
pause --wait=0 @0#NET_.WIM is ready.
write 0x60234 20
read 0x60064 && write 0x60234 19
fallback 0 && kernel



; 菜单 [23] 内容和 菜单21 一样,可共用
title
pause --wait=0 Loading /0PE/AUTORUNS/@0#NET_.WIM...
fallback 24

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/AUTORUNS/@0#NET_.WIM || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/AUTORUNS/@0#NET_.WIM (rd) || write 0x60000 0
read 0x60000 && kernel
pause --wait=0 @0#NET_.WIM not found.
write 0x60234 22
read 0x60064 && write 0x60234 21
fallback 0 && kernel



; 菜单 [24] 内容和 菜单22 一样,可共用
title
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_NET.WIM bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(hd7,0)/BUF/_NET.WIM bs=1 seek=4
pause --wait=0 @0#NET_.WIM is ready.
write 0x60234 22
read 0x60064 && write 0x60234 21
fallback 0 && kernel



; 菜单 [25] 处理 DEF.CAB,将 DEF.CAB 装入内存 (rd),以便写入到 _DEF.CAB 中
title
pause --wait=0 Loading /0PE/NET/*...
fallback 26

; 初始目录有
write 0x60000 1
dd if=(md) of=(md) bs=1 count=8 skip=0x60130 seek=0x829c && root ()
map --mem=0x8000 /0PE/NET/DEF.CAB (rd) || write 0x60000 0
read 0x60000 && kernel

; 找本地
write 0x60000 1
find --set-root /0PE/NET/DEF.CAB || write 0x60000 0
read 0x60000 && map --mem=0x8000 /0PE/NET/DEF.CAB (rd)
read 0x60000 && kernel

; 找PXE
write 0x60000 1
read 0x60064 && rootnoverify (pd)
map --mem=0x8000 /0PE/NET/DEF.CAB (rd) || write 0x60000 0
read 0x60000 && kernel

; 失败则直接启动
pause --wait=0 DEF.CAB not found.
write 0x60234 23
fallback 0 && kernel



; 菜单 [26] Loading /0PE/NET/*...
title
cat --length=0 (rd)+1 && dd if=(md) of=(hd7,0)/BUF/_DEF.CAB bs=1 count=4 skip=0x8290
dd if=(rd)+1 of=(hd7,0)/BUF/_DEF.CAB bs=1 seek=4
pause --wait=0 DEF.CAB is ready.

; 将 NETID.TXT 的内容写入 _NETID.TXT
write 0x60000 1
map --mem=0x8000 /0PE/NET/NETID.TXT (rd) || write 0x60000 0
read 0x60000 && cat --length=0 (rd)+1
read 0x60000 && dd if=(md) of=(hd7,0)/BUF/_NETID.TXT bs=1 count=4 skip=0x8290
read 0x60000 && dd if=(rd)+1 of=(hd7,0)/BUF/_NETID.TXT bs=1 seek=4
read 0x60000 && pause --wait=0 NETID.TXT is ready.
read 0x60000 || pause --wait=0 NETID.TXT not found.

; 将 NETMAP.TXT 的内容写入 _NETMAP.TXT
write 0x60000 1
map --mem=0x8000 /0PE/NET/NETMAP.TXT (rd) || write 0x60000 0
read 0x60000 && cat --length=0 (rd)+1
read 0x60000 && dd if=(md) of=(hd7,0)/BUF/_NETMAP.TXT bs=1 count=4 skip=0x8290
read 0x60000 && dd if=(rd)+1 of=(hd7,0)/BUF/_NETMAP.TXT bs=1 seek=4
read 0x60000 && pause --wait=0 NETMAP.TXT is ready.
read 0x60000 || pause --wait=0 NETMAP.TXT not found.

; 开始启动
write 0x60234 23
fallback 0 && kernel



; 菜单 [27] 启动
title


; 转 (fd2) 为 (fd0)
; 此时 (fd0) 中存放的是 SRS 文件
map --mem (fd2)+1 (fd0)

; 如果选择了“用户自定义菜单”,则转 (fd3) 为 (fd1)
; 此时 (fd1) 中存放的是 EXT1.GZ 中的内容
checkrange 4 read 0x60068 || map --mem (fd3)+1 (fd1)

; 如果未选择“用户自定义菜单”,则设置 (fd1) 为 B.GZ 的内容
; 此时 (fd1) 为 3M 大小的空软盘映像
checkrange 4 read 0x60068 && map --mem (hd7,0)/B.GZ (fd1)

; 卸载 (fd2), (fd3), (0xA0)到(0xff)
map --unmap=2,3,0xA0:0xff
map --rehook


; 调整硬盘顺序,(hd7) 优先
errorcheck off
map (hd7) (hd0)
map (hd2) (hd3)
map (hd1) (hd2)
map (hd0) (hd1)
map --hook
errorcheck on


; 进入 DOS 环境,处理文件
rootnoverify (hd0,0) && chainloader /io.sys


; 开始启动
; boot


--------------------------------------------------------------------------------






[ 本帖最后由 stevenldj 于 2009-9-2 16:10 编辑 ]
回复

使用道具 举报

发表于 2009-8-28 01:36:24 | 显示全部楼层
grub 强,pseudo 也强,这样的菜单,简直就是程序。。
回复

使用道具 举报

发表于 2009-8-28 20:18:46 | 显示全部楼层

预期今后程式菜单技术会有更多应用

原帖由 135956 于 2009-8-28 01:36 发表
grub 强,pseudo 也强,这样的菜单,简直就是程序。。

这是最早出现于0PE的一种程式菜单,与传统菜单有很大区别。
在chenall和我的推动以及不点的支持下,程式菜单技术已经得到很大的发展,充分体现了grub4dos的强大。
目前程式菜单技术还主要集中体现在0PE和MicroPE的菜单中,预期今后会有更多应用。

原帖由 stevenldj 于 2009-8-27 23:38 发表
... 这个菜单文件是从 〇peZip扩展版二合一090620.ISO 的 grldr 中提取出来的,根据自己的理解加了一些注释(理解不一定正确),还有很多看 ...

楼主分析透切。支持一下。

; 不知道这里是判断什么
checkrange 0x21 read 0x8280 && write 0x60064 1

pxe?
原帖由 stevenldj 于 2009-8-28 00:42 发表
菜单好象还没完,“Loading 0PE/KERNEL.ZIP...” 的脚本在哪里?

在(hd7)里。
MENU.0PE只是0PE程式菜单的一小部分。
回复

使用道具 举报

发表于 2009-8-28 22:02:38 | 显示全部楼层
菜单看起来很复杂,看了头都晕了.
回复

使用道具 举报

发表于 2009-8-28 23:05:53 | 显示全部楼层
我头都看大了....pseudo是高手,楼主也是高手
回复

使用道具 举报

 楼主| 发表于 2009-8-29 15:10:16 | 显示全部楼层
谢谢 pseudo 大侠的指点,我已将注释修改完善。

还有一个问题请教一下 pseudo 大侠,下面的语句最后加一个 NotExist 是什么意思?是不是不自动检测其它配置文件?

pxe detect NotExist



在 Grub4Dos 的 Readme 中看到了如下说明,但没有讲 NoExist 参数,不知是什么意思:

--------------------------------------------------------------------------------
                    
现在“pxe”命令有了个新的子命令“detect”:


pxe detect [BLOCK_SIZE] [MENU_FILE]
           包大小选项   菜单文件选项

BLOCK_SIZE 选项指定出 pxe 的包大小。如果它没有被指定或者是被指定为 0 ,那么
grub4dos将通过一个侦测过程来获取数据传送包的一个恰当的的值。


MENU_FILE 选项指定出 PXE 服务器上的配置文件。如果它被省略,在 menu.lst 子目录
中的标准配置文件将获得控制。关于menu.lst 子目录中的配置文件的描述,请查阅上面
的“用 GRLDR 作为 PXE 引导文件”一节。


如果MENU_FILE 是以"/"开始的,那么PXE 服务器上的 MENU_FILE 将获得控制,否则
(如果MENU_FILE不是以"/"开始)将没有菜单被执行。


在你的系统可能用 512 字节的默认包大小不能运行时,通常你应该在访问(pd)设备之前
使用一条 "pxe blksize ..." 或 一条 "pxe detect ..."命令。


                          GRLDR 作为 PXE 启动文件

GRLDR 可以被用作远程或网络服务器的 PXE 启动文件。(pd) 设备被用于访问服务器上文件。
当 GRLDR 已经通过网络启动后,它将使用预设菜单作为配置文件。不过,你可以使用
一条"pxe detect"命令,它的表现是和pxelinux一样的方式。


    * 首先,它将使用设备类型(使用它的 ARP 类型码)和地址来搜索配置文件,全部用
      破折号分割的十六进制;例如,对一个以太网(ARP 类型是1)的88:99:AA:BB:CC:DD
      地址,它会用文件名01-88-99-AA-BB-CC-DD 来搜索。


    * 其次,它将使用它本地的大写字母的十六进制格式的IP 地址(即192.0.2.91 转换为
      C000025B。)来搜索配置文件。如果文件没有找到,它将去掉一个十六进制数字后再试一次。
      最后,它会尝试寻找一个名为 default (小写字母)的文件。举个例,如果引导文件名
      是/mybootdir/grldr ,以太网 MAC 地址是88:99:AA:BB:CC:DD 并且 它的 IP 地址是
      192.0.2.91 ,它将尝试下面的文件 (用那样的顺序):

       /mybootdir/menu.lst/01-88-99-AA-BB-CC-DD
       /mybootdir/menu.lst/C000025B
       /mybootdir/menu.lst/C000025
       /mybootdir/menu.lst/C00002
       /mybootdir/menu.lst/C0000
       /mybootdir/menu.lst/C000
       /mybootdir/menu.lst/C00
       /mybootdir/menu.lst/C0
       /mybootdir/menu.lst/C
       /mybootdir/menu.lst/default


--------------------------------------------------------------------------------





`

[ 本帖最后由 stevenldj 于 2009-8-29 15:21 编辑 ]
回复

使用道具 举报

发表于 2009-8-29 18:26:42 | 显示全部楼层
原帖由 stevenldj 于 2009-8-29 15:10 发表
谢谢 pseudo 大侠的指点,我已将注释修改完善。
还有一个问题请教一下 pseudo 大侠,下面的语句最后加一个 NotExist 是什么意思?是不是不自动检测其它配置文件?
pxe detect NotExist
在 Grub4Dos 的 Readme 中看到了如下说明,但没有讲 NoExist 参数,不知是什么意思:
...

pxe detect NotExist是我发明的写法,起加速启动的作用。
推荐大家参考使用。

执行pxe detect NotExist时,已经下载了grldr并正在执行其内置菜单,由于0PE的pxe启动菜单与本地启动菜单是合一的,没必要再指定一个真实存在的[MENU_FILE]作为菜单文件。
顾名思义,NotExist表示不存在,其实一般也不会存在以此为名的文件。写上这个,可以避免以下搜索过程:
       /mybootdir/menu.lst/01-88-99-AA-BB-CC-DD
       /mybootdir/menu.lst/C000025B
       /mybootdir/menu.lst/C000025
       /mybootdir/menu.lst/C00002
       /mybootdir/menu.lst/C0000
       /mybootdir/menu.lst/C000
       /mybootdir/menu.lst/C00
       /mybootdir/menu.lst/C0
       /mybootdir/menu.lst/C
       /mybootdir/menu.lst/default
回复

使用道具 举报

发表于 2009-8-29 18:49:16 | 显示全部楼层
原帖由 zhxy9804 于 2009-8-28 20:49 发表
菜单很吓人,请问内置了的菜单,能不被人看到吗?


  • 菜单内置的目的,是减少文件数,使得目录结构清爽。
0PE基本上按照这样的原则来设计结构,以求清爽:一个文件如果是外置的,一般意味着它是一个可删除的组件,否则应该考虑与其它东西打包而不独立存在。
0PE启动相关文件只有一个grldr,pxe启动也是如此。

  • 菜单内置的另一目的,是避免多处存在外置菜单文件menu.lst时可能引起的混淆。

  • 内置菜单用UltraEdit就能看到,在文件尾部。
没有考虑如何不被人看到的问题。目前0PE菜单某种意义上也算是“隐藏”的,因为相对不好懂、不好改,呵呵
回复

使用道具 举报

 楼主| 发表于 2009-8-29 19:28:04 | 显示全部楼层
呵呵,原来不是什么参数,是 pseudo 大侠发明的写法。我已经注释到 1 楼的帖子里面了。
回复

使用道具 举报

发表于 2009-9-1 23:34:01 | 显示全部楼层
已经收藏,准备睡了,找时间认真学习
回复

使用道具 举报

发表于 2009-9-2 01:09:53 | 显示全部楼层
原帖由 pseudo 于 2009-8-29 18:49 发表


菜单内置的目的,是减少文件数,使得目录结构清爽。0PE基本上按照这样的原则来设计结构,以求清爽:一个文件如果是外置的,一般意味着它是一个可删除的组件,否则应该考虑与其它东西打包而不独立存在。
...


我的吗哟,本人可是花了两个星期去研究这个菜单和0PE加载的方法,笨办法与手动结合,结果只读懂三分之一;回头再看看chenall大大的MicroPE完全苕了,不相信请楼主去试试?
我感觉,得让chenall和pseudo 两位大大认真给我们上上课,仔细讲解一下,最好还出个教程。
回复

使用道具 举报

发表于 2009-9-2 09:46:20 | 显示全部楼层
呵呵 关键是他们吧菜单程序化了 全部看完了在回头看可能会好一些
回复

使用道具 举报

发表于 2009-9-2 16:50:04 | 显示全部楼层
C版也说是变态的写法,呵呵!真把G4DDOS发扬光大了。
回复

使用道具 举报

 楼主| 发表于 2009-9-2 16:51:32 | 显示全部楼层
`


继续看 0PE 的批处理文件



    整个 0PE 的菜单 2 楼已经补充完整了,继续看看 0PE 的批处理。

    批处理语句基本能看懂,就是流程太复杂了,转来转去的,看不太懂,只能理解个大概,错误的地方请 Pseudo 大侠指正。

    这里接着 2 楼的菜单继续启动,现在已经进入 DOS 了,由 autoexec.bat 调用 autoexe0.bat 来处理 PE 文件,内容如下:



autoexe0.bat:

--------------------------------------------------------------------------------
@echo off

:: 设置环境变量
CALL BAT\_ENV.BAT
del BAT\_ENV.BAT

:: 是否进入 DOS
if "%SYS.VER%"=="DOS" goto :dos

:: 不进入 DOS,则设置 PATH 变量
path c:\;c:\bin;c:\bat

:: 执行 0PE 补丁程序(如果有的话)
if exist bin\0pepatch.bat call 0pepatch.bat

:: 删除 config.sys(不再需要)
del config.sys

:: 这些已经在软盘里面了,可以删除了
>nul del A.GZ
>nul del F6.GZ
>nul if not "%MENU.USR%"=="1" del B.GZ

:: 创建临时目录
md c:\TEMP
set temp=c:\TEMP

:: 如果不进入 DOS,则转道 start 启动
if not "%SYS.VER%"=="DOS" goto :start

:: 启动 DOS
:dos
:: 删除无用目录
>nul deltree /y bat
>nul deltree /y buf
>nul deltree /y bin
>nul deltree /y wxpe
>nul deltree /y temp
:: 删除无用文件
del config.sys
>nul del A.GZ
>nul del B.GZ
>nul del F6.GZ
del deltree.com
del autoexec.bat
:: 启动完毕
cls
goto :end



:Start

:: 清空 autoexec.bat
>autoexec.bat echo.

:: 从 _KERNEL.ZIP 中获取 KERNEL.ZIP
cd C:\BUF
call grtrim.bat KERNEL.ZIP

:: 解压 KERNEL.ZIP 到根目录,并删除 KERNEL.ZIP
cd c:\
if exist C:\BUF\KERNEL.ZIP pkunzip -od C:\BUF\KERNEL.ZIP>NUL
if exist C:\BUF\KERNEL.ZIP del C:\BUF\KERNEL.ZIP

:: 复制 Kernel 目录中的所有文件到 C:\ 根目录,并删除 Kernel 目录
:: 为什么不直接压缩到 KERNEL.ZIP 的根目录中,直接解压,还要这样转移一次?
>nul xcp /m c:\KERNEL\*.* c:\ /H /S /Y /R /Q
>nul deltree /y c:\KERNEL

:: 继续启动 autoexe1.bat
autoexe1.bat
:end

--------------------------------------------------------------------------------





autoexe1.bat:

--------------------------------------------------------------------------------

@echo off

:: 如果不是启动用户自定义菜单,则启动 PE
if not "%MENU.USR%"=="1" goto PE

:: 复制 MENUUSR.bat 到 A 盘
>nul xcp /m /y c:\bat\MENUUSR.bat a:\MENUUSR.bat
:: 执行 MENUUSR.bat
a:\MENUUSR.bat
goto :end

:: 启动 PE
:PE

cd C:\BUF
:: 如果不是从 PXE 启动,则删除 _NETMAP.TXT _NETID.TXT _DEF.CAB
if "%BTM%"=="PXE" goto :L1
for %%i in (_NETMAP.TXT _NETID.TXT _DEF.CAB) do if exist %%i del %%i
:: 如果不是从 ISO 启动,则删除 _EXT2.WIM _NET.WIM
if "%BTM%"=="ISO" goto :L1
for %%i in (_EXT2.WIM _NET.WIM) do if exist %%i del %%i

:L1
:: 获取 NETMAP.TXT NETID.TXT DEF.CAB NET.WIM EXT2.WIM 文件(处理由 Grub4Dos 转移进来的文件)
for %%i in (NETMAP.TXT NETID.TXT DEF.CAB NET.WIM EXT2.WIM) do call grtrim.bat %%i


:: 删除 auoexe0.bat,不再需要
cd C:\
del autoexe0.bat

:: 继续启动 auto_exe.bat
call auto_exe.bat
:end

--------------------------------------------------------------------------------





auto_exe.bat :

--------------------------------------------------------------------------------

@echo off

:: 全局变量%scsiImg%、%OEMF6%、%EXT1%、%config%、%MP%, etc.

:: 如果 PEISO 不为空,则将 set PEISO=%PEISO%的值 写入 C:\WXPE\setPEISO.cmd
:: 注:PEISO = 0PE.ISO 的相对存放位置,由 GRUB4DOS 传入DOS
if not "%PEISO%"=="" echo set PEISO=%PEISO%>C:\WXPE\setPEISO.Cmd

:: 如果 PEISO 不为空,则 ??
if exist C:\WXPE\setPEISO.cmd str C:\WXPE\setPEISO.cmd 0 0 /R /ASC:/ /ASC:\ /A>nul

:: 如果 "%BTM%"=="ISO" 则创建 C:\WXPE\BTMISO 空文件
if "%BTM%"=="ISO" echo.>C:\WXPE\BTMISO

:: 将 set SYS.VER=%SYS.VER%的值 写入到 C:\WXPE\setOSVER.cmd
echo set SYS.VER=%SYS.VER%>C:\WXPE\setOSVER.cmd

:: 如果不是 PXE 启动,也不是 ISO 启动,则跳转到 NOSERVER
set Tftp_Server=
if not "%BTM%"=="PXE" if not "%BTM%"=="ISO" goto :NOSERVER

:: 否则复制文件到相应位置
>nul if exist c:\buf\EXT2.WIM xcp /m c:\buf\EXT2.WIM c:\0PE\%SYS.VER%\EXT2.WIM
>nul if exist c:\buf\NET.WIM xcp /m c:\buf\NET.WIM c:\0PE\AutoRuns\@0#NET.WIM

:: 如果是 ISO 启动,则跳转到 NOSERVER
if "%BTM%"=="ISO" goto :NOSERVER

:: ??
>nul undipd 0x60

:: 设置 FTP 服务器地址
call setip.bat

:: 如果 Tftp_Server 为空,则跳转到 NOSERVER
if "%Tftp_Server%"=="" goto :NOSERVER

:: 将 set Tftp_Server=%Tftp_Server% 写入 C:\WXPE\setTFTPD.cmd
>C:\WXPE\setTFTPD.cmd echo set Tftp_Server=%Tftp_Server%



:NOSERVER

Cls

:: 设置变量 status
if "%EXT1%"=="TRUE" set status=EXT1.GZ: Ready
if not "%EXT1%"=="TRUE" set status=EXT1.GZ: None
if "%scsiImg%"=="TRUE" set status=%status%,  SRS*.ZIP: Ready
if "%OEMF6%"=="TRUE" set status=%status%,  F6.ZIP: Ready
if not "%scsiImg%"=="TRUE" if not "%OEMF6%"=="TRUE" set status=%status%,  SRS: None



:: 显示 0PE 菜单选择窗口 (WBAT 窗口)
if "%scsiImg%"=="TRUE" call w.bat box  @c:\bat\wbat.txt:cc #5,3
if "%OEMF6%"=="TRUE" call w.bat box  @c:\bat\wbat.txt:cc #5,3
if not "%scsiImg%"=="TRUE" if not "%OEMF6%"=="TRUE" call w.bat box  @c:\bat\wbat.txt:cc #4,3
set status=

:: 处理选择
:: 从 XP 系统获取 SRS 驱动
IF "%WBAT%"=="1" set config=N_SCSI
:: 从 ZIP 中获取 SRS 驱动
IF "%WBAT%"=="2" set config=SCSI
:: 启动到 DOS
IF "%WBAT%"=="3" set config=DOS
:: 清除 CMOS 密码
IF "%WBAT%"=="4" set config=DELCMOS

:: 是否多核
set MP=ENABLE
IF "%wcb1%"=="1" set MP=DISABLE

:: 保存日志
set REPORT=FALSE
IF "%wcb2%"=="1" set REPORT=TRUE

:: 正常启动 PE
set MANUALSTART=FALSE
IF "%wcb3%"=="1" set MANUALSTART=TRUE


SET WBAT=
SET wcb1=
set wcb2=
set wcb3=
goto :%config%



:DOS
:: 进入 DOS
goto end




:DELCMOS
:: 清除 CMOS 密码
DELCMOS.com
echo CMOS password has been cleared, reboot system please!
goto end



:N_SCSI
:SCSI

:: 将 SRS 装载到虚拟软盘
call auto.bat

:: 消除莫名其妙的报txtsetup.sif某行错
>nul XCP.COM c:\wxpe\txtsetup.sif c:\wxpe\txtsetup.sjf /H
del c:\wxpe\txtsetup.sif
ren c:\wxpe\txtsetup.sjf txtsetup.sif


if "%OEMF6%"=="TRUE" IF not "%config%"=="N_SCSI" goto KEEPFD0
:: 卸载 (fd0), (fd1), (fd2), 光驱
>>0pemenu.lst echo map --unmap=0,1,2,0x81:0xff
goto REHOOK

:KEEPFD0
:: 卸载 (fd1), (fd2), 光驱
>>0pemenu.lst echo map --unmap=1,2,0x81:0xff

:REHOOK
:: 使 map 结果生效
>>0pemenu.lst echo map --rehook
>>0pemenu.lst echo map --hook=0x80
:: 设置 (hd0,0)/setupldr.bin 为启动文件
>>0pemenu.lst echo chainloader (hd0,0)/setupldr.bin


:: 判断是否删除 c:\HDdrv
IF "%MANUALSTART%"=="TRUE" goto L1
IF "%DEBUGON%"=="1" goto L1

:: 删除 c:\HDdrv 目录
>nul deltree /Y c:\HDdrv

:L1
:: 清理文件目录
>nul UNDIPD.COM -u
>nul deltree /Y c:\bat
>nul deltree /Y c:\bin
>nul deltree /Y c:\BUF
del c:\deltree.com

:: 判断是否显示 Debug 信息
IF "%MANUALSTART%"=="TRUE" goto PRMPT
IF "%DEBUGON%"=="1" goto PRMPT

:: 直接启动 PE
startPE.bat



:PRMPT

:: 显示变量值
echo DEBUGON=%DEBUGON%,config=%config%,PEISO=%PEISO%,EXT1=%EXT1%,scsiImg=%scsiImg%,OEMF6=%OEMF6%,F6DEF=%F6DEF%,Tftp_Server=%Tftp_Server%
echo xpres=%xpres%,xpdrv=%xpdrv%,xpdir=%xpdir%,MP=%MP%,SYS.VER=%SYS.VER%

:: 显示 c:\HDDRV 所有文件列表
if exist c:\HDDRV\nul dir /a-d c:\HDDRV


:: 启动 PE
IF "%DEBUGON%"=="1" pause
IF "%DEBUGON%"=="1" startPE.bat
echo Note: You can then start PE by typing "startPE".
:end

--------------------------------------------------------------------------------





startPE.bat:

--------------------------------------------------------------------------------

@echo off

c:
cd \
:: 0pemenu.lst 是动态创建的
if not exist 0pemenu.lst goto quit

:: 清理文件
del io.sys
del autoexe1.bat
del auto_exe.bat
del command.com
if exist a:\_SRS.ZIP del a:\_SRS.ZIP
>nul copy /y grub.exe a:\grub.exe
del grub.exe

:: 启动 PE (借助 GRUB4DOS)
a:\grub --config-file=c:\0pemenu.lst


:: 出错后转到这里
:quit
echo.
echo Sorry, PE not ready to start.

--------------------------------------------------------------------------------



    上面的还不是核心,只是流程,核心文件在 KERNEL\BAT 里面,文件列表如下:

auto.bat
check.bat
chknet.bat
CHKPCI.BIN
cpy.bat
drivers.txt
drvSif.bat
F6AUTO.bat
MENUUSR.bat
MP.SIF
REPORT.bat
SCSI.BAT
SCSI_DRV.EXE
setip.bat
system32.txt
tftpget.bat
userdl.bat
wbat.txt
xcpbat.bat



    希望 Pseudo 大侠有时间的话给大家解读一下这些脚本,这些脚本里面有太多判断和跳转,又牵扯到很多环境变量,如果不整体把握是很难读懂的,我就是被那些环境变量和跳转给搞晕了,看不懂了。





`
回复

使用道具 举报

发表于 2009-9-2 19:26:36 | 显示全部楼层
支持一下,就当是复习编程了
回复

使用道具 举报

发表于 2009-9-2 21:30:13 | 显示全部楼层
我这样滴水平只能先做个记号,慢慢看了
回复

使用道具 举报

发表于 2009-9-4 07:11:23 | 显示全部楼层
确实是好东西,收藏学习用。谢谢辛苦了。
回复

使用道具 举报

发表于 2009-10-13 16:48:10 | 显示全部楼层
楼主真是好样的,这样看起来就方便理解了。
楼主有空再根据OPE新版修正一下!
回复

使用道具 举报

发表于 2009-10-15 09:15:08 | 显示全部楼层
好贴先收着,以后慢慢学习
回复

使用道具 举报

发表于 2009-12-1 12:51:32 | 显示全部楼层
太感谢了。一直想读懂ope的菜单。看到一篇提到这个解读特意搜索,我搜了几次才找出来。找着了,太好了
回复

使用道具 举报

发表于 2010-1-8 23:14:49 | 显示全部楼层
楼主真是超强啊!
把这么复杂的东西写出来给我们当教程,谢过啦!!!!


P大的0PE,看了很多天都看不懂,还是看了楼主的解释,才明白了些许。
受益很大,龙其对G4D的很多命令有了新的理解。

[ 本帖最后由 jmwjy 于 2010-1-15 03:31 编辑 ]
回复

使用道具 举报

发表于 2010-1-9 01:05:14 | 显示全部楼层
这个非常有用 标记下
回复

使用道具 举报

发表于 2010-1-9 07:43:38 | 显示全部楼层
太厉害了 佩服P大!!!
回复

使用道具 举报

发表于 2010-1-9 09:26:25 | 显示全部楼层
从前真的不知道GRUB这么牛,如果菜单写的好的话可以发挥如此强大的功能..
回复

使用道具 举报

发表于 2010-1-10 12:17:16 | 显示全部楼层
2010年,什么最重要,技术。什么人最重要,掌握技术的人!。
回复

使用道具 举报

发表于 2010-1-11 19:51:36 | 显示全部楼层
严重支持!.最好请 pseudo大师 写一个具体流程..
回复

使用道具 举报

发表于 2010-1-11 21:02:06 | 显示全部楼层
Chenall 与 Pseudo的菜单都是高级用法,够学的
回复

使用道具 举报

发表于 2010-1-13 05:58:25 | 显示全部楼层
只想知道启动原理和过程,大概的就可以了,细节就不需要了。
回复

使用道具 举报

发表于 2010-3-16 18:20:07 | 显示全部楼层
。。。。。有没有简单的 先研究研究啊。。 功能是强大。。这也太复杂了啊。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-17 01:08

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表