請選擇 進入手機版 | 繼續訪問電腦版

NoName Team 電腦資訊討論區

 找回密碼
 我要註冊
搜索
查看: 150|回復: 5

[討論] 如何 在GRUB4DOS 選單中排除 USEB 所在的 HD0或者其他

[複製鏈接]
發表於 2021-2-15 00:29:28 | 顯示全部樓層 |閱讀模式
本來 GRUB4DOS 有個選項是 從硬碟開機

title 【01】  ===嘗試引導本地硬碟作業系統===
find --set-root --ignore-floppies --ignore-cd /ntldr || find --set-root --ignore-floppies --ignore-cd /bootmgr
map () (hd0)
map (hd0) ()
map --rehook
find --set-root --ignore-floppies --ignore-cd /ntldr || find --set-root --ignore-floppies --ignore-cd /bootmgr
chainloader /ntldr || chainloader /bootmgr


最近遇到某台電腦 卻失敗 變成從我的隨身碟開機   因為我的隨身碟 根目錄有 bootmgr
真正的硬碟 是在HD1

為了想解決這個問題 我上了 無憂  找到了 類似的.............對方希望的是 找到 除了U盤以外 第一個WINPE.WIM 所在位置
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=414816

利用他的方法  我可以排除掉 真正的硬碟在HD1問題

但是卻不能解決我的問題  我希望是否可以利用 搜尋U盤上的某個檔案 先得出 我的U盤到底是不是HD0  如果是  就啟動HD1 或者HD1以後搜尋的道開機的硬碟

如果我的 U盤  不是HD0  那就啟動HD0


有人可以給點想法嗎??






發表於 2021-2-15 18:20:06 | 顯示全部樓層
本帖最後由 阿達金田一 於 2021-2-15 20:51 編輯

如果要用 find /bootmgr 又要完美一點...
就比較麻煩...不過你找的那個文章...其實裡面有解答了
只是沒有寫的比較完整


先假設 usb 中有一個檔案 flag.usb 做為判斷 usb 的旗標檔

[Bash shell] 純文本查看 復制代碼
find --ignore-floppies --ignore-cd /flag.usb | set usb=

set list=(md)0x60500+0x100
find --ignore-floppies --ignore-cd /bootmgr > %list%

cat --length=10 --skip=0 %list% | set p=
if exist p if "%p%"=="%usb%" set p=
if exist p root %p% && chainloader /bootmgr && boot

cat --length=10 --skip=10 %list% | set p=
if exist p if "%p%"=="%usb%" set p=
if exist p root %p% && chainloader /bootmgr && boot



第1行...沒啥好說...就是找出 usb 的位置
第3行...用來暫存 find /bootmgr 輸出 的 記憶體位址
第4行...把 find /bootmgr 輸出 到 記憶體位址

第6行 ... 記憶體位址 跳過0個字元 長度10 輸出到 set p=

第7行 ... 如果 變數p 存在時 , 則如果 %p% 等於 %usb% , 則 set p=
簡單說就是... 變數p 存在 且 "%p%" 等於 "%usb%" 時 , 刪除 變數p

第8行 ... 如果 變數p 存在時 , root + chainloader + boot
簡單說就是... 變數p 存在...才會跑 root + chainloader + boot

至於後面就是 6-8 的重覆...
第10行... 就是跳過10個字元, 也就是 find 輸出的第2個

我這裡是只用2次...
也就是會判斷 find /bootmgr 輸出的前2個
這裡建議是 find 一定要用  --ignore-floppies --ignore-cd
因為這樣 find 輸出 基本應該都是 (hdx,x) ... 字串長度才一致 , 不然可能會出問題
而2次其實就夠了...因為只是要找出第1個 不是 usb 的 bootmgr
正常應該 usb 也應該只有 1 個...
也就是就算 usb 排前面 , 前2個只有一個會是 usb 的 bootmgr
當然如果你 usb 中一堆 /bootmgr 那可能要多重覆幾次


如果把 win bootmgr 的 hdd 用 map 交換到 hd0 也可以
[Bash shell] 純文本查看 復制代碼
find --ignore-floppies --ignore-cd /flag.usb | set usb=

