GRUB

GRUB

我有一個應用程序,我需要啟動到 Linux,執行自動化腳本,然後自動啟動到 Windows。我可以使用 Kexec 來執行 grub 嗎?

另一個用例是啟動 Linux 核心來更新處理器微程式碼,然後kexec啟動 GRUB 或 Syslinux 來啟動 Windows —— 因為微程式碼無法在完全重新啟動後繼續存在。

我聽過grub4dos連結(不可用),存檔版本),但是好像已經停產了,那有沒有辦法用GRUB2來做呢?

我基本上需要一個可載入的 GRUB 映像kexec。我嘗試加載在此找到的圖像解釋,但它們似乎不起作用。感謝您的任何提示。


註:已找到這個帖子從 2014 年開始,kexec 中還沒有實現這一點。

答案1

這對 Windows 來說似乎是可能的kexec,但它似乎充其量只是實驗性的(並且沒有經過充分的測試)。

GRUB

kexecgrub本身是不可能的core.img(因為它似乎沒有相容的二進位格式),另請參閱Launchpad 上的此錯誤報告。提到的錯誤仍然可以重現:

kexec -l /boot/grub2/i386-pc/core.img

根據kexec --help,目前支援以下類型:

elf-x86_64
multiboot-x86
multiboot2-x86
elf-x86
bzImage64
bzImage
beoboot-x86
nbi-x86

如果您想載入不同的載入器,則需要採用這些格式之一,否則必須新增相容性。我不確定 GRUB 使用什麼格式 - 一個簡單的file命令只會產生以下結果:

/boot/grub2/i386-pc/core.img: data

建立可開機的 GRUB 映像

目前看來有以下幾種可能:

引導程式

lnxboot.img將是一個Linux kernel x86 boot executeable bzImage.它似乎打算作為內核加載:

然後,您可以從 syslinux/isolinux/pxelinux/lilo 或任何其他支援 Linux 核心的引導程式載入 grub2.bin。

Kexec 確實載入了它,但執行時崩潰:

kexec -l /usr/lib/grub/i386-pc/lnxboot.img --initrd=/boot/grub2/i386-pc/core.img --debug

載入時似乎也出現問題(調試輸出的前幾行):

Try gzip decompression.
Try LZMA decompression.
lzma_decompress_file: read on /usr/lib/grub/i386-pc/lnxboot.img of 65536 bytes failed
[...]

Grub4Dos

快速瀏覽一下 Grub4Dos:

# file grub.exe
grub.exe: Linux kernel x86 boot executable bzImage, version \353kHdrS\003\002, RO-rootFS, Normal VGA

這應該意味著它是相容的。這對我來說不是一個選擇,因為它是遺留軟體。

grub4dos但是,我設法透過下載0.4.4來加載來源鍛造然後運行:

kexec -l grub.exe
kexec -e

未配置時,一段時間後它會退回 grub shell。如果您想使用gru4dos,您只需要調整cmdline即可滿足您的需求。這個線程仍應適用。

視窗

KexecWindows 似乎不是一句簡單的話,但它之前已經做過

這個方向的大部分工作似乎與Linux啟動專案.吉圖布

我找到了這些幻燈片還有這個github 倉庫。這似乎是文章中提到的使其發揮作用的項目。

這似乎是可能的,但需要做很多工作(並且沒有可用的“生產就緒”解決方案 - 至少我還沒有找到它)。不幸的是,似乎沒有很多關於 LinuxBoot 的文檔,所以你可能不得不詢問開發人員。可能已經有一種更直接的方法可以做到這一點。

答案2

kexec 進入 Windows 之所以如此困難和複雜,是因為 kexec 的內部設計機制存在缺陷,它假設所有作業系統引導程式都以類似的方式載入作業系統核心映像,但事實顯然並非如此。例如,某些作業系統核心映像必須從某些特殊的記憶體位址偏移量開始加載,某些作業系統可能需要與作業系統核心映像一起載入其他檔案(包含驅動程式資訊)等。系統如何載入其核心映像,或者將在未來版本中載入其核心映像,從長遠來看,當前 kexec-ing 到另一個作業系統/核心的方式不會很好地工作。