set list=(md)0x60500+0x100
find --ignore-floppies --ignore-cd /bootmgr > %list%

cat --length=10 --skip=0 %list% | set p=
if exist p if "%p%"=="%usb%" set p=
if exist p root %p% && map () (hd0) && map (hd0) () && map --hook

cat --length=10 --skip=10 %list% | set p=
if exist p if "%p%"=="%usb%" set p=
if exist p root %p% && map () (hd0) && map (hd0) () && map --hook

root (hd0)
chainloader /bootmgr



補充個用 批次檔 來處理的方式...就是會自動重覆判斷...直到沒資料
[Bash shell] 純文本查看 復制代碼
!BAT
find --ignore-floppies --ignore-cd /flag.usb | set usb=

set list=(md)0x60500+0x100
find --ignore-floppies --ignore-cd %1 > %%list%%

echo find %1
cat %%list%%

set /a sk=0
:find
cat --length=10 --skip=%%sk%% %%list%% | set p=
set /a sk=%%sk%%+10
if not exist p exit
if "%%p%%"=="%%usb%%" goto :find
echo %%p%% boot
root %%p%%
chainloader %1
boot


假設批次檔存成 /grub4dos/hddboot.bat
title hdd boot
/grub4dos/hddboot.bat /bootmgr
/grub4dos/hddboot.bat /ntldr

簡單說就是後面加上要 find 的檔案
發表於 2021-2-15 16:18:04 | 顯示全部樓層
本帖最後由 阿達金田一 於 2021-2-15 16:22 編輯

在 grub4dos 指令介面下可以用 help if 看指令說明
不過 grub4dos if 是比較簡易的
基本用法只有2種
if  [not] STRING1==STRING2 [COMMAND]
if [not] exist  VARIABLE|FILENAME [COMMAND]

/i 是不分大小寫
not == 就 不等於 <>
簡單說 g4d if 只有  == , 配合 not 變成 <> 效果
exist 是查看是否有 環境變數 或 檔案

grub4dos 本身指令也有 && 和 || 的用法
所以要達到 if then else 的效果
可以用
if  [not] STRING1==STRING2 [COMMAND1] || [COMMAND2]

舉例
set a=a
if %a%==a echo 1 || echo 2
會顯示 1
set a=A
if %a%==a echo 1 || echo 2
會顯示 2

本帖子中包含更多資源

您需要 登錄 才可以下載或查看,沒有帳號?我要註冊

x
發表於 2021-2-15 11:59:32 | 顯示全部樓層
本帖最後由 阿達金田一 於 2021-2-15 12:24 編輯

方法有很多...不過比較簡單的
應該是先判斷 usb 是不是 在 hd0 如果是
( 通常 Legacy USB 開機 ...只要 usb 是模擬 hdd 開機的 , usb 一定在 hd0 )
先把 usb map 交換到別的位置
一般懶一點就是直接
map (hd0) (hd1)
map (hd1) (hd0)
map --hook

find --set-root --ignore-floppies --ignore-cd /ntldr || find --set-root --ignore-floppies --ignore-cd /bootmgr
chainloader /ntldr || chainloader /bootmgr
或直接
chainloader (hd0)+1

更簡單的方法就是...
把 usb 上的 bootmgr 改個名字不就好了...
例如改成 peldr 或 bootmgr.usb
反正原本 pe 載入大概也是
chainloader /bootmgr
改名後改成
chainloader /peldr

chainloader /bootmgr.usb
不就好了...這樣就不會和 hdd 上的 bootmgr 重名

如果一定要判斷 usb 是不是 hd0
那你要先確保 usb 上只有一個用來判斷的 旗標檔...
不然如果硬碟中有也是沒意義
太久沒摸 grub4dos...指令大概是
find /xxxxx | set usb=
if "%usb:~0,4%"=="(hd0" map (hd1) (hd0) && map (hd0) (hd1) && map --hook
chainloader (hd0)+1

 樓主| 發表於 2021-2-15 13:53:10 | 顯示全部樓層
阿達金田一 發表於 2021-2-15 11:59
方法有很多...不過比較簡單的
應該是先判斷 usb 是不是 在 hd0 如果是
( 通常 Legacy USB 開機 ...只要 usb ...

老大  
在請教一下  如果判斷式 要用不等於 是不是可以寫成

if "%usb:~0,4%" <> "(hd0"

這樣語法 系統可以接受嗎

另外  IF 如果要寫成  IF 成立  THEN       ELSE     這樣 在 GRUB4DOS 下  可以怎麼寫呢??
發表於 2021-2-15 16:59:25 | 顯示全部樓層
本帖最後由 阿達金田一 於 2021-2-15 19:23 編輯

如果單純要我給建議
你的指令
find --set-root --ignore-floppies --ignore-cd /ntldr || find --set-root --ignore-floppies --ignore-cd /bootmgr
map () (hd0)
map (hd0) ()
map --rehook
find --set-root --ignore-floppies --ignore-cd /ntldr || find --set-root --ignore-floppies --ignore-cd /bootmgr
chainloader /ntldr || chainloader /bootmgr

第1個 find 的用意應該是要抓 hdd 中的 ntldr 或 bootmgr
抓到後 設為 root
然後下面的 map 指令 , 就是把 root 和 hd0 交換
而第2個 find 其實可以直接用 rootnoverify (hd0)
因為你都 map 到 (hd0) 了

所以照你原本的思路
最簡單就是 usb 中的 bootmgr 改檔名...
因為 bootmgr 就是用來判斷 hdd  中的 win bootmgr
所以 usb 就不應該有 bootmgr

正常 legacy usb boot 做 ... usb 本來就會在 hd0
如果 usb 中...不改 bootmgr 檔名
那 find 第一毎...一定是找到 usb 的 bootmgr
所以一般的 legacy usb boot ...
若不改 bootmgr 檔名...就是要先 map 交換
把 usb 從 hd0 改到別的位置 (通常是直接 hd0 hd1 交換)
這樣 find 在找的時候...
因為會從 hd0 開始找...所以 hdd map 到 hd0 並且有 bootmgr 就會先找到

其實我個人自己大多是用改檔名...不容易出錯...
因為...例如
你 usb boot 完
hd0 - usb
hd1 - hdd1
hd2 - hdd2
然後如果 win bootmgr 是在 hdd2 咧...
那交換 hd0 hd1...就沒意思... find 一樣會先找到 usb bootmgr
雖然...通常 hdd 開機都會用第1個 hdd... bootmgr 正常也會安裝到 第1個 hdd

所以改檔名是最簡單有不容易出錯
而一般 usb 用  map 交換 hd0 hd1
大多是用 chainloader (hd0)+1
這會順便幫你做 root (hd0) ... 這是用 hd0 mbr 做開機
簡單說就是 hd0 hd1 交換...
用 hd0 (之前的 hd1 - hdd1 ) 做開機...而不是找 bootmgr
也就是直接用 hdd1 開機
至於 hdd1 mbr 能不能開機 , 有沒有 bootmgr 那就不管

所以一般做法是
checkrange 0x80 read 0x8280 && map (hd1) (hd0) && map (hd0) (hd1) && map --hook && chainloader (hd0)+1

checkrange 0x80 read 0x8280
是用來判斷是不是 hdd 開機

如果是 hdd 開機
指令 read 0x8280 會回傳 0x80 ( cd 開機會回傳 0xef )

checkrange 0x80 是判斷 read 回傳值 是不是 0x8
如果是 0x80 則會回傳 true , 就會執行 && 後面的指令
不過這是比較簡易的方法...沒什麼太多判斷...前題就是 usb 在 hd0
只不過正常 legacy usb boot (用 hdd boot) ... usb 正常都會在 hd0
所以判斷是 hdd boot 就直接 map + chainloader

您需要登錄後才可以回帖 登錄 | 我要註冊

本版積分規則

小黑屋|手機版|NoName Team 電腦資訊討論區 |網站地圖

GMT+8, 2021-2-28 23:40 , Processed in 0.283121 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表