kexec-ing 進入另一個作業系統的更通用/相容的方式(正如我建議的)是載入實模式引導磁區引導程式碼,退出保護模式,然後直接跳到實模式引導程式碼入口點。這是最通用的方式,因為任何作業系統的實模式引導磁區引導程式碼始終可以從任何記憶體位址開始加載,這就是BIOS(不同的電腦製造商製造不同的BIOS)引導到作業系統的方式(除非作業系統不這樣做)不希望其他 BIOS 安裝或引導它,例如 Apple,他們可以對如何載入開機磁區引導程式碼施加專有限制)。這樣,我們總是可以引導到任何作業系統,無論其引導程式碼如何載入其作業系統核心映像,因為我們直接運行自己的引導磁區引導程式碼。此外,這種模式不會導致任何速度下降,因為引導磁區引導程式碼很小,因此載入速度很快,並且在實模式和保護模式下載入大型核心映像檔的差異不是很大。

然而,要實現這一目標非常具有挑戰性,因為:

  1. 對於所有現代作業系統,一旦從實模式進入保護模式,實模式記憶體就會被一些描述符表或頁表條目覆蓋。因此,沒有備份。然而,實模式啟動程式碼使用BIOS中斷來存取硬體IO,因此如果不恢復原始實模式記憶體映射,它們將無法從硬碟載入核心映像檔。這個問題很棘手但可以解決。我們可以安裝一些特殊的 Linux 引導程序,在進入保護模式之前拍攝記憶體快照,並且只需要在一台機器上完成一次。

  2. 並非所有處理器都很好地支援從保護模式返回實模式。出於生產成本和效率的原因,現代處理器被設計用於啟動到作業系統(從實模式進入保護模式),而不是從作業系統中取消啟動(從保護模式返回實模式)。因此,從保護模式返回實模式的行為沒有經過充分測試,因此非常不確定。由於每個型號的這種行為各不相同,因此無法控制,因此無法保證它可以在哪些品牌/型號的處理器上正常運作。

  3. 只有 Intel X86 處理器具有實模式和保護模式(因為它經歷了非常早期的遺留技術)。因此,對於不同的處理器架構,從引導磁區重新啟動的機制會有所不同,不一定涉及從保護模式返回實模式,但可能涉及處理器工作狀態的一些其他切換。

儘管如此,如果一切都得到正確處理,原則上它應該可以工作。將來,Linux 應該具有 kexec-ing 到任何已安裝的可開機分割區的能力(但不一定標記為可開機,因為每個硬碟只能有一個標記為可引導的分割區,否則 BIOS 將直接從任何硬碟報告錯誤並拒絕啟動),而無需完全硬體重新啟動,這要慢​​得多。這為Linux帶來了更多的光明和希望^_^

答案3

您需要安裝 grub 並將 Linux 系統作為預設啟動。

在 Linux 系統上建立一個 crontab 條目,如下所示:

@reboot /do/some/stuff

其中 /do/some/stuff 是執行您需要執行的任何任務的腳本。在腳本末尾添加以下內容:

#!/bin/bash
#
# Do something here

sudo grub2-once "Windows"
sudo reboot

如果 Windows 的 grub 選單項目是“Windows”,那麼它應該會重新啟動到 Windows。

下次重新啟動時,它將返回 Linux 並執行相同的操作。

答案4

kexec如果您將這兩個 grub 映像組合起來可能會起作用:lnxboot.imgcore.img,例如...

cat lnxboot.img core.img > your-kexec-able.img

值得嘗試。

編輯:

現在我查看了圖像內部,lnxboot.image看起來更像是“ELF”而不是lnxboot.img,所以也嘗試一下。

編輯:

顯然, /boot/grub2/i386-pc/xxx.img 映像不符合kexec.那麼為什麼不嘗試使用grub-mkimage產生一些不同的格式,看看什麼有效呢?從手冊頁來看,-O, --format=FORMAT支援一大堆其他格式。也許嘗試一下x86_64-xen格式。

相關內容