mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-08-02 20:02:26 +00:00
Compare commits
No commits in common. "master" and "v1.0.11" have entirely different histories.
12
.github/FUNDING.yml
vendored
12
.github/FUNDING.yml
vendored
@ -1,12 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: Ventoy
|
||||
open_collective: ventoy
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://www.paypal.me/ventoy', 'https://www.ventoy.net/en/donation.html'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
1
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
110
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
110
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@ -1,110 +0,0 @@
|
||||
name: Issue Report
|
||||
description: File an issue report
|
||||
title: "[issue]: "
|
||||
assignees:
|
||||
- octocat
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this issue report!
|
||||
- type: checkboxes
|
||||
id: faq
|
||||
attributes:
|
||||
label: Official FAQ
|
||||
description: Have you checked the official FAQ at [https://www.ventoy.net/en/faq.html](https://www.ventoy.net/en/faq.html) ?
|
||||
options:
|
||||
- label: I have checked the official FAQ.
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Ventoy Version
|
||||
description: What version of ventoy are you running?
|
||||
placeholder: 1.0.96
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: latestrelease
|
||||
attributes:
|
||||
label: What about latest release
|
||||
description: Have you tried with the latest release of Ventoy?
|
||||
options:
|
||||
- Yes. I have tried the latest release, but the bug still exist.
|
||||
- No. I didn't try the latest release.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: alternativemode
|
||||
attributes:
|
||||
label: Try alternative boot mode
|
||||
description: Have you tried alternative boot mode? (wimboot mode for Windows/WinPE, grub2 mode for linux)
|
||||
options:
|
||||
- Yes. I have tried them, but the bug still exist.
|
||||
- No. I didn't try these alternative boot modes.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: bios
|
||||
attributes:
|
||||
label: BIOS Mode
|
||||
description: In which BIOS mode did you find the bug?
|
||||
options:
|
||||
- Legacy BIOS Mode
|
||||
- UEFI Mode
|
||||
- Both
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: partstyle
|
||||
attributes:
|
||||
label: Partition Style
|
||||
description: Which partition style did you select when you install Ventoy?
|
||||
options:
|
||||
- MBR
|
||||
- GPT
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: capacity
|
||||
attributes:
|
||||
label: Disk Capacity
|
||||
description: What is the capacity of the disk installed with Ventoy?
|
||||
placeholder: 32GB
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: vendor
|
||||
attributes:
|
||||
label: Disk Manufacturer
|
||||
description: What is the manufacturer of the disk installed with Ventoy? (e.g. SanDisk/Kingston...)
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: checksum
|
||||
attributes:
|
||||
label: Image file checksum (if applicable)
|
||||
description: Have you checked the image file in Ventoy's menu as [https://www.ventoy.net/en/faq.html#faq_boot_checksum](https://www.ventoy.net/en/faq.html#faq_boot_checksum) ?
|
||||
options:
|
||||
- Yes.
|
||||
- No.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: link
|
||||
attributes:
|
||||
label: Image file download link (if applicable)
|
||||
description: What is the image file download link?
|
||||
placeholder: https://xxx
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Tell me what happened. It's highly recommended to include some photo or video about the bug.
|
||||
placeholder: Tell us what you see!
|
||||
value: "A bug happened!"
|
||||
validations:
|
||||
required: true
|
||||
|
101
.github/ISSUE_TEMPLATE/success_image_report.yml
vendored
101
.github/ISSUE_TEMPLATE/success_image_report.yml
vendored
@ -1,101 +0,0 @@
|
||||
name: Success Image Report
|
||||
description: To report an image file that boot successfully in Ventoy and is not yet listed in https://www.ventoy.net/en/isolist.html
|
||||
title: "[Success Image Report]: "
|
||||
assignees:
|
||||
- octocat
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
I list all the successfully tested image files in the official website: https://www.ventoy.net/en/isolist.html
|
||||
If you successfully test an image file which is not listed in the above page, you can tell me and I will be very glad to add it to the tested list.
|
||||
- type: checkboxes
|
||||
id: faq
|
||||
attributes:
|
||||
label: Official Website List
|
||||
description: Have you checked the list at [https://www.ventoy.net/en/isolist.html](https://www.ventoy.net/en/isolist.html) and the image file is not listed?
|
||||
options:
|
||||
- label: I have checked the list in official website and the image file is not listed there.
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Ventoy Version
|
||||
description: What version of ventoy did you test with the image file.
|
||||
placeholder: 1.0.57
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: bios
|
||||
attributes:
|
||||
label: BIOS Mode
|
||||
description: In which BIOS mode did you successfully test the image file? (It's recommended to test in both mode)
|
||||
options:
|
||||
- Legacy BIOS Mode
|
||||
- UEFI Mode
|
||||
- Both
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: partstyle
|
||||
attributes:
|
||||
label: Partition Style
|
||||
description: Which partition style did you use with Ventoy?
|
||||
options:
|
||||
- MBR
|
||||
- GPT
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: filename
|
||||
attributes:
|
||||
label: Image file name
|
||||
description: The successfully tested image file name.
|
||||
placeholder: xxxx.iso
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: checksum
|
||||
attributes:
|
||||
label: Image file checksum type
|
||||
description:
|
||||
options:
|
||||
- MD5
|
||||
- SHA1
|
||||
- SHA256
|
||||
- SHA512
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: checkvalue
|
||||
attributes:
|
||||
label: Image file checksum value
|
||||
description: What is the image file checksum value corresponding to the above checksum type?
|
||||
placeholder: xxxx
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: link
|
||||
attributes:
|
||||
label: Image file download link (if applicable)
|
||||
description: What is the image file download link?
|
||||
placeholder: https://xxx
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: testenv
|
||||
attributes:
|
||||
label: Test environment
|
||||
description: The manufacturer/model and other details about your computer (or VM).
|
||||
placeholder: Lenovo Thinkpad T420 laptop
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: details
|
||||
attributes:
|
||||
label: More Details?
|
||||
description: You can give more details here.
|
||||
value: "This image file booted successfully in Ventoy."
|
||||
validations:
|
||||
required: false
|
||||
|
37
.github/workflows/ci.yml
vendored
37
.github/workflows/ci.yml
vendored
@ -1,37 +0,0 @@
|
||||
name: Ventoy CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run docker compose up
|
||||
run: docker compose up
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ventoy-windows
|
||||
path: INSTALL/ventoy-*windows*
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ventoy-linux
|
||||
path: INSTALL/ventoy-*linux*
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ventoy-livecd
|
||||
path: INSTALL/ventoy-*livecd*
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SHA256SUM
|
||||
path: INSTALL/sha256.txt
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xxx-build-log
|
||||
path: DOC/build.log
|
25
.github/workflows/sync2gitee.yml
vendored
25
.github/workflows/sync2gitee.yml
vendored
@ -1,25 +0,0 @@
|
||||
name: Mirror GitHub to Gitee
|
||||
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the main branch
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Sync-GitHub-to-Gitee
|
||||
if: ${{ github.repository_owner == 'ventoy' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Mirror the Github repos to Gitee.
|
||||
uses: Yikun/hub-mirror-action@master
|
||||
with:
|
||||
src: github/ventoy
|
||||
dst: gitee/LongPanda
|
||||
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
|
||||
dst_token: ${{ secrets.GITEE_TOKEN }}
|
||||
static_list: "Ventoy"
|
||||
force_update: true
|
193
BLOB_List.md
193
BLOB_List.md
@ -1,193 +0,0 @@
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>BLOB</th>
|
||||
<th>File Source</th>
|
||||
<th>Desc</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr> <td>./BUSYBOX/chmod/vtchmod32</td> <td rowspan=5>build</td> <td rowspan=5>Build Instructions:<br/> ./BUSYBOX/chmod/build.sh</td> </tr>
|
||||
<tr> <td>./BUSYBOX/chmod/vtchmod64</td> </tr>
|
||||
<tr> <td>./BUSYBOX/chmod/vtchmod64_musl</td> </tr>
|
||||
<tr> <td>./BUSYBOX/chmod/vtchmodaa64</td> </tr>
|
||||
<tr> <td>./BUSYBOX/chmod/vtchmodm64e</td> </tr>
|
||||
<tr> <td>./cryptsetup/veritysetup32</td> <td rowspan=2>build</td> <td rowspan=2>Build Instructions:<br/> ./cryptsetup/cryptsetup-build.txt</td> </tr>
|
||||
<tr> <td>./cryptsetup/veritysetup64</td> </tr>
|
||||
<tr> <td>./DMSETUP/dmsetup32</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/> ./DMSETUP/build.txt</td> </tr>
|
||||
<tr> <td>./DMSETUP/dmsetup64</td> </tr>
|
||||
<tr> <td>./DMSETUP/dmsetupaa64</td> </tr>
|
||||
<tr> <td>./DMSETUP/dmsetupm64e</td> </tr>
|
||||
<tr> <td>./FUSEISO/vtoy_fuse_iso_32</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/> ./FUSEISO/build.sh<br/>./FUSEISO/build_aarch64.sh<br/>./FUSEISO/build_libfuse.sh<br/>./FUSEISO/build_libfuse_aarch64.sh </td> </tr>
|
||||
<tr> <td>./FUSEISO/vtoy_fuse_iso_64</td> </tr>
|
||||
<tr> <td>./FUSEISO/vtoy_fuse_iso_aa64</td> </tr>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/busybox/a64</td> <td>build</td> <td>Build Instructions:<br/>./BUSYBOX/build.txt ash</td> </tr>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/busybox/vtchmodaa64</td> <td>build</td> <td>Same with ./BUSYBOX/chmod/vtchmodaa64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/busybox/xzminidecaa64</td> <td>build</td> <td>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.17</td> </tr>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/tool/lz4cataa64</td> <td>build</td> <td>Same with ./LZIP/lz4cataa64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/tool/zstdcataa64</td> <td>build</td> <td>Same with ./ZSTD/zstdcataa64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_mips64/ventoy/busybox/m64</td> <td>build</td> <td>Build Instructions:<br/>./BUSYBOX/build.txt ash</td> </tr>
|
||||
<tr> <td>./IMG/cpio_mips64/ventoy/busybox/vtchmodm64e</td> <td>build</td> <td>Same with ./BUSYBOX/chmod/vtchmodm64e<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_mips64/ventoy/busybox/xzminidecm64e</td> <td>build</td> <td>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.18</td> </tr>
|
||||
<tr> <td>./IMG/cpio_mips64/ventoy/tool/lz4catm64e</td> <td>build</td> <td>Same with ./LZIP/lz4catm64e<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/64h</td> <td>build</td> <td>Build Instructions:<br/>./BUSYBOX/build.txt ash</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/ash</td> <td>upstream</td> <td>Download from BusyBox website.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.4</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/vtchmod32</td> <td>build</td> <td>Same with ./BUSYBOX/chmod/vtchmod32<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/vtchmod64</td> <td>build</td> <td>Same with ./BUSYBOX/chmod/vtchmod64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/vtchmod64_musl</td> <td>build</td> <td>Same with ./BUSYBOX/chmod/vtchmod64_musl<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/xzminidec32</td> <td>build</td> <td>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.15</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/xzminidec64</td> <td>build</td> <td>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.16</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/xzminidec64_musl</td> <td>build</td> <td>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.16</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/ar</td> <td>upstream</td> <td>Download from BusyBox website.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.2</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/inotifyd</td> <td>upstream</td> <td>Download from BusyBox website.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.3</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/lz4cat</td> <td>upstream</td> <td>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.1</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/lz4cat64</td> <td>build</td> <td>Build Instructions:<br/>./LZIP/buildlz4.txt</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/zstdcat</td> <td>build</td> <td>Same with ./ZSTD/zstdcat<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/tool/zstdcat64</td> <td>build</td> <td>Same with ./ZSTD/zstdcat64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/BOOTAA64.EFI</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/> ./DOC/BuildVentoyFromSource.txt 4.1-Build grub2</td> </tr>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/BOOTMIPS.EFI</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/grubia32_real.efi</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/grubx64_real.efi</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/grub.efi</td> <td rowspan=6>upstream</td> <td rowspan=6>https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk </td> </tr>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/BOOTIA32.EFI</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/BOOTX64.EFI</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/grubia32.efi</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/mmia32.efi</td>
|
||||
<tr> <td>./INSTALL/EFI/BOOT/MokManager.efi</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/ash</td> <td rowspan=12>build</td> <td rowspan=12>Build Instructions:<br/>./DOC/BUSYBOX/build.txt</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/aarch64/hexdump</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/xzcat</td>
|
||||
<tr> <td>./INSTALL/tool/i386/ash</td>
|
||||
<tr> <td>./INSTALL/tool/i386/hexdump</td>
|
||||
<tr> <td>./INSTALL/tool/i386/xzcat</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/ash</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/hexdump</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/xzcat</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/ash</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/hexdump</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/xzcat</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/Ventoy2Disk.gtk3</td> <td rowspan=6>build</td> <td rowspan=6>Build Instructions:<br/>./LinuxGUI/build_gtk.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/Ventoy2Disk.gtk3</td>
|
||||
<tr> <td>./INSTALL/tool/i386/Ventoy2Disk.gtk2</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/Ventoy2Disk.gtk3</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/Ventoy2Disk.gtk3</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/Ventoy2Disk.gtk2</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/Ventoy2Disk.qt5</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./LinuxGUI/build_qt.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/Ventoy2Disk.qt5</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/Ventoy2Disk.qt5</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/Ventoy2Disk.qt5</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/Plugson</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./Plugson/build.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/Plugson</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/Plugson</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/Plugson</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/V2DServer</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./LinuxGUI/build.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/V2DServer</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/V2DServer</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/V2DServer</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/mkexfatfs</td> <td rowspan=8>build</td> <td rowspan=8>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.9<br/>./ExFAT/buidexfat.sh<br/>./ExFAT/buidexfat_aarch64.sh<br/>./ExFAT/buidlibfuse.sh<br/>./ExFAT/buidlibfuse_aarch64.sh<br/></td> </tr>
|
||||
<tr> <td>./INSTALL/tool/aarch64/mount.exfat-fuse</td>
|
||||
<tr> <td>./INSTALL/tool/i386/mkexfatfs</td>
|
||||
<tr> <td>./INSTALL/tool/i386/mount.exfat-fuse</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/mkexfatfs</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/mount.exfat-fuse</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/mkexfatfs</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/mount.exfat-fuse</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/vlnk</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./Vlnk/build.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/vlnk</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/vlnk</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/vlnk</td>
|
||||
<tr> <td>./INSTALL/tool/aarch64/vtoycli</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./vtoycli/build.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/tool/i386/vtoycli</td>
|
||||
<tr> <td>./INSTALL/tool/mips64el/vtoycli</td>
|
||||
<tr> <td>./INSTALL/tool/x86_64/vtoycli</td>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/32/imdisk.cpl</td> <td rowspan=6>upstream</td> <td rowspan=6>Download from imdisk project.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.8</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/32/imdisk.exe</td>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/32/imdisk.sys</td>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/64/imdisk.cpl</td>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/64/imdisk.exe</td>
|
||||
<tr> <td>./INSTALL/ventoy/imdisk/64/imdisk.sys</td>
|
||||
<tr> <td>./INSTALL/ventoy/iso9660_aa64.efi</td> <td rowspan=6>build</td> <td rowspan=6>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.17</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/udf_aa64.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/iso9660_ia32.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/udf_ia32.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/iso9660_x64.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/udf_x64.efi</td>
|
||||
<tr> <td>./INSTALL/VentoyGUI.aarch64</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./LinuxGUI/build_gtk.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/VentoyGUI.i386</td>
|
||||
<tr> <td>./INSTALL/VentoyGUI.mips64el</td>
|
||||
<tr> <td>./INSTALL/VentoyGUI.x86_64</td>
|
||||
<tr> <td>./INSTALL/Ventoy2Disk.exe</td> <td rowspan=4>build</td> <td rowspan=4>Build Instructions:<br/>./Ventoy2Disk/Ventoy2Disk.sln</td> </tr>
|
||||
<tr> <td>./INSTALL/Ventoy2Disk_ARM.exe</td>
|
||||
<tr> <td>./INSTALL/Ventoy2Disk_ARM64.exe</td>
|
||||
<tr> <td>./INSTALL/Ventoy2Disk_X64.exe</td>
|
||||
<tr> <td>./INSTALL/ventoy/vtoyjump32.exe</td> <td rowspan=2>build</td> <td rowspan=2>Build Instructions:<br/>./vtoyjump/vtoyjump.sln</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/vtoyjump64.exe</td>
|
||||
<tr> <td>./INSTALL/ventoy/ventoy_aa64.efi</td> <td rowspan=6>build</td> <td rowspan=6>Build Instructions:<br/>./EDK2/buildedk.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/ventoy_ia32.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/ventoy_x64.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/vtoyutil_aa64.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/vtoyutil_ia32.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/vtoyutil_x64.efi</td>
|
||||
<tr> <td>./INSTALL/ventoy/ipxe.krn</td> <td>build</td> <td>Build Instructions:<br/>./IPXE/buildipxe.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/memdisk</td> <td>upstream</td> <td>Download from syslinux project.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.9</td> </tr>
|
||||
<tr> <td>./LiveCD/ISO/EFI/boot/vmlinuz64</td> <td>upstream</td> <td>Download from TinyLinux website.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.14</td> </tr>
|
||||
<tr> <td>./LiveCDGUI/EXT/busybox-x86_64</td> <td>build</td> <td>Same with ./IMG/cpio_x86/ventoy/busybox/busybox64<br/>Check the file hash to confirm</td> </tr>
|
||||
<tr> <td>./LiveCDGUI/GRUB/bootx64.efi</td> <td rowspan=2>build</td> <td rowspan=2>./DOC/BuildVentoyFromSource.txt 4.1-Build grub2</td> </tr>
|
||||
<tr> <td>./LiveCD/GRUB/bootx64.efi</td>
|
||||
<tr> <td>./LZIP/lunzip32</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/>./DOC/BuildVentoyFromSource.txt 4.19</td> </tr>
|
||||
<tr> <td>./LZIP/lunzip64</td>
|
||||
<tr> <td>./LZIP/lunzipaa64</td>
|
||||
<tr> <td>./LZIP/lz4cat64</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/>./LZIP/buildlz4.txt</td> </tr>
|
||||
<tr> <td>./LZIP/lz4cataa64</td>
|
||||
<tr> <td>./LZIP/lz4catm64e</td>
|
||||
<tr> <td>./Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe</td> <td rowspan=2>build</td> <td rowspan=2>Build Instructions:<br/>./Plugson/vs/VentoyPlugson/VentoyPlugson.sln</td> </tr>
|
||||
<tr> <td>./Plugson/vs/VentoyPlugson/x64/Release/VentoyPlugson_X64.exe</td>
|
||||
<tr> <td>./SQUASHFS/unsquashfs_32</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/>./SQUASHFS/build.sh</td> </tr>
|
||||
<tr> <td>./SQUASHFS/unsquashfs_64</td>
|
||||
<tr> <td>./SQUASHFS/unsquashfs_aa64</td>
|
||||
<tr> <td>./Unix/ventoy_unix/DragonFly/sbin/dmsetup</td> <td>upstream</td> <td>Get from DragonFly ISO.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.13</td> </tr>
|
||||
<tr> <td>./Unix/ventoy_unix/DragonFly/sbin/init</td> <td>build</td> <td>Build Instructions:<br/>./Unix/ventoy_unix_src/DragonFly/build.sh</td> </tr>
|
||||
<tr> <td>./VBLADE/vblade-master/vblade_32</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/>./VBLADE/vblade-master/build.sh</td> </tr>
|
||||
<tr> <td>./VBLADE/vblade-master/vblade_64</td>
|
||||
<tr> <td>./VBLADE/vblade-master/vblade_aa64</td>
|
||||
<tr> <td>./Vlnk/vs/VentoyVlnk/Release/VentoyVlnk.exe</td> <td>build</td> <td>Build Instructions:<br/>./Vlnk/vs/VentoyVlnk/VentoyVlnk.sln</td> </tr>
|
||||
<tr> <td>./VtoyTool/vtoytool/00/vtoytool_32</td> <td rowspan=6>build</td> <td rowspan=6>Build Instructions:<br/>./VtoyTool/build.sh</td> </tr>
|
||||
<tr> <td>./VtoyTool/vtoytool/00/vtoytool_64</td>
|
||||
<tr> <td>./VtoyTool/vtoytool/00/vtoytool_aa64</td>
|
||||
<tr> <td>./VtoyTool/vtoytool/00/vtoytool_m64e</td>
|
||||
<tr> <td>./VtoyTool/vtoytool/01/vtoytool_64</td>
|
||||
<tr> <td>./VtoyTool/vtoytool/02/vtoytool_64</td>
|
||||
<tr> <td>./ZSTD/zstdcat</td> <td rowspan=3>build</td> <td rowspan=3>Build Instructions:<br/>./ZSTD/build.txt</td> </tr>
|
||||
<tr> <td>./ZSTD/zstdcat64</td>
|
||||
<tr> <td>./ZSTD/zstdcataa64</td>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/busybox32</td> <td rowspan=6>build</td> <td rowspan=6>Build Instructions:<br/>./BUSYBOX/build.txt full busybox</td> </tr>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/busybox64</td>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/xzcat32_musl</td>
|
||||
<tr> <td>./IMG/cpio_x86/ventoy/busybox/xzcat64_musl</td>
|
||||
<tr> <td>./IMG/cpio_arm64/ventoy/busybox/busyboxaa64</td>
|
||||
<tr> <td>./IMG/cpio_mips64/ventoy/busybox/busyboxm64e</td>
|
||||
<tr> <td>ISNTALL/ventoy/7z/64/7za.exe</td> <td rowspan=2>upstream</td> <td>Download from 7z project.<br/>URL & File Hash documented in<br/> ./DOC/BuildVentoyFromSource.txt 5.12</td> </tr>
|
||||
<tr> <td>ISNTALL/ventoy/7z/32/7za.exe</td>
|
||||
<tr> <td>./INSTALL/ventoy/wimboot.i386.efi</td> <td rowspan=2>build</td> <td rowspan=2>Build Instructions:<br/>./wimboot/build.sh</td> </tr>
|
||||
<tr> <td>./INSTALL/ventoy/wimboot.x86_64</td>
|
||||
<tr> <td> ./Unix/ventoy_unix/ClonOS/geom_ventoy_ko/13.x/64/geom_ventoy.ko</td> <td rowspan=18>build</td> <td rowspan=18>Build Instructions:<br/>./Unix/BuildUnixKmod.txt</td> </tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/2.x/32/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/2.x/64/geom_ventoy.ko</td></tr>
|
||||
<tr> <td> ./Unix/ventoy_unix/pfSense/geom_ventoy_ko/14.x/64/geom_ventoy.ko</td></tr>
|
||||
</tbody>
|
||||
</table>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
||||
======== How to build ash/hexdump/xzcat for aarch64 ========
|
||||
#How to get ash.config/hexdump.cofig/xzcat.config
|
||||
#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make allnoconfig
|
||||
#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make menuconfig
|
||||
#----> enable static build
|
||||
#----> enable xzcat
|
||||
#get aarch64_xzcat.config
|
||||
|
||||
tar xf busybox-1.32.0.tar.bz2
|
||||
cd busybox-1.32.0
|
||||
copy aarch64_xzcat.config as .config
|
||||
ARCH=arm64 CROSS_COMPILE=aarch64-linux- make
|
||||
rename ./busybox to xzcat
|
||||
|
||||
|
||||
======== How to build ash/hexdump/xzcat for mips64el ========
|
||||
#download mips64el-musl cross toolchain from https://github.com/ventoy/musl-cross-make/releases/download/latest/
|
||||
#How to get ash.config/hexdump.cofig/xzcat.config
|
||||
#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make allnoconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"
|
||||
#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make menuconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"
|
||||
#----> enable static build
|
||||
#----> enable xzcat
|
||||
#get mips64el_xzcat.config
|
||||
|
||||
tar xf busybox-1.32.0.tar.bz2
|
||||
cd busybox-1.32.0
|
||||
copy mips64el_xzcat.config as .config
|
||||
ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"
|
||||
rename ./busybox to xzcat
|
||||
|
||||
|
||||
======== How to build full busybox =========
|
||||
#make defconfig
|
||||
#make menuconfig select static build
|
||||
|
||||
======== How to build ash/hexdump/xzcat for x86_64 ==========
|
||||
#How to get ash.config/hexdump.cofig/xzcat.config
|
||||
#make allnoconfig
|
||||
#make menuconfig
|
||||
#----> enable static build
|
||||
#----> enable xzcat
|
||||
#get x86_64_xzcat.config
|
||||
|
||||
|
||||
tar xf busybox-1.32.0.tar.bz2
|
||||
cd busybox-1.32.0
|
||||
copy x86_64_xzcat.config as .config
|
||||
modify Makefile
|
||||
CC = gcc -specs "/usr/local/musl/lib/musl-gcc.specs"
|
||||
MODFLAGS = -DMODULE -specs "/usr/local/musl/lib/musl-gcc.specs"
|
||||
make
|
||||
rename ./busybox to xzcat
|
||||
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
DSTDIR1=../../IMG/cpio_x86/ventoy/busybox
|
||||
DSTDIR2=../../IMG/cpio_arm64/ventoy/busybox
|
||||
DSTDIR3=../../IMG/cpio_mips64/ventoy/busybox
|
||||
|
||||
rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64
|
||||
rm -f $DSTDIR1/vtchmod32 $DSTDIR1/vtchmod64 $DSTDIR2/vtchmodaa64 $DSTDIR3/vtchmodm64e
|
||||
|
||||
/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32
|
||||
/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64
|
||||
aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64
|
||||
aarch64-linux-strip --strip-all vtchmodaa64
|
||||
|
||||
mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static vtchmod.c -o vtchmodm64e
|
||||
mips64el-linux-musl-strip --strip-all vtchmodm64e
|
||||
|
||||
|
||||
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static vtchmod.c -o vtchmod64_musl
|
||||
strip --strip-all vtchmod64_musl
|
||||
|
||||
chmod 777 vtchmod32
|
||||
chmod 777 vtchmod64
|
||||
chmod 777 vtchmodaa64
|
||||
chmod 777 vtchmod64_musl
|
||||
chmod 777 vtchmodm64e
|
||||
|
||||
cp -a vtchmod32 $DSTDIR1/
|
||||
cp -a vtchmod64 $DSTDIR1/
|
||||
cp -a vtchmod64_musl $DSTDIR1/
|
||||
cp -a vtchmodaa64 $DSTDIR2/
|
||||
cp -a vtchmodm64e $DSTDIR3/
|
||||
|
@ -1,34 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argv[1][0] == '-' && argv[1][1] == '6')
|
||||
{
|
||||
struct utsname buf;
|
||||
if (0 == uname(&buf))
|
||||
{
|
||||
if (strstr(buf.machine, "amd64"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(buf.machine, "x86_64"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return chmod(argv[1], 0777);
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1181
BUSYBOX/config
1181
BUSYBOX/config
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
|
||||
obj-m += dm_patch.o
|
||||
|
||||
EXTRA_CFLAGS := -Wall
|
||||
|
||||
dm_patch-objs := dmpatch.o
|
||||
|
@ -1,7 +0,0 @@
|
||||
|
||||
obj-m += dm_patch_ibt.o
|
||||
|
||||
EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register
|
||||
|
||||
dm_patch_ibt-objs := dmpatch.o
|
||||
|
@ -1,632 +0,0 @@
|
||||
/******************************************************************************
|
||||
* dmpatch.c ---- patch for device-mapper
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mempool.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define MAX_PATCH 4
|
||||
|
||||
#define magic_sig 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
|
||||
|
||||
typedef int (*kprobe_reg_pf)(void *);
|
||||
typedef void (*kprobe_unreg_pf)(void *);
|
||||
typedef int (*printk_pf)(const char *fmt, ...);
|
||||
typedef int (*set_memory_attr_pf)(unsigned long addr, int numpages);
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct ko_param
|
||||
{
|
||||
unsigned char magic[16];
|
||||
unsigned long struct_size;
|
||||
unsigned long pgsize;
|
||||
unsigned long printk_addr;
|
||||
unsigned long ro_addr;
|
||||
unsigned long rw_addr;
|
||||
unsigned long reg_kprobe_addr;
|
||||
unsigned long unreg_kprobe_addr;
|
||||
unsigned long sym_get_addr;
|
||||
unsigned long sym_get_size;
|
||||
unsigned long sym_put_addr;
|
||||
unsigned long sym_put_size;
|
||||
unsigned long kv_major;
|
||||
unsigned long ibt;
|
||||
unsigned long kv_minor;
|
||||
unsigned long blkdev_get_addr;
|
||||
unsigned long blkdev_put_addr;
|
||||
unsigned long bdev_open_addr;
|
||||
unsigned long kv_subminor;
|
||||
unsigned long bdev_file_open_addr;
|
||||
unsigned long padding[1];
|
||||
}ko_param;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
static printk_pf kprintf = NULL;
|
||||
static set_memory_attr_pf set_mem_ro = NULL;
|
||||
static set_memory_attr_pf set_mem_rw = NULL;
|
||||
static kprobe_reg_pf reg_kprobe = NULL;
|
||||
static kprobe_unreg_pf unreg_kprobe = NULL;
|
||||
|
||||
static volatile ko_param g_ko_param =
|
||||
{
|
||||
{ magic_sig },
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#if defined(CONFIG_X86_64)
|
||||
#define PATCH_OP_POS1 3
|
||||
#define CODE_MATCH1(code, i) \
|
||||
(code[i] == 0x40 && code[i + 1] == 0x80 && code[i + 2] == 0xce && code[i + 3] == 0x80)
|
||||
|
||||
#define PATCH_OP_POS2 1
|
||||
#define CODE_MATCH2(code, i) \
|
||||
(code[i] == 0x0C && code[i + 1] == 0x80 && code[i + 2] == 0x89 && code[i + 3] == 0xC6)
|
||||
|
||||
#define PATCH_OP_POS3 4
|
||||
#define CODE_MATCH3(code, i) \
|
||||
(code[i] == 0x44 && code[i + 1] == 0x89 && code[i + 2] == 0xe8 && code[i + 3] == 0x0c && code[i + 4] == 0x80)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined(CONFIG_X86_32)
|
||||
#define PATCH_OP_POS1 2
|
||||
#define CODE_MATCH1(code, i) \
|
||||
(code[i] == 0x80 && code[i + 1] == 0xca && code[i + 2] == 0x80 && code[i + 3] == 0xe8)
|
||||
|
||||
#define PATCH_OP_POS2 PATCH_OP_POS1
|
||||
#define CODE_MATCH2 CODE_MATCH1
|
||||
#define PATCH_OP_POS3 PATCH_OP_POS1
|
||||
#define CODE_MATCH3 CODE_MATCH1
|
||||
|
||||
|
||||
#else
|
||||
#error "unsupported arch"
|
||||
#endif
|
||||
|
||||
#ifdef VTOY_IBT
|
||||
#ifdef CONFIG_X86_64
|
||||
/* Using 64-bit values saves one instruction clearing the high half of low */
|
||||
#define DECLARE_ARGS(val, low, high) unsigned long low, high
|
||||
#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32)
|
||||
#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
|
||||
#else
|
||||
#define DECLARE_ARGS(val, low, high) unsigned long long val
|
||||
#define EAX_EDX_VAL(val, low, high) (val)
|
||||
#define EAX_EDX_RET(val, low, high) "=A" (val)
|
||||
#endif
|
||||
|
||||
#define EX_TYPE_WRMSR 8
|
||||
#define EX_TYPE_RDMSR 9
|
||||
#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */
|
||||
#define CET_ENDBR_EN (1ULL << 2)
|
||||
|
||||
/* Exception table entry */
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#define _ASM_EXTABLE_TYPE(from, to, type) \
|
||||
.pushsection "__ex_table","a" ; \
|
||||
.balign 4 ; \
|
||||
.long (from) - . ; \
|
||||
.long (to) - . ; \
|
||||
.long type ; \
|
||||
.popsection
|
||||
|
||||
#else /* ! __ASSEMBLY__ */
|
||||
|
||||
#define _ASM_EXTABLE_TYPE(from, to, type) \
|
||||
" .pushsection \"__ex_table\",\"a\"\n" \
|
||||
" .balign 4\n" \
|
||||
" .long (" #from ") - .\n" \
|
||||
" .long (" #to ") - .\n" \
|
||||
" .long " __stringify(type) " \n" \
|
||||
" .popsection\n"
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* VTOY_IBT */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
|
||||
|
||||
static unsigned int g_claim_ptr = 0;
|
||||
static unsigned char *g_get_patch[MAX_PATCH] = { NULL };
|
||||
static unsigned char *g_put_patch[MAX_PATCH] = { NULL };
|
||||
|
||||
static int notrace dmpatch_kv_above(unsigned long Major, unsigned long Minor, unsigned long SubMinor)
|
||||
{
|
||||
if (g_ko_param.kv_major != Major)
|
||||
{
|
||||
return (g_ko_param.kv_major > Major) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (g_ko_param.kv_minor != Minor)
|
||||
{
|
||||
return (g_ko_param.kv_minor > Minor) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (g_ko_param.kv_subminor != SubMinor)
|
||||
{
|
||||
return (g_ko_param.kv_subminor > SubMinor) ? 1 : 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void notrace dmpatch_restore_code(int bytes, unsigned char *opCode, unsigned int code)
|
||||
{
|
||||
unsigned long align;
|
||||
|
||||
if (opCode)
|
||||
{
|
||||
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||
set_mem_rw(align, 1);
|
||||
if (bytes == 1)
|
||||
{
|
||||
*opCode = (unsigned char)code;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(unsigned int *)opCode = code;
|
||||
}
|
||||
set_mem_ro(align, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int notrace dmpatch_replace_code
|
||||
(
|
||||
int style,
|
||||
unsigned long addr,
|
||||
unsigned long size,
|
||||
int expect,
|
||||
const char *desc,
|
||||
unsigned char **patch
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
int cnt = 0;
|
||||
unsigned long align;
|
||||
unsigned char *opCode = (unsigned char *)addr;
|
||||
|
||||
vdebug("patch for %s style[%d] 0x%lx %d\n", desc, style, addr, (int)size);
|
||||
|
||||
for (i = 0; i < (int)size - 8; i++)
|
||||
{
|
||||
if (style == 1)
|
||||
{
|
||||
if (CODE_MATCH1(opCode, i) && cnt < MAX_PATCH)
|
||||
{
|
||||
patch[cnt] = opCode + i + PATCH_OP_POS1;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
else if (style == 2)
|
||||
{
|
||||
if (CODE_MATCH2(opCode, i) && cnt < MAX_PATCH)
|
||||
{
|
||||
patch[cnt] = opCode + i + PATCH_OP_POS2;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
else if (style == 3)
|
||||
{
|
||||
if (CODE_MATCH3(opCode, i) && cnt < MAX_PATCH)
|
||||
{
|
||||
patch[cnt] = opCode + i + PATCH_OP_POS3;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (cnt != expect || cnt >= MAX_PATCH)
|
||||
{
|
||||
vdebug("patch error: cnt=%d expect=%d\n", cnt, expect);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
opCode = patch[i];
|
||||
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||
|
||||
set_mem_rw(align, 1);
|
||||
*opCode = 0;
|
||||
set_mem_ro(align, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long notrace dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
unsigned long dest;
|
||||
unsigned char *opCode = NULL;
|
||||
unsigned char aucOffset[8] = { 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
opCode = (unsigned char *)addr;
|
||||
|
||||
for (i = 0; i + 4 < size; i++)
|
||||
{
|
||||
if (opCode[i] == 0xE8)
|
||||
{
|
||||
aucOffset[0] = opCode[i + 1];
|
||||
aucOffset[1] = opCode[i + 2];
|
||||
aucOffset[2] = opCode[i + 3];
|
||||
aucOffset[3] = opCode[i + 4];
|
||||
|
||||
dest = addr + i + 5 + *(unsigned long *)aucOffset;
|
||||
if (dest == func)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int notrace dmpatch_patch_claim_ptr(void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
unsigned long t = 0;
|
||||
unsigned long offset1 = 0;
|
||||
unsigned long offset2 = 0;
|
||||
unsigned long align = 0;
|
||||
unsigned char *opCode = NULL;
|
||||
|
||||
opCode = (unsigned char *)g_ko_param.sym_get_addr;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
vdebug("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
opCode[i + 0], opCode[i + 1], opCode[i + 2], opCode[i + 3],
|
||||
opCode[i + 4], opCode[i + 5], opCode[i + 6], opCode[i + 7],
|
||||
opCode[i + 8], opCode[i + 9], opCode[i + 10], opCode[i + 11],
|
||||
opCode[i + 12], opCode[i + 13], opCode[i + 14], opCode[i + 15]);
|
||||
}
|
||||
|
||||
if (dmpatch_kv_above(6, 7, 0)) /* >= 6.7 kernel */
|
||||
{
|
||||
vdebug("Get addr: 0x%lx %lu open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
|
||||
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
|
||||
if (offset1 == 0)
|
||||
{
|
||||
vdebug("call bdev_open_addr Not found\n");
|
||||
|
||||
vdebug("Get addr: 0x%lx %lu file_open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
|
||||
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
|
||||
if (offset1 == 0)
|
||||
{
|
||||
vdebug("call bdev_file_open_addr Not found\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
|
||||
vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
|
||||
|
||||
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
|
||||
offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
|
||||
if (offset1 == 0 || offset2 == 0)
|
||||
{
|
||||
vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vdebug("call addr1:0x%lx call addr2:0x%lx\n",
|
||||
g_ko_param.sym_get_addr + offset1,
|
||||
g_ko_param.sym_put_addr + offset2);
|
||||
|
||||
opCode = (unsigned char *)g_ko_param.sym_get_addr;
|
||||
for (i = offset1 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
|
||||
{
|
||||
/* rdx */
|
||||
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc2)
|
||||
{
|
||||
g_claim_ptr = *(unsigned int *)(opCode + i + 3);
|
||||
g_get_patch[0] = opCode + i + 3;
|
||||
vdebug("claim_ptr(%08X) found at get addr 0x%lx\n", g_claim_ptr, g_ko_param.sym_get_addr + i + 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_claim_ptr == 0)
|
||||
{
|
||||
vdebug("Claim_ptr not found in get\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
align = (unsigned long)g_get_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||
set_mem_rw(align, 1);
|
||||
*(unsigned int *)(g_get_patch[0]) = 0;
|
||||
set_mem_ro(align, 1);
|
||||
|
||||
|
||||
if (offset2 > 0)
|
||||
{
|
||||
opCode = (unsigned char *)g_ko_param.sym_put_addr;
|
||||
for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
|
||||
{
|
||||
/* rsi */
|
||||
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6)
|
||||
{
|
||||
if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr)
|
||||
{
|
||||
vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3);
|
||||
g_put_patch[0] = opCode + i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_put_patch[0] == 0)
|
||||
{
|
||||
vdebug("Claim_ptr not found in put\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||
set_mem_rw(align, 1);
|
||||
*(unsigned int *)(g_put_patch[0]) = 0;
|
||||
set_mem_ro(align, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef VTOY_IBT
|
||||
static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr)
|
||||
{
|
||||
DECLARE_ARGS(val, low, high);
|
||||
|
||||
asm volatile("1: rdmsr\n"
|
||||
"2:\n"
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR)
|
||||
: EAX_EDX_RET(val, low, high) : "c" (msr));
|
||||
|
||||
return EAX_EDX_VAL(val, low, high);
|
||||
}
|
||||
|
||||
static __always_inline void dmpatch_wrmsr(unsigned int msr, u32 low, u32 high)
|
||||
{
|
||||
asm volatile("1: wrmsr\n"
|
||||
"2:\n"
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
|
||||
: : "c" (msr), "a"(low), "d" (high) : "memory");
|
||||
}
|
||||
|
||||
static u64 notrace dmpatch_ibt_save(void)
|
||||
{
|
||||
u64 msr = 0;
|
||||
u64 val = 0;
|
||||
|
||||
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
|
||||
val = msr & ~CET_ENDBR_EN;
|
||||
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(val & 0xffffffffULL), (u32)(val >> 32));
|
||||
|
||||
return msr;
|
||||
}
|
||||
|
||||
static void notrace dmpatch_ibt_restore(u64 save)
|
||||
{
|
||||
u64 msr;
|
||||
|
||||
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
|
||||
|
||||
msr &= ~CET_ENDBR_EN;
|
||||
msr |= (save & CET_ENDBR_EN);
|
||||
|
||||
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(msr & 0xffffffffULL), (u32)(msr >> 32));
|
||||
}
|
||||
#else
|
||||
static u64 notrace dmpatch_ibt_save(void) { return 0; }
|
||||
static void notrace dmpatch_ibt_restore(u64 save) { (void)save; }
|
||||
#endif
|
||||
|
||||
static int notrace dmpatch_process(unsigned long a, unsigned long b, unsigned long c)
|
||||
{
|
||||
int r = 0;
|
||||
int rc = 0;
|
||||
unsigned long kv_major = 0;
|
||||
unsigned long kv_minor = 0;
|
||||
unsigned long kv_subminor = 0;
|
||||
|
||||
vdebug("dmpatch_process as KV %d.%d.%d ...\n", (int)a, (int)b, (int)c);
|
||||
|
||||
kv_major = g_ko_param.kv_major;
|
||||
kv_minor = g_ko_param.kv_minor;
|
||||
kv_subminor = g_ko_param.kv_subminor;
|
||||
|
||||
g_ko_param.kv_major = a;
|
||||
g_ko_param.kv_minor = b;
|
||||
g_ko_param.kv_subminor = c;
|
||||
|
||||
if (dmpatch_kv_above(6, 5, 0)) /* >= kernel 6.5 */
|
||||
{
|
||||
vdebug("new interface patch dm_get_table_device...\n");
|
||||
r = dmpatch_patch_claim_ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
r = dmpatch_replace_code(1, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device", g_get_patch);
|
||||
if (r && g_ko_param.kv_major >= 5)
|
||||
{
|
||||
vdebug("new2 patch dm_get_table_device...\n");
|
||||
r = dmpatch_replace_code(2, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
|
||||
}
|
||||
|
||||
if (r && g_ko_param.kv_major >= 5)
|
||||
{
|
||||
vdebug("new3 patch dm_get_table_device...\n");
|
||||
r = dmpatch_replace_code(3, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
|
||||
}
|
||||
}
|
||||
|
||||
if (r)
|
||||
{
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
vdebug("patch dm_get_table_device success\n");
|
||||
|
||||
if (dmpatch_kv_above(6, 5, 0))
|
||||
{
|
||||
r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch);
|
||||
if (r)
|
||||
{
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
vdebug("patch dm_put_table_device success\n");
|
||||
}
|
||||
|
||||
vdebug("#####################################\n");
|
||||
vdebug("######## dm patch success ###########\n");
|
||||
vdebug("#####################################\n");
|
||||
|
||||
out:
|
||||
|
||||
g_ko_param.kv_major = kv_major;
|
||||
g_ko_param.kv_minor = kv_minor;
|
||||
g_ko_param.kv_subminor = kv_subminor;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int notrace dmpatch_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
u64 msr = 0;
|
||||
|
||||
if (g_ko_param.ibt == 0x8888)
|
||||
{
|
||||
msr = dmpatch_ibt_save();
|
||||
}
|
||||
|
||||
kprintf = (printk_pf)(g_ko_param.printk_addr);
|
||||
|
||||
vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu.%lu ...\n",
|
||||
g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
|
||||
|
||||
if (g_ko_param.struct_size != sizeof(ko_param))
|
||||
{
|
||||
vdebug("Invalid struct size %d %d\n", (int)g_ko_param.struct_size, (int)sizeof(ko_param));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (g_ko_param.sym_get_addr == 0 || g_ko_param.sym_put_addr == 0 ||
|
||||
g_ko_param.ro_addr == 0 || g_ko_param.rw_addr == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
set_mem_ro = (set_memory_attr_pf)(g_ko_param.ro_addr);
|
||||
set_mem_rw = (set_memory_attr_pf)(g_ko_param.rw_addr);
|
||||
reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr;
|
||||
unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr;
|
||||
|
||||
rc = dmpatch_process(g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
|
||||
if (rc)
|
||||
{
|
||||
if (g_ko_param.kv_major >= 5)
|
||||
{
|
||||
rc = dmpatch_process(6, 5, 0);
|
||||
if (rc)
|
||||
{
|
||||
rc = dmpatch_process(6, 7, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ko_param.ibt == 0x8888)
|
||||
{
|
||||
dmpatch_ibt_restore(msr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void notrace dmpatch_exit(void)
|
||||
{
|
||||
int i = 0;
|
||||
u64 msr;
|
||||
|
||||
if (g_ko_param.ibt == 0x8888)
|
||||
{
|
||||
msr = dmpatch_ibt_save();
|
||||
}
|
||||
|
||||
if (g_claim_ptr)
|
||||
{
|
||||
dmpatch_restore_code(4, g_get_patch[0], g_claim_ptr);
|
||||
if (g_put_patch[0])
|
||||
{
|
||||
dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_PATCH; i++)
|
||||
{
|
||||
dmpatch_restore_code(1, g_get_patch[i], 0x80);
|
||||
dmpatch_restore_code(1, g_put_patch[i], 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
vdebug("dmpatch_exit success\n");
|
||||
|
||||
if (g_ko_param.ibt == 0x8888)
|
||||
{
|
||||
dmpatch_ibt_restore(msr);
|
||||
}
|
||||
}
|
||||
|
||||
module_init(dmpatch_init);
|
||||
module_exit(dmpatch_exit);
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("dmpatch driver");
|
||||
MODULE_AUTHOR("longpanda <admin@ventoy.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1,38 +0,0 @@
|
||||
1. install ubuntu 22.04 5.15.0-25
|
||||
2. apt-get install build-essential flex libncurses-dev linux-headers-generic linux-source libssl-dev bison yacc vim libelf-dev ...... and so on
|
||||
3. cp /lib/modules/5.15.0-25-generic/build/Module.symvers ./
|
||||
4. /boot/config-5.15.0-25-generic as .config make oldconfig
|
||||
5. make menuconfig
|
||||
1. close CONFIG_STACKPROTECTOR
|
||||
2. close CONFIG_RETPOLINE
|
||||
3. close CONFIG_UBSAN_BOUNDS
|
||||
4. close CONFIG_UBSAN_ENUM
|
||||
|
||||
6. modify ./scripts/mod/modpost.c
|
||||
1. skip add_srcversion (just return)
|
||||
2. force add_retpoline (#ifdef --> #ifndef)
|
||||
3. force add_intree_flag
|
||||
|
||||
7. make modules_prepare LOCALVERSION=-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
8. Append padding at the end of struct module <include/linux/module.h>
|
||||
struct module {
|
||||
enum module_state state;
|
||||
|
||||
/* Member of list of modules */
|
||||
struct list_head list;
|
||||
|
||||
/* Unique handle for this module */
|
||||
char name[MODULE_NAME_LEN];
|
||||
|
||||
....
|
||||
|
||||
char padding[1024];
|
||||
};
|
||||
|
||||
This is because struct module size is different in different kernel versions or with different CONFIG item.
|
||||
|
||||
|
||||
9. make modules M=/home/dmpatch
|
||||
10. strip --strip-debug /home/dmpatch/dm_patch.ko
|
||||
|
@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
FTPIP=192.168.44.1
|
||||
FTPUSR='a:a'
|
||||
|
||||
rm -f dmpatch.c Makefile Makefile_IBT
|
||||
|
||||
for f in dmpatch.c Makefile Makefile_IBT; do
|
||||
curl -s -u $FTPUSR ftp://$FTPIP/$f -o $f
|
||||
if [ -f $f ]; then
|
||||
echo "download $f OK ..."
|
||||
else
|
||||
echo "download $f FAILED ..."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
||||
rm -f *.ko
|
||||
|
||||
|
||||
echo "build dm_patch.ko ..."
|
||||
rm -rf ./aa
|
||||
mkdir ./aa
|
||||
|
||||
cp -a *.c aa/
|
||||
cp -a Makefile aa/
|
||||
|
||||
cd /home/panda/linux-source-5.15.0
|
||||
make modules M=/home/panda/build/aa/
|
||||
strip --strip-debug /home/panda/build/aa/dm_patch.ko
|
||||
cd -
|
||||
|
||||
cp -a aa/dm_patch.ko ./
|
||||
|
||||
|
||||
|
||||
echo "build dm_patch_ibt.ko ..."
|
||||
rm -rf ./aa
|
||||
mkdir ./aa
|
||||
|
||||
cp -a *.c aa/
|
||||
cp -a Makefile_IBT aa/Makefile
|
||||
|
||||
cd /home/panda/linux-source-5.15.0
|
||||
make modules M=/home/panda/build/aa/
|
||||
strip --strip-debug /home/panda/build/aa/dm_patch_ibt.ko
|
||||
cd -
|
||||
|
||||
cp -a aa/dm_patch_ibt.ko ./
|
||||
|
||||
rm -rf ./aa
|
||||
|
||||
|
||||
curl -s -T dm_patch.ko -u $FTPUSR ftp://$FTPIP/dm_patch_64.ko || exit 1
|
||||
curl -s -T dm_patch_ibt.ko -u $FTPUSR ftp://$FTPIP/dm_patch_ibt_64.ko || exit 1
|
||||
|
||||
|
||||
if [ -f ./dm_patch.ko -a -f ./dm_patch_ibt.ko ]; then
|
||||
echo -e "\n\n=============== SUCCESS =============\n\n"
|
||||
else
|
||||
echo -e "\n\n=============== FAILED ==============\n\n"
|
||||
fi
|
||||
|
@ -1,70 +1,31 @@
|
||||
Build a static linked, small dmsetup tool
|
||||
|
||||
======== Source Code ========
|
||||
use an old version of dmsetup
|
||||
http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm
|
||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz
|
||||
|
||||
======== Build Environment ========
|
||||
build for 32bit, static linked with dietlibc
|
||||
1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso
|
||||
2. yum install gcc kernel-devel package
|
||||
3. install dietc libc (just make && make install)
|
||||
4. export PATH=$PATH:/opt/diet/bin
|
||||
|
||||
======== Build Step ========
|
||||
1. extract device mapper source code
|
||||
2. CC="diet gcc" ./configure --disable-nls --disable-selinux --disable-shared
|
||||
3. modify include/configure.h file
|
||||
--- delete the line with "#define malloc rpl_malloc"
|
||||
--- add 2 defines as follow:
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef UINT64_C
|
||||
#define UINT64_C(c) c ## ULL
|
||||
#endif
|
||||
|
||||
4. make
|
||||
5. strip dmsetup/dmsetup
|
||||
6. get dmsetup/dmsetup as the dmsetup32 binary file
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
======================== Build for 64bit dmsetup =========================
|
||||
1. extract device mapper source code
|
||||
2. ./configure --disable-nls --disable-selinux --disable-shared --enable-static_link CC='gcc -specs /usr/local/musl/lib/musl-gcc.specs'
|
||||
3. touch include/linux/limits.h include/linux/types.h
|
||||
echo '#include <sys/mount.h>' > include/linux/fs.h
|
||||
4. make
|
||||
5. strip --strip-all dmsetup/dmsetup.static
|
||||
6. get dmsetup/dmsetup.static as the dmsetup64 binary file
|
||||
|
||||
|
||||
======================== Build for arm64 dmsetup =========================
|
||||
1. extract device mapper source code
|
||||
2. ./configure CC=aarch64-linux-gcc --target=arm --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link
|
||||
3. modify include/configure.h file
|
||||
--- delete the line with "#define malloc rpl_malloc"
|
||||
4. make
|
||||
5. aarch64-linux-strip dmsetup/dmsetup.static
|
||||
6. get dmsetup/dmsetup.static as the dmsetupaa64 binary file
|
||||
|
||||
|
||||
======================== Build for mips64 dmsetup =========================
|
||||
1. extract device mapper source code
|
||||
2. ./configure CC="mips64el-linux-musl-gcc -mips64r2 -mabi=64" --target=mips --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link
|
||||
3. modify include/configure.h file
|
||||
--- delete the line with "#define malloc rpl_malloc"
|
||||
4. make
|
||||
5. mips64el-linux-musl-strip dmsetup/dmsetup.static
|
||||
6. get dmsetup/dmsetup.static as the dmsetupm64e binary file
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Build a static linked, small dmsetup tool
|
||||
|
||||
======== Source Code ========
|
||||
use an old version of dmsetup
|
||||
http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm
|
||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz
|
||||
|
||||
======== Build Envrioment ========
|
||||
build for 32bit, static linked with dietlibc
|
||||
1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso
|
||||
2. yum install gcc kernel-devel package
|
||||
3. install dietc libc (just make && make install)
|
||||
4. export PATH=$PATH:/opt/diet/bin
|
||||
|
||||
======== Build Step ========
|
||||
1. extract device mapper source code
|
||||
2. CC="diet gcc" ./configure --disable-nls --disable-selinux --disable-shared
|
||||
3. modify include/configure.h file
|
||||
--- delete the line with "#define malloc rpl_malloc"
|
||||
--- add 2 defines as follow:
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef UINT64_C
|
||||
#define UINT64_C(c) c ## ULL
|
||||
#endif
|
||||
|
||||
4. make
|
||||
5. strip dmsetup/dmsetup
|
||||
5. get dmsetup/dmsetup as the binary file
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,276 +1,203 @@
|
||||
|
||||
==========================================
|
||||
1. Compile Environment
|
||||
==========================================
|
||||
My build environment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch.
|
||||
Ventoy is based on many open source projects, so the build environment is important. I suggest you first test it on a virtual machine.
|
||||
|
||||
1.1 Install CentOS 7.8
|
||||
I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install
|
||||
|
||||
1.2 Install Packages
|
||||
yum install \
|
||||
libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \
|
||||
mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \
|
||||
flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \
|
||||
libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \
|
||||
iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
2. Download Source Code
|
||||
==========================================
|
||||
2.1 Download Ventoy source code from GitHub and decompress it.
|
||||
Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory layout).
|
||||
|
||||
2.2 Download third-party source code and tool
|
||||
|
||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz
|
||||
https://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz
|
||||
https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz ===> /home/Ventoy-master/GRUB2/grub-2.04.tar.xz
|
||||
https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 ===> /home/Ventoy-master/EDK2/edk2-edk2-stable201911.zip
|
||||
https://codeload.github.com/relan/exfat/zip/v1.3.0 ===> /home/Ventoy-master/ExFAT/exfat-1.3.0.zip
|
||||
https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip
|
||||
https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
|
||||
https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2
|
||||
https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz
|
||||
https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2
|
||||
|
||||
|
||||
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/vmlinuz64 ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/vmlinuz64
|
||||
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz
|
||||
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz
|
||||
|
||||
2.3 Prepare third-party tools
|
||||
cd /home/Ventoy-master/DOC/
|
||||
tar xf musl-1.2.1.tar.gz
|
||||
cd musl-1.2.1
|
||||
./configure && make install
|
||||
|
||||
tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt
|
||||
tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt
|
||||
tar xf /opt/output.tar.bz2 -C /opt
|
||||
mv /opt/output /opt/mips64el-linux-musl-gcc730
|
||||
|
||||
|
||||
2.4 Set PATH environment
|
||||
export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin
|
||||
better to add this line to /root/.bashrc and relogin as root
|
||||
|
||||
|
||||
==========================================
|
||||
3. All in one script
|
||||
==========================================
|
||||
I have made an all-in-one script `all_in_one.sh`. You can run this script to build and pack ventoy.
|
||||
If you want to compile a certain part separately, you can continue to refer to the later chapters of this text.
|
||||
|
||||
cd /home/Ventoy-master/INSTALL
|
||||
sh all_in_one.sh
|
||||
|
||||
It should be noted that:
|
||||
1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other parts contain binaries and are rarely modified, so will not be recompiled everytime.
|
||||
You can rebuild these parts separately if you want.
|
||||
|
||||
2. Some parts of Ventoy have a 32-bit and 64-bit version (like 4.9, 4.10, 4.11 follows)
|
||||
all_in_one.sh only builds the 64bit version of them. If you want to rebuild the 32bit verison, you should create a 32-bit CentOS environment and build them.
|
||||
Fortunately these parts are rarely modified, so you only need to build once or you can directly use the binaries I have built.
|
||||
|
||||
Besides, after a full compile and packaging, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package.
|
||||
|
||||
==========================================
|
||||
4. Build every part of Ventoy
|
||||
==========================================
|
||||
4.1 == Build grub2 ==
|
||||
cd /home/Ventoy-master/GRUB2
|
||||
sh buildgrub.sh
|
||||
|
||||
4.2 == Build ipxe.krn ==
|
||||
cd /home/Ventoy-master/IPXE
|
||||
sh buildipxe.sh
|
||||
|
||||
4.3 == Build Ventoy2Disk.exe ==
|
||||
Ventoy2Disk.exe is the installer in Windows platform. And it must be built in Windows with Microsoft Visual Studio (2013+).
|
||||
Open /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk.sln with Visual Studio and build it.
|
||||
|
||||
4.4 == Build vtoyjump64.exe/vtoyjump32.exe ==
|
||||
vtoyjump64.exe/vtoyjump32.exe is used to mount iso file in windows PE. You should install Microsoft Visual Studio (2013+) to build it.
|
||||
Open /home/Ventoy-master/vtoyjump/vtoyjump.sln with Visual Studio and build it (64&32).
|
||||
|
||||
4.5 == Build dmsetup ==
|
||||
Please refer to DMSETUP/build.txt
|
||||
|
||||
4.6 == Build ventoy_x64.efi ==
|
||||
cd /home/Ventoy-master/EDK2
|
||||
sh buildedk.sh
|
||||
|
||||
4.7 == Build VtoyTool ==
|
||||
cd /home/Ventoy-master/VtoyTool
|
||||
sh build.sh
|
||||
|
||||
4.8 == Build vtoycli ==
|
||||
cd /home/Ventoy-master/vtoycli/fat_io_lib
|
||||
sh buildlib.sh
|
||||
cd /home/Ventoy-master/vtoycli
|
||||
sh build.sh
|
||||
|
||||
4.9 == Build exfat-util ==
|
||||
cd /home/Ventoy-master/ExFAT
|
||||
sh buidlibfuse.sh
|
||||
sh buidexfat.sh
|
||||
|
||||
After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64
|
||||
After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64
|
||||
|
||||
Use the same build step to build exfat-util 32-bit in a 32-bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32
|
||||
|
||||
4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 ==
|
||||
cd /home/Ventoy-master/FUSEISO
|
||||
sh build_libfuse.sh
|
||||
sh build.sh
|
||||
|
||||
Use the same build step to build in a 32-bit CentOS system and get vtoy_fuse_iso_32
|
||||
|
||||
4.11 == Build unsquashfs_64/unsquashfs_32 ==
|
||||
cd /home/Ventoy-master/SQUASHFS/SRC
|
||||
sh build_lz4.sh
|
||||
sh build_lzma.sh
|
||||
sh build_lzo.sh
|
||||
sh build_zstd.sh
|
||||
|
||||
cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools
|
||||
sh build.sh
|
||||
|
||||
Use the same build step to build in a 32-bit CentOS system and get unsquashfs_32
|
||||
|
||||
4.12 == Build vblade_64/vblade_32 ==
|
||||
cd /home/Ventoy-master/VBLADE/vblade-master
|
||||
sh build.sh
|
||||
|
||||
4.13 == Build zstdcat ==
|
||||
Please refer to ZSTD/build.txt
|
||||
|
||||
4.14 == Build vtoy_gen_uuid ==
|
||||
cd /home/Ventoy-master/GenUUID
|
||||
sh build.sh
|
||||
|
||||
4.15 == Build xzminidec32 ==
|
||||
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||
make -f ventoy_makefile
|
||||
strip --strip-all xzminidec
|
||||
|
||||
4.16 == Build xzminidec64/xzminidec64_musl ==
|
||||
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||
make -f ventoy_makefile64 or make -f ventoy_makefile64_musl
|
||||
strip --strip-all xzminidec
|
||||
|
||||
4.17 == Build iso9660_x64.efi/udf_x64.efi/iso9660_ia32.efi/udf_ia32.efi/iso9660_aa64.efi/udf_aa64.efi/ ==
|
||||
This efi driver is from https://github.com/pbatard/efifs
|
||||
Follow all the build instructions in this project. I modified 3 files (the original and modified source are at /home/Ventoy-master/EDK2/efiffs)
|
||||
|
||||
4.18 IMG/cpio/ventoy/busybox/64h
|
||||
https://www.uclibc.org/downloads/binaries/0.9.30.1/mini-native-x86_64.tar.bz2
|
||||
https://busybox.net/downloads/busybox-1.32.0.tar.bz2
|
||||
use BUSYBOX/x86_64_ash.config and uclibc to build busybox-1.32
|
||||
|
||||
4.19 == Build lunzip32/lunzip64 ==
|
||||
http://mirror.yongbok.net/nongnu/lzip/lunzip/lunzip-1.11.tar.gz
|
||||
PATH=$PATH:/opt/diet/bin
|
||||
./configure --disable-nls CC='diet gcc -nostdinc'
|
||||
make
|
||||
strip --strip-all lunzip
|
||||
|
||||
#aarch64
|
||||
./configure --disable-nls CC='aarch64-buildroot-linux-uclibc-gcc -static'
|
||||
make
|
||||
aarch64-buildroot-linux-uclibc-strip --strip-all lunzip
|
||||
|
||||
4.17 == Build xzminidecaa64 ==
|
||||
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||
make -f ventoy_makefileaa64
|
||||
strip --strip-all xzminidec
|
||||
|
||||
4.18 == Build xzminidecm64e ==
|
||||
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||
make -f ventoy_makefilem64e
|
||||
strip --strip-all xzminidec
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
5. Binaries
|
||||
==========================================
|
||||
There some binaries in Ventoy install package. These files are downloaded from other open source project's website, such as busybox.
|
||||
Here is the list of the binaries, their SHA-256 and the download urls:
|
||||
|
||||
5.1 IMG/cpio/ventoy/tool/lz4cat
|
||||
https://create.stephan-brumme.com/smallz4 smallz4cat-x32-v1.4
|
||||
SHA-256: 13d293ddeedb469f51da41167f79b2cbdb904e681716f6e6191b233dbb162438
|
||||
|
||||
5.2 IMG/cpio/ventoy/tool/ar
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_AR
|
||||
SHA-256: f29b7d81a983c0c85d22496f4a833c18f2528a1b666eb7d47c93084c1ed66ae0
|
||||
|
||||
5.3 IMG/cpio/ventoy/tool/inotifyd
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD
|
||||
SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f
|
||||
|
||||
5.4 IMG/cpio/ventoy/busybox/ash
|
||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH
|
||||
SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97
|
||||
|
||||
5.5 IMG/cpio/ventoy/busybox/tmpxz
|
||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ
|
||||
SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291
|
||||
|
||||
5.6 INSTALL/tool/i386/xzcat
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT
|
||||
SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44
|
||||
|
||||
5.7 INSTALL/tool/i386/hexdump
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP
|
||||
SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af
|
||||
|
||||
5.8 imdisk
|
||||
download http://www.ltr-data.se/files/imdiskinst.exe and extract it by 7zip.
|
||||
|
||||
INSTALL/ventoy/imdisk/64/imdisk.sys --> sys/amd64/imdisk.sys SHA-256: 6702202220268787e361f5a82dae53362c8e6c6dcd240bb01b44dd77ae0788da
|
||||
INSTALL/ventoy/imdisk/64/imdisk.exe --> cli/amd64/imdisk.exe SHA-256: 9759175380af836869443e5f21ce2e33022125d154bc6b3d1c04dc36b190de04
|
||||
INSTALL/ventoy/imdisk/64/imdisk.cpl --> cpl/amd64/imdisk.cpl SHA-256: aea2ebbea2b073c947263744962af8a3eab025ff4c9d825c543e380e738a4c99
|
||||
|
||||
INSTALL/ventoy/imdisk/32/imdisk.sys --> sys/i386/imdisk.sys SHA-256: a94caec2f71a924d6a914c093ad4b905d7cfdea3f515ed48aaa8c3950b2dc191
|
||||
INSTALL/ventoy/imdisk/32/imdisk.exe --> cli/i386/imdisk.exe SHA-256: 33b53858e2139704cf603b115a3e5e1dfd4daeaaed4d3e03c633f2df3b55dbaa
|
||||
INSTALL/ventoy/imdisk/32/imdisk.cpl --> cpl/i386/imdisk.cpl SHA-256: b781d3e2d286ac8bf548f44e50cbbb3fe78203296e41e4d2e73b407668f88f2d
|
||||
|
||||
5.9 INSTALL/ventoy/memdisk
|
||||
https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz
|
||||
decompress it and memdisk is at syslinux-6.03/bios/memdisk/memdisk
|
||||
SHA-256: 3f6cd656b8a14109cd3f906fee2dd2e75418f983a5e1bfdb64f44f7765588cbb
|
||||
|
||||
|
||||
5.10 UEFIinSecureBoot
|
||||
https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk/releases Super-UEFIinSecureBoot-Disk_minimal_v3.zip
|
||||
unzip it and get Super-UEFIinSecureBoot-Disk_minimal.img, extract the img by 7zip.
|
||||
|
||||
INSTALL/EFI/BOOT/BOOTX64.EFI --> EFI/BOOT/BOOTX64.EFI SHA-256: 475552c7476ad45e42344eee8b30d44c264d200ac2468428aa86fc8795fb6e34
|
||||
INSTALL/EFI/BOOT/grubx64.efi --> EFI/BOOT/grubx64.efi SHA-256: 25d858157349dc52fa70f3cdf5c62fe1e0bae37ddfc3a6b6528af9a3c745775f
|
||||
INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b
|
||||
|
||||
|
||||
5.11 INSTALL/tool/ash
|
||||
https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH
|
||||
SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b
|
||||
|
||||
5.12 7za.exe
|
||||
download from https://www.7-zip.org/a/7z1900-extra.7z
|
||||
ISNTALL/ventoy/7z/64/7za.exe SHA-256: 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549
|
||||
ISNTALL/ventoy/7z/32/7za.exe SHA-256: ea308c76a2f927b160a143d94072b0dce232e04b751f0c6432a94e05164e716d
|
||||
|
||||
5.13 ./Ventoy/Unix/ventoy_unix/DragonFly/sbin/dmsetup
|
||||
download from https://cdimage.debian.org/mirror/dragonflybsd.org/iso-images/dfly-x86_64-5.8.3_REL.iso.bz2
|
||||
extract from the ISO file sbin/dmsetup
|
||||
dmsetup SHA-256: bedcf26650e87edfe961e33bae20d832bce73efd4b6239f9a6a5785661e4e698
|
||||
|
||||
5.14 ./LiveCD/ISO/EFI/boot/vmlinuz64
|
||||
download from http://www.tinycorelinux.net/11.x/x86_64/archive/11.0/distribution_files/vmlinuz64
|
||||
vmlinuz64 SHA-256: 641077fc1f9914af244c248453005f56536ba9e7f54ba3e52402f26709ddb8a5
|
||||
|
||||
==========================================
|
||||
1. Compile Enviroment
|
||||
==========================================
|
||||
My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch.
|
||||
Because Ventoy is based on many open source projects, so the envrioment is important. I suggest you test it on a virtual machine first.
|
||||
|
||||
1.1 Install CentOS 7.8
|
||||
I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install
|
||||
|
||||
1.2 Install Packages
|
||||
yum install \
|
||||
libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \
|
||||
mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \
|
||||
flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \
|
||||
libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \
|
||||
iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
2. Download Source Code
|
||||
==========================================
|
||||
2.1 Download Ventoy source code from github and decompress it.
|
||||
Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory level).
|
||||
|
||||
2.2 Download third-part source code
|
||||
|
||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz
|
||||
https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz ===> /home/Ventoy-master/GRUB2/grub-2.04.tar.xz
|
||||
https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 ===> /home/Ventoy-master/EDK2/edk2-edk2-stable201911.zip
|
||||
https://codeload.github.com/relan/exfat/zip/v1.3.0 ===> /home/Ventoy-master/ExFAT/exfat-1.3.0.zip
|
||||
https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip
|
||||
http://ultra-embedded.com/releases/fat_io_lib.zip ===> /home/Ventoy-master/vtoyfat/fat_io_lib/fat_io_lib.zip
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
3. All in one script
|
||||
==========================================
|
||||
I have made the whole build process in all_in_one.sh, you can run this script to build and pack ventoy.
|
||||
If you want to compile a certain part separately, you can continue to refer to the later chapters of this text.
|
||||
|
||||
cd /home/Ventoy-master/INSTALL
|
||||
sh all_in_one.sh
|
||||
|
||||
It should be noted that, some part of Ventoy has 32bit&64bit version (like 4.9 4.10 4.11 follows)
|
||||
all_in_one.sh only build 64bit version of them, if you want to rebuild the 32bit verison. You should create a 32bit CentOS environment and build them.
|
||||
Fortunately these parts are few modified, you only need to build once or you can directly use the binary I have built.
|
||||
|
||||
Besides, after a fully compile and pack, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package.
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
4. Build every part of Ventoy
|
||||
==========================================
|
||||
4.1 == Build grub2 ==
|
||||
cd /home/Ventoy-master/GRUB2
|
||||
sh buildgrub.sh
|
||||
|
||||
4.2 == Build ipxe.krn ==
|
||||
cd /home/Ventoy-master/IPXE
|
||||
sh buildipxe.sh
|
||||
|
||||
4.3 == Build Ventoy2Disk.exe ==
|
||||
Ventoy2Disk.exe is the installer in Windows platform. And it must be built in Windows with Microsoft Visual Studio (2013+).
|
||||
Open /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk.sln with Visual Studio and build it.
|
||||
|
||||
4.4 == Build vtoyjump64.exe/vtoyjump32.exe ==
|
||||
vtoyjump64.exe/vtoyjump32.exe is used to mount iso file in windows PE. You should install Microsoft Visual Studio (2013+) to build it.
|
||||
Open /home/Ventoy-master/vtoyjump/vtoyjump.sln with Visual Studio and build it (64&32).
|
||||
|
||||
4.5 == Build dmsetup ==
|
||||
Please refer to DMSETUP/build.txt
|
||||
|
||||
4.6 == Build ventoy_x64.efi ==
|
||||
cd /home/Ventoy-master/EDK2
|
||||
sh buildedk.sh
|
||||
|
||||
4.7 == Build VtoyTool ==
|
||||
cd /home/Ventoy-master/VtoyTool
|
||||
sh build.sh
|
||||
|
||||
4.8 == Build vtoyfat ==
|
||||
cd /home/Ventoy-master/vtoyfat/fat_io_lib
|
||||
sh buildlib.sh
|
||||
cd /home/Ventoy-master/vtoyfat
|
||||
sh build.sh
|
||||
|
||||
4.9 == Build exfat-util ==
|
||||
cd /home/Ventoy-master/ExFAT
|
||||
sh buidlibfuse.sh
|
||||
sh buidexfat.sh
|
||||
|
||||
After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64
|
||||
After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64
|
||||
|
||||
Use the same build step to build exfat-util 32bit in a 32bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32
|
||||
|
||||
4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 ==
|
||||
cd /home/Ventoy-master/FUSEISO
|
||||
sh build_libfuse.sh
|
||||
sh build.sh
|
||||
|
||||
Use the same build step to build in a 32bit CentOS system and get vtoy_fuse_iso_32
|
||||
|
||||
4.11 == Build unsquashfs_64/unsquashfs_32 ==
|
||||
cd /home/Ventoy-master/SQUASHFS/SRC
|
||||
sh build_lz4.sh
|
||||
sh build_lzma.sh
|
||||
sh build_lzo.sh
|
||||
sh build_zstd.sh
|
||||
|
||||
cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools
|
||||
sh build.sh
|
||||
|
||||
Use the same build step to build in a 32bit CentOS system and get unsquashfs_32
|
||||
|
||||
4.12 == Build vblade_64/vblade_32 ==
|
||||
cd /home/Ventoy-master/VBLADE/vblade-master
|
||||
sh build.sh
|
||||
|
||||
4.13 == Build zstdcat ==
|
||||
Please refer to ZSTD/build.txt
|
||||
|
||||
4.14 == Build vtoy_gen_uuid ==
|
||||
cd /home/Ventoy-master/GenUUID
|
||||
sh build.sh
|
||||
|
||||
4.15 == Build xzminidec ==
|
||||
cd /home/Ventoy-master/xz-embedded-20130513/userspace
|
||||
make -f ventoy_makefile
|
||||
strip --strip-all xzminidec
|
||||
|
||||
4.16 == Build iso9660_x64.efi ==
|
||||
This efi driver is from https://github.com/pbatard/efifs
|
||||
Follow all the build instructions in this project. I modified 3 files (the original and modified source are at /home/Ventoy-master/EDK2/efiffs)
|
||||
|
||||
|
||||
|
||||
==========================================
|
||||
5. Binaries
|
||||
==========================================
|
||||
There some binaries in Ventoy install package. These files are downloaded from other open source project's website, such as busybox.
|
||||
Here is the list of the binaries, their SHA-256 and the download urls:
|
||||
|
||||
5.1 IMG/cpio/ventoy/tool/lz4cat
|
||||
https://create.stephan-brumme.com/smallz4 smallz4cat-x32-v1.4
|
||||
SHA-256: 13d293ddeedb469f51da41167f79b2cbdb904e681716f6e6191b233dbb162438
|
||||
|
||||
5.2 IMG/cpio/ventoy/tool/ar
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_AR
|
||||
SHA-256: f29b7d81a983c0c85d22496f4a833c18f2528a1b666eb7d47c93084c1ed66ae0
|
||||
|
||||
5.3 IMG/cpio/ventoy/tool/inotifyd
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD
|
||||
SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f
|
||||
|
||||
5.4 IMG/cpio/ventoy/busybox/tmpsh
|
||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH
|
||||
SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97
|
||||
|
||||
5.5 IMG/cpio/ventoy/busybox/tmpxz
|
||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ
|
||||
SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291
|
||||
|
||||
5.6 INSTALL/tool/xzcat
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT
|
||||
SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44
|
||||
|
||||
5.7 INSTALL/tool/hexdump
|
||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP
|
||||
SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af
|
||||
|
||||
5.8 imdisk
|
||||
download http://www.ltr-data.se/files/imdiskinst.exe and extract it by 7zip.
|
||||
|
||||
INSTALL/ventoy/imdisk/64/imdisk.sys --> sys/amd64/imdisk.sys SHA-256: 6702202220268787e361f5a82dae53362c8e6c6dcd240bb01b44dd77ae0788da
|
||||
INSTALL/ventoy/imdisk/64/imdisk.exe --> cli/amd64/imdisk.exe SHA-256: 9759175380af836869443e5f21ce2e33022125d154bc6b3d1c04dc36b190de04
|
||||
INSTALL/ventoy/imdisk/64/imdisk.cpl --> cpl/amd64/imdisk.cpl SHA-256: aea2ebbea2b073c947263744962af8a3eab025ff4c9d825c543e380e738a4c99
|
||||
|
||||
INSTALL/ventoy/imdisk/32/imdisk.sys --> sys/i386/imdisk.sys SHA-256: a94caec2f71a924d6a914c093ad4b905d7cfdea3f515ed48aaa8c3950b2dc191
|
||||
INSTALL/ventoy/imdisk/32/imdisk.exe --> cli/i386/imdisk.exe SHA-256: 33b53858e2139704cf603b115a3e5e1dfd4daeaaed4d3e03c633f2df3b55dbaa
|
||||
INSTALL/ventoy/imdisk/32/imdisk.cpl --> cpl/i386/imdisk.cpl SHA-256: b781d3e2d286ac8bf548f44e50cbbb3fe78203296e41e4d2e73b407668f88f2d
|
||||
|
||||
5.9 INSTALL/ventoy/memdisk
|
||||
https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz
|
||||
decompress it and memdisk is at syslinux-6.03/bios/memdisk/memdisk
|
||||
SHA-256: 3f6cd656b8a14109cd3f906fee2dd2e75418f983a5e1bfdb64f44f7765588cbb
|
||||
|
||||
|
||||
5.10 UEFIinSecureBoot
|
||||
https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk/releases Super-UEFIinSecureBoot-Disk_minimal_v3.zip
|
||||
unzip it and get Super-UEFIinSecureBoot-Disk_minimal.img, extract the img by 7zip.
|
||||
|
||||
INSTALL/EFI/BOOT/BOOTX64.EFI --> EFI/BOOT/BOOTX64.EFI SHA-256: 475552c7476ad45e42344eee8b30d44c264d200ac2468428aa86fc8795fb6e34
|
||||
INSTALL/EFI/BOOT/grubx64.efi --> EFI/BOOT/grubx64.efi SHA-256: 25d858157349dc52fa70f3cdf5c62fe1e0bae37ddfc3a6b6528af9a3c745775f
|
||||
INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
|
||||
1. LAKKA dm-mod.ko
|
||||
LaKKa config
|
||||
https://github.com/libretro/Lakka-LibreELEC/releases download source code
|
||||
\projects\Generic\linux\linux.x86_64.conf
|
||||
|
||||
Linux Kernel
|
||||
linux-4.11.12.tar.xz & patch-4.11.12-rt14.patch.xz
|
||||
patch -p1 < ../patch-4.11.12-rt14
|
||||
|
||||
make menuconfig
|
||||
select device mapper as module
|
||||
make -j 16
|
||||
get drivers\md\dm-mod.ko
|
||||
|
||||
2. LibreELEC dm-mod.ko
|
||||
LibreELEC config
|
||||
https://github.com/LibreELEC/LibreELEC.tv/releases download source code
|
||||
\projects\Generic\linux\linux.x86_64.conf
|
||||
|
||||
Linux Kernel
|
||||
linux-5.1.6.tar.xz
|
||||
make menuconfig
|
||||
select device mapper as module
|
||||
make -j 16
|
||||
get drivers\md\dm-mod.ko
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#[ -d /opt/diet64 ] || sh ./installdietlibc.sh
|
||||
|
||||
[ -d /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu ] || tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt
|
||||
|
||||
[ -d /opt/aarch64--uclibc--stable-2020.08-1 ] || tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt
|
||||
|
||||
[ -d /opt/mips-loongson-gcc7.3-linux-gnu ] || tar xf /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz -C /opt
|
15
Dockerfile
15
Dockerfile
@ -1,15 +0,0 @@
|
||||
FROM centos:7
|
||||
|
||||
RUN sed -i \
|
||||
-e 's/^mirrorlist/#mirrorlist/' \
|
||||
-e 's/^#baseurl/baseurl/' \
|
||||
-e 's/mirror\.centos\.org/vault.centos.org/' \
|
||||
/etc/yum.repos.d/*.repo && \
|
||||
yum -y -q install \
|
||||
libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \
|
||||
mpfr.i686 mpfr-devel.i686 rsync autogen autoconf automake libtool gettext* bison binutils \
|
||||
flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \
|
||||
libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \
|
||||
iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso lz4 squashfs-tools
|
||||
|
||||
CMD cd /ventoy/INSTALL && ls -la && sh docker_ci_build.sh
|
@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
EDKARCH=X64
|
||||
postfix=x64
|
||||
elif [ "$1" = "ia32" ]; then
|
||||
EDKARCH=IA32
|
||||
postfix=ia32
|
||||
shift
|
||||
elif [ "$1" = "aa64" ]; then
|
||||
EDKARCH=AARCH64
|
||||
postfix=aa64
|
||||
shift
|
||||
fi
|
||||
|
||||
cd edk2-edk2-stable201911
|
||||
|
||||
rm -rf ./Conf/.cache
|
||||
rm -f ./Conf/.AutoGenIdFile.txt
|
||||
|
||||
VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/Ventoy/Ventoy/OUTPUT/Ventoy.efi
|
||||
DST_PATH=../../INSTALL/ventoy/ventoy_${postfix}.efi
|
||||
|
||||
VTEFI_PATH2=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VtoyUtil/VtoyUtil/OUTPUT/VtoyUtil.efi
|
||||
DST_PATH2=../../INSTALL/ventoy/vtoyutil_${postfix}.efi
|
||||
|
||||
VTEFI_PATH3=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VDiskChain/VDiskChain/OUTPUT/VDiskChain.efi
|
||||
DST_PATH3=../../VDiskChain/Tool/vdiskchain_${postfix}.efi
|
||||
|
||||
|
||||
rm -f $VTEFI_PATH
|
||||
rm -f $DST_PATH
|
||||
rm -f $VTEFI_PATH2
|
||||
rm -f $DST_PATH2
|
||||
rm -f $VTEFI_PATH3
|
||||
[ -d ../../VDiskChain ] && rm -f $DST_PATH3
|
||||
|
||||
unset WORKSPACE
|
||||
source ./edksetup.sh
|
||||
|
||||
if [ "$EDKARCH" = "AARCH64" ]; then
|
||||
GCC48_AARCH64_PREFIX=aarch64-linux-gnu- \
|
||||
build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48
|
||||
else
|
||||
build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48
|
||||
fi
|
||||
|
||||
if [ -e $VTEFI_PATH ] && [ -e $VTEFI_PATH2 ] && [ -e $VTEFI_PATH3 ]; then
|
||||
echo -e '\n\n====================== SUCCESS ========================\n\n'
|
||||
cp -a $VTEFI_PATH $DST_PATH
|
||||
cp -a $VTEFI_PATH2 $DST_PATH2
|
||||
[ -d ../../VDiskChain ] && cp -a $VTEFI_PATH3 $DST_PATH3
|
||||
cd ..
|
||||
else
|
||||
echo -e '\n\n====================== FAILED ========================\n\n'
|
||||
cd ..
|
||||
exit 1
|
||||
fi
|
||||
|
@ -2,20 +2,32 @@
|
||||
|
||||
rm -rf edk2-edk2-stable201911
|
||||
|
||||
unzip edk2-edk2-stable201911.zip > /dev/null
|
||||
unzip edk2-edk2-stable201911.zip
|
||||
|
||||
/bin/cp -a ./edk2_mod/edk2-edk2-stable201911 ./
|
||||
|
||||
cd edk2-edk2-stable201911
|
||||
|
||||
VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/X64/MdeModulePkg/Application/Ventoy/Ventoy/OUTPUT/Ventoy.efi
|
||||
DST_PATH=../../INSTALL/ventoy/ventoy_x64.efi
|
||||
|
||||
rm -f $VTEFI_PATH
|
||||
rm -f $DST_PATH
|
||||
|
||||
make -j 4 -C BaseTools/
|
||||
cd ..
|
||||
|
||||
echo '======== build EDK2 for i386-efi ==============='
|
||||
sh ./build.sh ia32 || exit 1
|
||||
source ./edksetup.sh
|
||||
build -p MdeModulePkg/MdeModulePkg.dsc -a X64 -b RELEASE -t GCC48
|
||||
|
||||
if [ -e $VTEFI_PATH ]; then
|
||||
echo -e '\n\n====================== SUCCESS ========================\n\n'
|
||||
cp -a $VTEFI_PATH $DST_PATH
|
||||
cd ..
|
||||
else
|
||||
echo -e '\n\n====================== FAILED ========================\n\n'
|
||||
cd ..
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo '======== build EDK2 for arm64-efi ==============='
|
||||
sh ./build.sh aa64 || exit 1
|
||||
|
||||
echo '======== build EDK2 for x86_64-efi ==============='
|
||||
sh ./build.sh || exit 1
|
||||
|
||||
|
@ -1,472 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VDiskChain.c
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Library/UefiDecompressLib.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <VDiskChain.h>
|
||||
|
||||
BOOLEAN gVDiskDebugPrint = FALSE;
|
||||
vdisk_block_data gVDiskBlockData;
|
||||
|
||||
/* Boot filename */
|
||||
CONST CHAR16 *gEfiBootFileName[] =
|
||||
{
|
||||
L"@",
|
||||
EFI_REMOVABLE_MEDIA_FILE_NAME,
|
||||
#if defined (MDE_CPU_IA32)
|
||||
L"\\EFI\\BOOT\\GRUBIA32.EFI",
|
||||
L"\\EFI\\BOOT\\BOOTia32.EFI",
|
||||
L"\\EFI\\BOOT\\bootia32.efi",
|
||||
L"\\efi\\boot\\bootia32.efi",
|
||||
#elif defined (MDE_CPU_X64)
|
||||
L"\\EFI\\BOOT\\GRUBX64.EFI",
|
||||
L"\\EFI\\BOOT\\BOOTx64.EFI",
|
||||
L"\\EFI\\BOOT\\bootx64.efi",
|
||||
L"\\efi\\boot\\bootx64.efi",
|
||||
#elif defined (MDE_CPU_ARM)
|
||||
L"\\EFI\\BOOT\\GRUBARM.EFI",
|
||||
L"\\EFI\\BOOT\\BOOTarm.EFI",
|
||||
L"\\EFI\\BOOT\\bootarm.efi",
|
||||
L"\\efi\\boot\\bootarm.efi",
|
||||
#elif defined (MDE_CPU_AARCH64)
|
||||
L"\\EFI\\BOOT\\GRUBAA64.EFI",
|
||||
L"\\EFI\\BOOT\\BOOTaa64.EFI",
|
||||
L"\\EFI\\BOOT\\bootaa64.efi",
|
||||
L"\\efi\\boot\\bootaa64.efi",
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
UINT8 *g_disk_buf_addr = NULL;
|
||||
UINT64 g_disk_buf_size = 0;
|
||||
|
||||
STATIC EFI_GET_VARIABLE g_org_get_variable = NULL;
|
||||
STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL;
|
||||
|
||||
VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...)
|
||||
{
|
||||
VA_LIST Marker;
|
||||
CHAR16 Buffer[512];
|
||||
|
||||
VA_START (Marker, Format);
|
||||
UnicodeVSPrintAsciiFormat(Buffer, sizeof(Buffer), Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
gST->ConOut->OutputString(gST->ConOut, Buffer);
|
||||
}
|
||||
|
||||
VOID EFIAPI vdisk_clear_input(VOID)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||
while (EFI_SUCCESS == gST->ConIn->ReadKeyStroke(gST->ConIn, &Key))
|
||||
{
|
||||
;
|
||||
}
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI vdisk_load_image
|
||||
(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath,
|
||||
IN CONST CHAR16 *FileName,
|
||||
IN UINTN FileNameLen,
|
||||
OUT EFI_HANDLE *Image
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
CHAR16 TmpBuf[256] = {0};
|
||||
FILEPATH_DEVICE_PATH *pFilePath = NULL;
|
||||
EFI_DEVICE_PATH_PROTOCOL *pImgPath = NULL;
|
||||
|
||||
pFilePath = (FILEPATH_DEVICE_PATH *)TmpBuf;
|
||||
pFilePath->Header.Type = MEDIA_DEVICE_PATH;
|
||||
pFilePath->Header.SubType = MEDIA_FILEPATH_DP;
|
||||
pFilePath->Header.Length[0] = FileNameLen + sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
pFilePath->Header.Length[1] = 0;
|
||||
CopyMem(pFilePath->PathName, FileName, FileNameLen);
|
||||
|
||||
pImgPath = AppendDevicePathNode(pDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)pFilePath);
|
||||
if (!pImgPath)
|
||||
{
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Status = gBS->LoadImage(FALSE, ImageHandle, pImgPath, NULL, 0, Image);
|
||||
|
||||
debug("Load Image File %r DP: <%s>", Status, ConvertDevicePathToText(pImgPath, FALSE, FALSE));
|
||||
|
||||
FreePool(pImgPath);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI vdisk_decompress_vdisk(IN EFI_LOADED_IMAGE_PROTOCOL *pImageInfo)
|
||||
{
|
||||
UINT32 Size;
|
||||
UINT32 DestinationSize;
|
||||
UINT32 ScratchSize;
|
||||
UINT8 *buf;
|
||||
VOID *ScratchBuf;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
(VOID)pImageInfo;
|
||||
|
||||
vdisk_get_vdisk_raw(&buf, &Size);
|
||||
UefiDecompressGetInfo(buf + VDISK_MAGIC_LEN, Size - VDISK_MAGIC_LEN, &DestinationSize, &ScratchSize);
|
||||
debug("vdisk: size:%u realsize:%u", Size, DestinationSize);
|
||||
|
||||
g_disk_buf_size = DestinationSize;
|
||||
g_disk_buf_addr = AllocatePool(DestinationSize);
|
||||
ScratchBuf = AllocatePool(ScratchSize);
|
||||
|
||||
Status = UefiDecompress(buf + VDISK_MAGIC_LEN, g_disk_buf_addr, ScratchBuf);
|
||||
FreePool(ScratchBuf);
|
||||
|
||||
debug("Status:%r %p %u", Status, g_disk_buf_addr, (UINT32)g_disk_buf_size);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS vdisk_patch_vdisk_path(CHAR16 *pos)
|
||||
{
|
||||
UINTN i;
|
||||
UINTN j;
|
||||
CHAR16 *end;
|
||||
CHAR8 *buf = (char *)g_disk_buf_addr;
|
||||
|
||||
if (*pos == L'\"')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
end = StrStr(pos, L".vtoy");
|
||||
end += 5;//string length
|
||||
|
||||
for (i = 0; i < g_disk_buf_size; i++)
|
||||
{
|
||||
if (*(UINT32 *)(buf + i) == 0x59595959)
|
||||
{
|
||||
for (j = 0; j < 300; j++)
|
||||
{
|
||||
if (buf[i + j] != 'Y')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j >= 300)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= g_disk_buf_size)
|
||||
{
|
||||
debug("No need to fill vdisk path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("Fill vdisk path at %d", i);
|
||||
|
||||
while (pos != end)
|
||||
{
|
||||
buf[i++] = (CHAR8)(*pos++);
|
||||
}
|
||||
|
||||
buf[i++] = '\"';
|
||||
|
||||
while (buf[i] == 'Y' || buf[i] == '\"')
|
||||
{
|
||||
buf[i] = ' ';
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_get_variable_wrapper
|
||||
(
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
OUT UINT32 *Attributes, OPTIONAL
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data);
|
||||
if (StrCmp(VariableName, L"SecureBoot") == 0)
|
||||
{
|
||||
if ((*DataSize == 1) && Data)
|
||||
{
|
||||
*(UINT8 *)Data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_exit_boot_service_wrapper
|
||||
(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN UINTN MapKey
|
||||
)
|
||||
{
|
||||
if (g_org_get_variable)
|
||||
{
|
||||
gRT->GetVariable = g_org_get_variable;
|
||||
g_org_get_variable = NULL;
|
||||
}
|
||||
|
||||
return g_org_exit_boot_service(ImageHandle, MapKey);
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI vdisk_disable_secure_boot(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
/* step1: wrapper security protocol. */
|
||||
/* Do we still need it since we have been loaded ? */
|
||||
|
||||
|
||||
/* step2: fake SecureBoot variable */
|
||||
g_org_exit_boot_service = gBS->ExitBootServices;
|
||||
gBS->ExitBootServices = vdisk_exit_boot_service_wrapper;
|
||||
|
||||
g_org_get_variable = gRT->GetVariable;
|
||||
gRT->GetVariable = vdisk_get_variable_wrapper;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI vdisk_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
CHAR16 *Pos = NULL;
|
||||
CHAR16 *pCmdLine = NULL;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
|
||||
|
||||
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
VDiskDebug("Failed to handle load image protocol %r\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4);
|
||||
SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0);
|
||||
CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize);
|
||||
|
||||
if (StrStr(pCmdLine, L"debug"))
|
||||
{
|
||||
gVDiskDebugPrint = TRUE;
|
||||
}
|
||||
|
||||
debug("cmdline:<%s>", pCmdLine);
|
||||
vdisk_debug_pause();
|
||||
|
||||
Pos = StrStr(pCmdLine, L"vdisk=");
|
||||
if (NULL == Pos || NULL == StrStr(pCmdLine, L".vtoy"))
|
||||
{
|
||||
VDiskDebug("vdisk parameter not found!\n");
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
vdisk_decompress_vdisk(pImageInfo);
|
||||
|
||||
vdisk_patch_vdisk_path(Pos + 6);
|
||||
|
||||
if (StrStr(pCmdLine, L"secureboot=off"))
|
||||
{
|
||||
vdisk_disable_secure_boot(ImageHandle);
|
||||
}
|
||||
|
||||
FreePool(pCmdLine);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_boot(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
UINTN t = 0;
|
||||
UINTN i = 0;
|
||||
UINTN j = 0;
|
||||
UINTN Find = 0;
|
||||
UINTN Count = 0;
|
||||
EFI_HANDLE Image = NULL;
|
||||
EFI_HANDLE *Handles = NULL;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
|
||||
EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
|
||||
|
||||
for (t = 0; t < 3; t++)
|
||||
{
|
||||
Count = 0;
|
||||
Handles = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
debug("vdisk_boot fs count:%u", Count);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume);
|
||||
|
||||
Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&pDevPath,
|
||||
ImageHandle,
|
||||
Handles[i],
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
debug("Failed to open device path protocol %r", Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE));
|
||||
if (CompareMem(gVDiskBlockData.Path, pDevPath, gVDiskBlockData.DevicePathCompareLen))
|
||||
{
|
||||
debug("Not ventoy disk file system");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 1; j < ARRAY_SIZE(gEfiBootFileName); j++)
|
||||
{
|
||||
Status = vdisk_load_image(ImageHandle, pDevPath, gEfiBootFileName[j],
|
||||
StrSize(gEfiBootFileName[j]), &Image);
|
||||
if (EFI_SUCCESS == Status)
|
||||
{
|
||||
break;
|
||||
}
|
||||
debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]);
|
||||
}
|
||||
|
||||
if (j >= ARRAY_SIZE(gEfiBootFileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Find++;
|
||||
debug("Find boot file, now try to boot .....");
|
||||
vdisk_debug_pause();
|
||||
|
||||
if (gVDiskDebugPrint)
|
||||
{
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||
}
|
||||
|
||||
/* can't add debug print here */
|
||||
//ventoy_wrapper_system();
|
||||
Status = gBS->StartImage(Image, NULL, NULL);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
debug("Failed to start image %r", Status);
|
||||
sleep(3);
|
||||
gBS->UnloadImage(Image);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreePool(Handles);
|
||||
|
||||
if (Find == 0)
|
||||
{
|
||||
debug("Fs not found, now wait and retry...");
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (Find == 0)
|
||||
{
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI VDiskChainEfiMain
|
||||
(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
gST->ConOut->ClearScreen(gST->ConOut);
|
||||
vdisk_clear_input();
|
||||
|
||||
Status = vdisk_parse_cmdline(ImageHandle);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
vdisk_install_blockio(ImageHandle, g_disk_buf_size);
|
||||
vdisk_debug_pause();
|
||||
|
||||
Status = vdisk_boot(ImageHandle);
|
||||
|
||||
gBS->DisconnectController(gVDiskBlockData.Handle, NULL, NULL);
|
||||
gBS->UninstallMultipleProtocolInterfaces(gVDiskBlockData.Handle,
|
||||
&gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo,
|
||||
&gEfiDevicePathProtocolGuid, gVDiskBlockData.Path,
|
||||
NULL);
|
||||
|
||||
if (EFI_NOT_FOUND == Status)
|
||||
{
|
||||
gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
|
||||
gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
|
||||
sleep(30);
|
||||
}
|
||||
|
||||
vdisk_clear_input();
|
||||
gST->ConOut->ClearScreen(gST->ConOut);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -1,97 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VDiskChain.h
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __VENTOY_H__
|
||||
#define __VENTOY_H__
|
||||
|
||||
#define VDISK_MAGIC_LEN 32
|
||||
|
||||
#define VDISK_BLOCK_DEVICE_PATH_GUID \
|
||||
{ 0x6ed2134e, 0xc2ea, 0x4943, { 0x99, 0x54, 0xa7, 0x76, 0xe5, 0x9c, 0x12, 0xc3 }}
|
||||
|
||||
#define VDISK_BLOCK_DEVICE_PATH_NAME L"vdisk"
|
||||
|
||||
#if defined (MDE_CPU_IA32)
|
||||
#define VENTOY_UEFI_DESC L"IA32 UEFI"
|
||||
#elif defined (MDE_CPU_X64)
|
||||
#define VENTOY_UEFI_DESC L"X64 UEFI"
|
||||
#elif defined (MDE_CPU_EBC)
|
||||
#elif defined (MDE_CPU_ARM)
|
||||
#define VENTOY_UEFI_DESC L"ARM UEFI"
|
||||
#elif defined (MDE_CPU_AARCH64)
|
||||
#define VENTOY_UEFI_DESC L"ARM64 UEFI"
|
||||
#else
|
||||
#error Unknown Processor Type
|
||||
#endif
|
||||
|
||||
typedef struct vdisk_block_data
|
||||
{
|
||||
EFI_HANDLE Handle;
|
||||
EFI_BLOCK_IO_MEDIA Media; /* Media descriptor */
|
||||
EFI_BLOCK_IO_PROTOCOL BlockIo; /* Block I/O protocol */
|
||||
|
||||
UINTN DevicePathCompareLen;
|
||||
EFI_DEVICE_PATH_PROTOCOL *Path; /* Device path protocol */
|
||||
|
||||
EFI_HANDLE RawBlockIoHandle;
|
||||
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo;
|
||||
EFI_DEVICE_PATH_PROTOCOL *pDiskDevPath;
|
||||
|
||||
/* ventoy disk part2 ESP */
|
||||
EFI_HANDLE DiskFsHandle;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
|
||||
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
|
||||
|
||||
EFI_HANDLE IsoDriverImage;
|
||||
}vdisk_block_data;
|
||||
|
||||
|
||||
#define debug(expr, ...) if (gVDiskDebugPrint) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__)
|
||||
#define trace(expr, ...) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__)
|
||||
#define sleep(sec) gBS->Stall(1000000 * (sec))
|
||||
|
||||
#define vdisk_debug_pause() \
|
||||
if (gVDiskDebugPrint) \
|
||||
{ \
|
||||
UINTN __Index = 0; \
|
||||
gST->ConOut->OutputString(gST->ConOut, L"[VDISK] ###### Press Enter to continue... ######\r\n");\
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE); \
|
||||
gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\
|
||||
}
|
||||
|
||||
extern BOOLEAN gVDiskDebugPrint;
|
||||
VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...);
|
||||
EFI_STATUS EFIAPI vdisk_block_io_read
|
||||
(
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer
|
||||
);
|
||||
|
||||
extern UINT8 *g_disk_buf_addr;
|
||||
extern UINT64 g_disk_buf_size;
|
||||
extern vdisk_block_data gVDiskBlockData;
|
||||
EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize);
|
||||
int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size);
|
||||
|
||||
#endif
|
||||
|
@ -1,82 +0,0 @@
|
||||
#************************************************************************************
|
||||
# Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#************************************************************************************
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = VDiskChain
|
||||
FILE_GUID = 5bce96e3-ba11-4440-833b-299cf5849193
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = VDiskChainEfiMain
|
||||
|
||||
|
||||
[Sources]
|
||||
VDiskChain.h
|
||||
VDiskChain.c
|
||||
VDiskRawData.c
|
||||
VDiskChainProtocol.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiApplicationEntryPoint
|
||||
UefiLib
|
||||
DebugLib
|
||||
UefiDecompressLib
|
||||
|
||||
[Guids]
|
||||
gShellVariableGuid
|
||||
gEfiVirtualCdGuid
|
||||
gEfiFileInfoGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiBlockIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiSimpleFileSystemProtocolGuid
|
||||
gEfiRamDiskProtocolGuid
|
||||
gEfiAbsolutePointerProtocolGuid
|
||||
gEfiAcpiTableProtocolGuid
|
||||
gEfiBlockIo2ProtocolGuid
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid
|
||||
gEfiComponentNameProtocolGuid
|
||||
gEfiComponentName2ProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEfiDiskIoProtocolGuid
|
||||
gEfiDiskIo2ProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiHiiConfigAccessProtocolGuid
|
||||
gEfiHiiFontProtocolGuid
|
||||
gEfiLoadFileProtocolGuid
|
||||
gEfiLoadFile2ProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiLoadedImageDevicePathProtocolGuid
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextInputExProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,264 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VDiskChainProtocol.c
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <VDiskChain.h>
|
||||
|
||||
/* EFI block device vendor device path GUID */
|
||||
EFI_GUID gVDiskBlockDevicePathGuid = VDISK_BLOCK_DEVICE_PATH_GUID;
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_block_io_reset
|
||||
(
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)ExtendedVerification;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_block_io_read
|
||||
(
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)MediaId;
|
||||
|
||||
debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512);
|
||||
CopyMem(Buffer, g_disk_buf_addr + (Lba * 512), BufferSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_block_io_write
|
||||
(
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)MediaId;
|
||||
(VOID)Buffer;
|
||||
|
||||
debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512);
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_fill_device_path(VOID)
|
||||
{
|
||||
UINTN NameLen = 0;
|
||||
UINT8 TmpBuf[128] = {0};
|
||||
VENDOR_DEVICE_PATH *venPath = NULL;
|
||||
|
||||
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
|
||||
NameLen = StrSize(VDISK_BLOCK_DEVICE_PATH_NAME);
|
||||
venPath->Header.Type = HARDWARE_DEVICE_PATH;
|
||||
venPath->Header.SubType = HW_VENDOR_DP;
|
||||
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||
venPath->Header.Length[1] = 0;
|
||||
CopyMem(&venPath->Guid, &gVDiskBlockDevicePathGuid, sizeof(EFI_GUID));
|
||||
CopyMem(venPath + 1, VDISK_BLOCK_DEVICE_PATH_NAME, NameLen);
|
||||
|
||||
gVDiskBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
|
||||
gVDiskBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||
|
||||
debug("gVDiskBlockData.Path=<%s>\n", ConvertDevicePathToText(gVDiskBlockData.Path, FALSE, FALSE));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName)
|
||||
{
|
||||
UINTN i = 0;
|
||||
UINTN Count = 0;
|
||||
CHAR16 *DriverName = NULL;
|
||||
EFI_HANDLE *Handles = NULL;
|
||||
EFI_HANDLE DrvHandles[2] = { NULL };
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
|
||||
EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
|
||||
|
||||
debug("vdisk_connect_driver <%s>...", DrvName);
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName);
|
||||
if (EFI_ERROR(Status) || NULL == DriverName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrStr(DriverName, DrvName))
|
||||
{
|
||||
debug("Find driver name2:<%s>: <%s>", DriverName, DrvName);
|
||||
DrvHandles[0] = Handles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < Count)
|
||||
{
|
||||
Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
|
||||
debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status);
|
||||
goto end;
|
||||
}
|
||||
|
||||
debug("%s NOT found, now try COMPONENT_NAME", DrvName);
|
||||
|
||||
Count = 0;
|
||||
FreePool(Handles);
|
||||
Handles = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrStr(DriverName, DrvName))
|
||||
{
|
||||
debug("Find driver name:<%s>: <%s>", DriverName, DrvName);
|
||||
DrvHandles[0] = Handles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < Count)
|
||||
{
|
||||
Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
|
||||
debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status);
|
||||
goto end;
|
||||
}
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
end:
|
||||
FreePool(Handles);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gVDiskBlockData.BlockIo);
|
||||
|
||||
vdisk_fill_device_path();
|
||||
|
||||
debug("install block io protocol %p", ImageHandle);
|
||||
vdisk_debug_pause();
|
||||
|
||||
gVDiskBlockData.Media.BlockSize = 512;
|
||||
gVDiskBlockData.Media.LastBlock = ImgSize / 512 - 1;
|
||||
gVDiskBlockData.Media.ReadOnly = TRUE;
|
||||
gVDiskBlockData.Media.MediaPresent = 1;
|
||||
gVDiskBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
|
||||
|
||||
pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
|
||||
pBlockIo->Media = &(gVDiskBlockData.Media);
|
||||
pBlockIo->Reset = vdisk_block_io_reset;
|
||||
pBlockIo->ReadBlocks = vdisk_block_io_read;
|
||||
pBlockIo->WriteBlocks = vdisk_block_io_write;
|
||||
pBlockIo->FlushBlocks = vdisk_block_io_flush;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(&gVDiskBlockData.Handle,
|
||||
&gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo,
|
||||
&gEfiDevicePathProtocolGuid, gVDiskBlockData.Path,
|
||||
NULL);
|
||||
debug("Install protocol %r %p", Status, gVDiskBlockData.Handle);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Disk I/O Driver");
|
||||
debug("Connect disk IO driver %r", Status);
|
||||
|
||||
Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Partition Driver");
|
||||
debug("Connect partition driver %r", Status);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
Status = gBS->ConnectController(gVDiskBlockData.Handle, NULL, NULL, TRUE);
|
||||
debug("Connect all controller %r", Status);
|
||||
}
|
||||
|
||||
vdisk_debug_pause();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
#include <Uefi.h>
|
||||
int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size) { *buf = NULL; *size = 0; return 0; }
|
File diff suppressed because it is too large
Load Diff
@ -25,15 +25,6 @@
|
||||
|
||||
#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }}
|
||||
|
||||
typedef enum ventoy_chain_type
|
||||
{
|
||||
ventoy_chain_linux = 0, /* 0: linux */
|
||||
ventoy_chain_windows, /* 1: windows */
|
||||
ventoy_chain_wim, /* 2: wim */
|
||||
|
||||
ventoy_chain_max
|
||||
}ventoy_chain_type;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct ventoy_guid
|
||||
@ -98,9 +89,7 @@ typedef struct ventoy_os_param
|
||||
|
||||
UINT64 vtoy_reserved[4]; // Internal use by ventoy
|
||||
|
||||
UINT8 vtoy_disk_signature[4];
|
||||
|
||||
UINT8 reserved[27];
|
||||
UINT8 reserved[31];
|
||||
}ventoy_os_param;
|
||||
|
||||
#pragma pack()
|
||||
@ -170,32 +159,21 @@ typedef struct ventoy_virt_chunk
|
||||
#define VTOY_BLOCK_DEVICE_PATH_GUID \
|
||||
{ 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }}
|
||||
|
||||
|
||||
#define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy"
|
||||
|
||||
#if defined (MDE_CPU_IA32)
|
||||
#define VENTOY_UEFI_DESC L"IA32 UEFI"
|
||||
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_ia32.efi"
|
||||
#define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_ia32.efi"
|
||||
#elif defined (MDE_CPU_X64)
|
||||
#define VENTOY_UEFI_DESC L"X64 UEFI"
|
||||
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi"
|
||||
#define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_x64.efi"
|
||||
#elif defined (MDE_CPU_EBC)
|
||||
#elif defined (MDE_CPU_ARM)
|
||||
#define VENTOY_UEFI_DESC L"ARM UEFI"
|
||||
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_arm.efi"
|
||||
#define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_arm.efi"
|
||||
#elif defined (MDE_CPU_AARCH64)
|
||||
#define VENTOY_UEFI_DESC L"ARM64 UEFI"
|
||||
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_aa64.efi"
|
||||
#define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_aa64.efi"
|
||||
#else
|
||||
#error Unknown Processor Type
|
||||
#endif
|
||||
|
||||
#define VENTOY_DEVICE_WARN 1
|
||||
#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
||||
|
||||
typedef struct ventoy_sector_flag
|
||||
{
|
||||
UINT8 flag; // 0:init 1:mem 2:remap
|
||||
@ -224,6 +202,7 @@ typedef struct vtoy_block_data
|
||||
EFI_HANDLE IsoDriverImage;
|
||||
}vtoy_block_data;
|
||||
|
||||
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi"
|
||||
|
||||
#define debug(expr, ...) if (gDebugPrint) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
|
||||
#define trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
|
||||
@ -238,15 +217,11 @@ if (gDebugPrint) \
|
||||
gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\
|
||||
}
|
||||
|
||||
typedef int (*grub_env_set_pf)(const char *name, const char *val);
|
||||
typedef const char * (*grub_env_get_pf)(const char *name);
|
||||
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define VTOY_MAX_CONF_REPLACE 2
|
||||
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
|
||||
#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF
|
||||
|
||||
typedef struct ventoy_efi_file_replace
|
||||
{
|
||||
@ -269,10 +244,8 @@ typedef struct ventoy_grub_param_file_replace
|
||||
typedef struct ventoy_grub_param
|
||||
{
|
||||
grub_env_get_pf grub_env_get;
|
||||
grub_env_set_pf grub_env_set;
|
||||
|
||||
ventoy_grub_param_file_replace file_replace;
|
||||
ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
|
||||
grub_env_printf_pf grub_env_printf;
|
||||
}ventoy_grub_param;
|
||||
|
||||
typedef struct ventoy_ram_disk
|
||||
@ -281,40 +254,6 @@ typedef struct ventoy_ram_disk
|
||||
UINT64 DiskSize;
|
||||
}ventoy_ram_disk;
|
||||
|
||||
typedef struct ventoy_iso9660_override
|
||||
{
|
||||
UINT32 first_sector;
|
||||
UINT32 first_sector_be;
|
||||
UINT32 size;
|
||||
UINT32 size_be;
|
||||
}ventoy_iso9660_override;
|
||||
|
||||
typedef struct PART_TABLE
|
||||
{
|
||||
UINT8 Active; // 0x00 0x80
|
||||
|
||||
UINT8 StartHead;
|
||||
UINT16 StartSector : 6;
|
||||
UINT16 StartCylinder : 10;
|
||||
|
||||
UINT8 FsFlag;
|
||||
|
||||
UINT8 EndHead;
|
||||
UINT16 EndSector : 6;
|
||||
UINT16 EndCylinder : 10;
|
||||
|
||||
UINT32 StartSectorId;
|
||||
UINT32 SectorCount;
|
||||
}PART_TABLE;
|
||||
|
||||
typedef struct MBR_HEAD
|
||||
{
|
||||
UINT8 BootCode[446];
|
||||
PART_TABLE PartTbl[4];
|
||||
UINT8 Byte55;
|
||||
UINT8 ByteAA;
|
||||
}MBR_HEAD;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
@ -334,28 +273,8 @@ typedef struct ventoy_system_wrapper
|
||||
|
||||
EFI_OPEN_PROTOCOL NewOpenProtocol;
|
||||
EFI_OPEN_PROTOCOL OriOpenProtocol;
|
||||
|
||||
EFI_LOCATE_HANDLE_BUFFER NewLocateHandleBuffer;
|
||||
EFI_LOCATE_HANDLE_BUFFER OriLocateHandleBuffer;
|
||||
|
||||
EFI_PROTOCOLS_PER_HANDLE NewProtocolsPerHandle;
|
||||
EFI_PROTOCOLS_PER_HANDLE OriProtocolsPerHandle;
|
||||
|
||||
EFI_LOCATE_HANDLE NewLocateHandle;
|
||||
EFI_LOCATE_HANDLE OriLocateHandle;
|
||||
|
||||
EFI_LOCATE_DEVICE_PATH NewLocateDevicePath;
|
||||
EFI_LOCATE_DEVICE_PATH OriLocateDevicePath;
|
||||
} ventoy_system_wrapper;
|
||||
|
||||
|
||||
#define MAX_DRIVER_BIND_WRAPPER 64
|
||||
typedef struct DriverBindWrapper
|
||||
{
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
EFI_DRIVER_BINDING_SUPPORTED pfOldSupport;
|
||||
}DRIVER_BIND_WRAPPER;
|
||||
|
||||
#define ventoy_wrapper(bs, wrapper, func, newfunc) \
|
||||
{\
|
||||
wrapper.Ori##func = bs->func;\
|
||||
@ -363,25 +282,11 @@ typedef struct DriverBindWrapper
|
||||
bs->func = wrapper.New##func;\
|
||||
}
|
||||
|
||||
|
||||
#define VENTOY_GET_COMPONENT_NAME(Protocol, DriverName) \
|
||||
{\
|
||||
DriverName = NULL;\
|
||||
Status = Protocol->GetDriverName(Protocol, "en", &DriverName);\
|
||||
if (EFI_ERROR(Status) || NULL == DriverName) \
|
||||
{\
|
||||
DriverName = NULL;\
|
||||
Status = Protocol->GetDriverName(Protocol, "eng", &DriverName);\
|
||||
if (EFI_ERROR(Status) || NULL == DriverName) \
|
||||
{\
|
||||
continue;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
extern ventoy_efi_file_replace g_efi_file_replace;
|
||||
extern BOOLEAN gDebugPrint;
|
||||
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File);
|
||||
EFI_STATUS EFIAPI ventoy_block_io_read
|
||||
(
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
@ -391,43 +296,5 @@ EFI_STATUS EFIAPI ventoy_block_io_read
|
||||
OUT VOID *Buffer
|
||||
);
|
||||
|
||||
|
||||
extern ventoy_chain_head *g_chain;
|
||||
extern ventoy_img_chunk *g_chunk;
|
||||
extern UINT32 g_img_chunk_num;
|
||||
extern ventoy_override_chunk *g_override_chunk;
|
||||
extern UINT32 g_override_chunk_num;
|
||||
extern ventoy_virt_chunk *g_virt_chunk;
|
||||
extern UINT32 g_virt_chunk_num;
|
||||
extern vtoy_block_data gBlockData;
|
||||
extern ventoy_efi_file_replace g_efi_file_replace;
|
||||
extern ventoy_efi_file_replace g_img_file_replace[VTOY_MAX_CONF_REPLACE];
|
||||
extern ventoy_sector_flag *g_sector_flag;
|
||||
extern UINT32 g_sector_flag_num;
|
||||
extern BOOLEAN gMemdiskMode;
|
||||
extern BOOLEAN gSector512Mode;
|
||||
extern UINTN g_iso_buf_size;
|
||||
extern UINT8 *g_iso_data_buf;
|
||||
extern ventoy_grub_param_file_replace *g_file_replace_list;
|
||||
extern ventoy_grub_param_file_replace *g_img_replace_list;
|
||||
extern BOOLEAN g_fixup_iso9660_secover_enable;
|
||||
extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex;
|
||||
extern BOOLEAN g_fix_windows_1st_cdrom_issue;
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_open_volume
|
||||
(
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
||||
OUT EFI_FILE_PROTOCOL **Root
|
||||
);
|
||||
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize);
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume);
|
||||
EFI_STATUS ventoy_hook_keyboard_start(VOID);
|
||||
EFI_STATUS ventoy_hook_keyboard_stop(VOID);
|
||||
BOOLEAN ventoy_is_cdrom_dp_exist(VOID);
|
||||
EFI_STATUS ventoy_hook_1st_cdrom_start(VOID);
|
||||
EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID);
|
||||
EFI_STATUS ventoy_disable_ex_filesystem(VOID);
|
||||
EFI_STATUS ventoy_enable_ex_filesystem(VOID);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,82 +1,80 @@
|
||||
#************************************************************************************
|
||||
# Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#************************************************************************************
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Ventoy
|
||||
FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = VentoyEfiMain
|
||||
|
||||
|
||||
[Sources]
|
||||
Ventoy.h
|
||||
Ventoy.c
|
||||
VentoyDebug.c
|
||||
VentoyProtocol.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiApplicationEntryPoint
|
||||
UefiLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
gEfiGlobalVariableGuid
|
||||
gShellVariableGuid
|
||||
gEfiVirtualCdGuid
|
||||
gEfiFileInfoGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiBlockIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiSimpleFileSystemProtocolGuid
|
||||
gEfiRamDiskProtocolGuid
|
||||
gEfiAbsolutePointerProtocolGuid
|
||||
gEfiAcpiTableProtocolGuid
|
||||
gEfiBlockIo2ProtocolGuid
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid
|
||||
gEfiComponentNameProtocolGuid
|
||||
gEfiComponentName2ProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEfiDiskIoProtocolGuid
|
||||
gEfiDiskIo2ProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiHiiConfigAccessProtocolGuid
|
||||
gEfiHiiFontProtocolGuid
|
||||
gEfiLoadFileProtocolGuid
|
||||
gEfiLoadFile2ProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiLoadedImageDevicePathProtocolGuid
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextInputExProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#************************************************************************************
|
||||
# Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#************************************************************************************
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Ventoy
|
||||
FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = VentoyEfiMain
|
||||
|
||||
|
||||
[Sources]
|
||||
Ventoy.h
|
||||
Ventoy.c
|
||||
VentoyDebug.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiApplicationEntryPoint
|
||||
UefiLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
gShellVariableGuid
|
||||
gEfiVirtualCdGuid
|
||||
gEfiFileInfoGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiBlockIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiSimpleFileSystemProtocolGuid
|
||||
gEfiRamDiskProtocolGuid
|
||||
gEfiAbsolutePointerProtocolGuid
|
||||
gEfiAcpiTableProtocolGuid
|
||||
gEfiBlockIo2ProtocolGuid
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid
|
||||
gEfiComponentNameProtocolGuid
|
||||
gEfiComponentName2ProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEfiDiskIoProtocolGuid
|
||||
gEfiDiskIo2ProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiHiiConfigAccessProtocolGuid
|
||||
gEfiHiiFontProtocolGuid
|
||||
gEfiLoadFileProtocolGuid
|
||||
gEfiLoadFile2ProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiLoadedImageDevicePathProtocolGuid
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextInputExProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -34,13 +34,8 @@
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Ventoy.h>
|
||||
|
||||
#define PROCOTOL_SLEEP_MSECONDS 0
|
||||
|
||||
#define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS)
|
||||
|
||||
STATIC ventoy_system_wrapper g_system_wrapper;
|
||||
|
||||
static struct well_known_guid g_efi_well_known_guids[] =
|
||||
@ -89,6 +84,183 @@ static const char * ventoy_get_guid_name(EFI_GUID *guid)
|
||||
return gEfiGuidName;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_fs_open(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)New;
|
||||
(VOID)Name;
|
||||
(VOID)Mode;
|
||||
(VOID)Attributes;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token)
|
||||
{
|
||||
return ventoy_wrapper_fs_open(This, New, Name, Mode, Attributes);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_delete(EFI_FILE_HANDLE This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_flush(EFI_FILE_HANDLE This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Ex version */
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)Token;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)Len;
|
||||
(VOID)Data;
|
||||
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
|
||||
{
|
||||
return ventoy_wrapper_file_write(This, &(Token->BufferSize), Token->Buffer);
|
||||
}
|
||||
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_close(EFI_FILE_HANDLE This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
|
||||
{
|
||||
(VOID)This;
|
||||
|
||||
g_efi_file_replace.CurPos = Position;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
|
||||
{
|
||||
(VOID)This;
|
||||
|
||||
*Position = g_efi_file_replace.CurPos;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
|
||||
{
|
||||
EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
|
||||
|
||||
debug("ventoy_wrapper_file_get_info ... %u", *Len);
|
||||
|
||||
if (!CompareGuid(Type, &gEfiFileInfoGuid))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (*Len == 0)
|
||||
{
|
||||
*Len = 384;
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
ZeroMem(Data, sizeof(EFI_FILE_INFO));
|
||||
|
||||
Info->Size = sizeof(EFI_FILE_INFO);
|
||||
Info->FileSize = g_efi_file_replace.FileSizeBytes;
|
||||
Info->PhysicalSize = g_efi_file_replace.FileSizeBytes;
|
||||
Info->Attribute = EFI_FILE_READ_ONLY;
|
||||
//Info->FileName = EFI_FILE_READ_ONLY;
|
||||
|
||||
*Len = Info->Size;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
|
||||
{
|
||||
EFI_LBA Lba;
|
||||
UINTN ReadLen = *Len;
|
||||
|
||||
(VOID)This;
|
||||
|
||||
debug("ventoy_wrapper_file_read ... %u", *Len);
|
||||
|
||||
if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes)
|
||||
{
|
||||
ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos;
|
||||
}
|
||||
|
||||
Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart;
|
||||
|
||||
ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data);
|
||||
|
||||
*Len = ReadLen;
|
||||
|
||||
g_efi_file_replace.CurPos += ReadLen;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
|
||||
{
|
||||
return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File)
|
||||
{
|
||||
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
|
||||
File->Open = ventoy_wrapper_fs_open;
|
||||
File->Close = ventoy_wrapper_file_close;
|
||||
File->Delete = ventoy_wrapper_file_delete;
|
||||
File->Read = ventoy_wrapper_file_read;
|
||||
File->Write = ventoy_wrapper_file_write;
|
||||
File->GetPosition = ventoy_wrapper_file_get_pos;
|
||||
File->SetPosition = ventoy_wrapper_file_set_pos;
|
||||
File->GetInfo = ventoy_wrapper_file_get_info;
|
||||
File->SetInfo = ventoy_wrapper_file_set_info;
|
||||
File->Flush = ventoy_wrapper_file_flush;
|
||||
File->OpenEx = ventoy_wrapper_file_open_ex;
|
||||
File->ReadEx = ventoy_wrapper_file_read_ex;
|
||||
File->WriteEx = ventoy_wrapper_file_write_ex;
|
||||
File->FlushEx = ventoy_wrapper_file_flush_ex;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
|
||||
(
|
||||
IN EFI_HANDLE Handle,
|
||||
@ -98,7 +270,7 @@ STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep();
|
||||
debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
Status = g_system_wrapper.OriHandleProtocol(Handle, Protocol, Interface);
|
||||
|
||||
if (CompareGuid(Protocol, &gEfiSimpleFileSystemProtocolGuid))
|
||||
@ -108,7 +280,7 @@ STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
|
||||
|
||||
pFile->OpenVolume(pFile, &FileProtocol);
|
||||
|
||||
trace("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
|
||||
debug("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
|
||||
pFile, pFile->OpenVolume, FileProtocol, FileProtocol->Open);
|
||||
|
||||
sleep(3);
|
||||
@ -127,7 +299,7 @@ STATIC EFI_STATUS EFIAPI ventoy_open_protocol
|
||||
IN UINT32 Attributes
|
||||
)
|
||||
{
|
||||
debug("ventoy_open_protocol:<%p> %a", Handle, ventoy_get_guid_name(Protocol)); debug_sleep();
|
||||
debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes);
|
||||
}
|
||||
|
||||
@ -138,91 +310,15 @@ STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
|
||||
OUT VOID **Interface
|
||||
)
|
||||
{
|
||||
debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep();
|
||||
debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface);
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer
|
||||
(
|
||||
IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
||||
IN EFI_GUID *Protocol, OPTIONAL
|
||||
IN VOID *SearchKey, OPTIONAL
|
||||
IN OUT UINTN *NoHandles,
|
||||
OUT EFI_HANDLE **Buffer
|
||||
)
|
||||
{
|
||||
debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol)); debug_sleep();
|
||||
return g_system_wrapper.OriLocateHandleBuffer(SearchType, Protocol, SearchKey, NoHandles, Buffer);
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle
|
||||
(
|
||||
IN EFI_HANDLE Handle,
|
||||
OUT EFI_GUID ***ProtocolBuffer,
|
||||
OUT UINTN *ProtocolBufferCount
|
||||
)
|
||||
{
|
||||
debug("ventoy_protocol_per_handle:%p", Handle); debug_sleep();
|
||||
return g_system_wrapper.OriProtocolsPerHandle(Handle, ProtocolBuffer, ProtocolBufferCount);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_locate_handle
|
||||
(
|
||||
IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
||||
IN EFI_GUID *Protocol, OPTIONAL
|
||||
IN VOID *SearchKey, OPTIONAL
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_HANDLE *Buffer
|
||||
)
|
||||
{
|
||||
UINTN i;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
debug("ventoy_locate_handle: %d %a %p", SearchType, ventoy_get_guid_name(Protocol), SearchKey);
|
||||
Status = g_system_wrapper.OriLocateHandle(SearchType, Protocol, SearchKey, BufferSize, Buffer);
|
||||
debug("ventoy_locate_handle: %r Handle Count:%u", Status, *BufferSize/sizeof(EFI_HANDLE));
|
||||
|
||||
if (EFI_SUCCESS == Status)
|
||||
{
|
||||
for (i = 0; i < *BufferSize / sizeof(EFI_HANDLE); i++)
|
||||
{
|
||||
if (Buffer[i] == gBlockData.Handle)
|
||||
{
|
||||
Handle = Buffer[0];
|
||||
Buffer[0] = Buffer[i];
|
||||
Buffer[i] = Handle;
|
||||
debug("####### Handle at %u", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_sleep();
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_locate_device_path
|
||||
(
|
||||
IN EFI_GUID *Protocol,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
|
||||
OUT EFI_HANDLE *Device
|
||||
)
|
||||
{
|
||||
debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol)); debug_sleep();
|
||||
return g_system_wrapper.OriLocateDevicePath(Protocol, DevicePath, Device);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID)
|
||||
{
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateHandleBuffer, ventoy_locate_handle_buffer);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, ProtocolsPerHandle, ventoy_protocol_per_handle);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateHandle, ventoy_locate_handle);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateDevicePath, ventoy_locate_device_path);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,179 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Memhole.c
|
||||
*
|
||||
* Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <VtoyUtil.h>
|
||||
|
||||
STATIC BOOLEAN IsMemContiguous
|
||||
(
|
||||
IN CONST EFI_MEMORY_DESCRIPTOR *Prev,
|
||||
IN CONST EFI_MEMORY_DESCRIPTOR *Curr,
|
||||
IN CONST EFI_MEMORY_DESCRIPTOR *Next
|
||||
)
|
||||
{
|
||||
UINTN Addr1 = 0;
|
||||
UINTN Addr2 = 0;
|
||||
|
||||
if (Prev == NULL || Curr == NULL || Next == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Prev->Type == EfiBootServicesData &&
|
||||
Curr->Type == EfiConventionalMemory &&
|
||||
Next->Type == EfiBootServicesData)
|
||||
{
|
||||
Addr1 = Prev->PhysicalStart + MultU64x64(SIZE_4KB, Prev->NumberOfPages);
|
||||
Addr2 = Curr->PhysicalStart + MultU64x64(SIZE_4KB, Curr->NumberOfPages);
|
||||
|
||||
if (Addr1 == Curr->PhysicalStart && Addr2 == Next->PhysicalStart)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC EFI_MEMORY_DESCRIPTOR* GetMemDesc
|
||||
(
|
||||
OUT UINTN *pSize,
|
||||
OUT UINTN *pItemSize,
|
||||
OUT UINTN *pDescCount
|
||||
)
|
||||
{
|
||||
UINTN Size = 0;
|
||||
UINTN MapKey = 0;
|
||||
UINTN ItemSize = 0;
|
||||
UINTN DescCount = 0;
|
||||
UINT32 Version = 0;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_MEMORY_DESCRIPTOR *pDesc = NULL;
|
||||
EFI_MEMORY_DESCRIPTOR *Curr = NULL;
|
||||
|
||||
Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version);
|
||||
if (EFI_BUFFER_TOO_SMALL != Status)
|
||||
{
|
||||
debug("GetMemoryMap: %r", Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Size += SIZE_1KB;
|
||||
pDesc = AllocatePool(Size);
|
||||
if (!pDesc)
|
||||
{
|
||||
debug("AllocatePool: %lu failed", Size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZeroMem(pDesc, Size);
|
||||
|
||||
Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
debug("GetMemoryMap: %r", Status);
|
||||
FreePool(pDesc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Curr = pDesc;
|
||||
while (Curr && Curr < (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)pDesc + Size))
|
||||
{
|
||||
DescCount++;
|
||||
Curr = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize);
|
||||
}
|
||||
|
||||
*pSize = Size;
|
||||
*pItemSize = ItemSize;
|
||||
*pDescCount = DescCount;
|
||||
|
||||
debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize, DescCount);
|
||||
|
||||
return pDesc;
|
||||
}
|
||||
|
||||
EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine)
|
||||
{
|
||||
UINTN Size = 0;
|
||||
UINTN ItemSize = 0;
|
||||
UINTN DescCount = 0;
|
||||
UINTN TotalMem = 0;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_PHYSICAL_ADDRESS AllocAddr = 0;
|
||||
EFI_MEMORY_DESCRIPTOR *pDescs = NULL;
|
||||
EFI_MEMORY_DESCRIPTOR *Prev = NULL;
|
||||
EFI_MEMORY_DESCRIPTOR *Next = NULL;
|
||||
EFI_MEMORY_DESCRIPTOR *Curr = NULL;
|
||||
|
||||
(VOID)ImageHandle;
|
||||
(VOID)CmdLine;
|
||||
|
||||
pDescs = GetMemDesc(&Size, &ItemSize, &DescCount);
|
||||
if (!pDescs)
|
||||
{
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (DescCount < 500)
|
||||
{
|
||||
FreePool(pDescs);
|
||||
Printf("There is no need to fixup (%lu)\n", DescCount);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Curr = pDescs;
|
||||
while ((UINT8 *)Curr < (UINT8 *)pDescs + Size)
|
||||
{
|
||||
Next = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize);
|
||||
|
||||
if (IsMemContiguous(Prev, Curr, Next))
|
||||
{
|
||||
AllocAddr = Curr->PhysicalStart;
|
||||
Status = gBS->AllocatePages(AllocateAddress, EfiBootServicesData, Curr->NumberOfPages, &AllocAddr);
|
||||
if (EFI_SUCCESS == Status)
|
||||
{
|
||||
TotalMem += MultU64x64(SIZE_4KB, Curr->NumberOfPages);
|
||||
}
|
||||
}
|
||||
|
||||
Prev = Curr;
|
||||
Curr = Next;
|
||||
}
|
||||
|
||||
Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -1,140 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VtoyDrv.c
|
||||
*
|
||||
* Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <VtoyUtil.h>
|
||||
|
||||
STATIC UINTN g_EfiDriverNameCnt = 0;
|
||||
STATIC CHAR16 *g_EfiDriverNameList[1024] = { NULL };
|
||||
|
||||
STATIC EFI_STATUS AddEfiDriverName(IN CHAR16 *DriverName)
|
||||
{
|
||||
UINTN i = 0;
|
||||
|
||||
if (g_EfiDriverNameCnt >= 1024)
|
||||
{
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_EfiDriverNameCnt; i++)
|
||||
{
|
||||
if (g_EfiDriverNameList[i] && StrCmp(g_EfiDriverNameList[i], DriverName) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= g_EfiDriverNameCnt)
|
||||
{
|
||||
g_EfiDriverNameList[g_EfiDriverNameCnt] = DriverName;
|
||||
g_EfiDriverNameCnt++;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine)
|
||||
{
|
||||
UINTN i = 0;
|
||||
UINTN Count = 0;
|
||||
CHAR16 *DriverName = NULL;
|
||||
EFI_HANDLE *Handles = NULL;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
|
||||
EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
|
||||
|
||||
(VOID)ImageHandle;
|
||||
(VOID)CmdLine;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DriverName = NULL;
|
||||
Status = VtoyGetComponentName(2, Name2Protocol, &DriverName);
|
||||
if ((!EFI_ERROR(Status)) && (DriverName))
|
||||
{
|
||||
AddEfiDriverName(DriverName);
|
||||
}
|
||||
}
|
||||
|
||||
Count = 0;
|
||||
FreePool(Handles);
|
||||
Handles = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DriverName = NULL;
|
||||
Status = VtoyGetComponentName(1, Name2Protocol, &DriverName);
|
||||
if ((!EFI_ERROR(Status)) && (DriverName))
|
||||
{
|
||||
AddEfiDriverName(DriverName);
|
||||
}
|
||||
}
|
||||
|
||||
FreePool(Handles);
|
||||
|
||||
for (i = 0; i < g_EfiDriverNameCnt; i++)
|
||||
{
|
||||
Printf("%2d %s\n", i, g_EfiDriverNameList[i]);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -1,178 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VtoyUtil.c
|
||||
*
|
||||
* Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <VtoyUtil.h>
|
||||
|
||||
BOOLEAN gVtoyDebugPrint = FALSE;
|
||||
STATIC CONST CHAR16 *gCurFeature= NULL;
|
||||
STATIC CHAR16 *gCmdLine = NULL;
|
||||
STATIC grub_env_printf_pf g_env_printf = NULL;
|
||||
|
||||
STATIC VtoyUtilFeature gFeatureList[] =
|
||||
{
|
||||
{ L"fix_windows_mmap", FixWindowsMemhole },
|
||||
{ L"show_efi_drivers", ShowEfiDrivers },
|
||||
};
|
||||
|
||||
EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
CHAR16 *DrvName = NULL;
|
||||
EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
|
||||
EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
|
||||
|
||||
if (1 == Ver)
|
||||
{
|
||||
NameProtocol = (EFI_COMPONENT_NAME_PROTOCOL *)Protocol;
|
||||
Status = NameProtocol->GetDriverName(Protocol, "en", &DrvName);
|
||||
if (EFI_ERROR(Status) || NULL == DrvName)
|
||||
{
|
||||
Status = NameProtocol->GetDriverName(Protocol, "eng", &DrvName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Name2Protocol = (EFI_COMPONENT_NAME2_PROTOCOL *)Protocol;
|
||||
Status = Name2Protocol->GetDriverName(Protocol, "en", &DrvName);
|
||||
if (EFI_ERROR(Status) || NULL == DrvName)
|
||||
{
|
||||
Status = Name2Protocol->GetDriverName(Protocol, "eng", &DrvName);
|
||||
}
|
||||
}
|
||||
|
||||
*DriverName = DrvName;
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...)
|
||||
{
|
||||
VA_LIST Marker;
|
||||
CHAR8 Buffer[512];
|
||||
|
||||
VA_START (Marker, Format);
|
||||
AsciiVSPrint(Buffer, sizeof(Buffer), Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
if (g_env_printf)
|
||||
{
|
||||
g_env_printf("%s", Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
CHAR16 *pPos = NULL;
|
||||
CHAR16 *pCmdLine = NULL;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
ventoy_grub_param *pGrubParam = NULL;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
|
||||
|
||||
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4);
|
||||
SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0);
|
||||
CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize);
|
||||
|
||||
if (StrStr(pCmdLine, L"vtoyefitest"))
|
||||
{
|
||||
gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################");
|
||||
gST->ConOut->OutputString(gST->ConOut, L"\r\n######### VTOY #########");
|
||||
gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################");
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (StrStr(pCmdLine, L"debug"))
|
||||
{
|
||||
gVtoyDebugPrint = TRUE;
|
||||
}
|
||||
|
||||
pPos = StrStr(pCmdLine, L"env_param=");
|
||||
if (!pPos)
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
|
||||
g_env_printf = pGrubParam->grub_env_printf;
|
||||
|
||||
pPos = StrStr(pCmdLine, L"feature=");
|
||||
if (!pPos)
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
gCurFeature = pPos + StrLen(L"feature=");
|
||||
|
||||
gCmdLine = pCmdLine;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI VtoyUtilEfiMain
|
||||
(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
UINTN i;
|
||||
UINTN Len;
|
||||
|
||||
ParseCmdline(ImageHandle);
|
||||
|
||||
for (i = 0; gCurFeature && i < ARRAY_SIZE(gFeatureList); i++)
|
||||
{
|
||||
Len = StrLen(gFeatureList[i].Cmd);
|
||||
if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0)
|
||||
{
|
||||
debug("Find main proc <%s>", gFeatureList[i].Cmd);
|
||||
gFeatureList[i].MainProc(ImageHandle, gCurFeature + Len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCmdLine)
|
||||
{
|
||||
FreePool(gCmdLine);
|
||||
gCmdLine = NULL;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
/******************************************************************************
|
||||
* VtoyUtil.h
|
||||
*
|
||||
* Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __VTOYUTIL_H__
|
||||
#define __VTOYUTIL_H__
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
||||
typedef int (*grub_env_set_pf)(const char *name, const char *val);
|
||||
typedef const char * (*grub_env_get_pf)(const char *name);
|
||||
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
||||
|
||||
#define VTOY_MAX_CONF_REPLACE 2
|
||||
|
||||
typedef struct ventoy_grub_param_file_replace
|
||||
{
|
||||
UINT32 magic;
|
||||
char old_file_name[4][256];
|
||||
UINT32 old_file_cnt;
|
||||
UINT32 new_file_virtual_id;
|
||||
}ventoy_grub_param_file_replace;
|
||||
|
||||
typedef struct ventoy_grub_param
|
||||
{
|
||||
grub_env_get_pf grub_env_get;
|
||||
grub_env_set_pf grub_env_set;
|
||||
ventoy_grub_param_file_replace file_replace;
|
||||
ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
|
||||
grub_env_printf_pf grub_env_printf;
|
||||
}ventoy_grub_param;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
typedef struct VtoyUtilFeature
|
||||
{
|
||||
CONST CHAR16 *Cmd;
|
||||
VTOY_UTIL_PROC_PF MainProc;
|
||||
}VtoyUtilFeature;
|
||||
|
||||
extern BOOLEAN gVtoyDebugPrint;
|
||||
VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...);
|
||||
#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__)
|
||||
#define Printf VtoyUtilDebug
|
||||
|
||||
EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName);
|
||||
EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
||||
EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
||||
|
||||
#endif
|
||||
|
@ -1,81 +0,0 @@
|
||||
#************************************************************************************
|
||||
# Copyright (c) 2020, longpanda <admin@ventoy.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#************************************************************************************
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = VtoyUtil
|
||||
FILE_GUID = a43466a0-68c6-469d-ba4b-678bbe90bc47
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = VtoyUtilEfiMain
|
||||
|
||||
|
||||
[Sources]
|
||||
VtoyUtil.h
|
||||
VtoyUtil.c
|
||||
VtoyDrv.c
|
||||
Memhole.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiApplicationEntryPoint
|
||||
UefiLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
gShellVariableGuid
|
||||
gEfiVirtualCdGuid
|
||||
gEfiFileInfoGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiBlockIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiSimpleFileSystemProtocolGuid
|
||||
gEfiRamDiskProtocolGuid
|
||||
gEfiAbsolutePointerProtocolGuid
|
||||
gEfiAcpiTableProtocolGuid
|
||||
gEfiBlockIo2ProtocolGuid
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid
|
||||
gEfiComponentNameProtocolGuid
|
||||
gEfiComponentName2ProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEfiDiskIoProtocolGuid
|
||||
gEfiDiskIo2ProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiHiiConfigAccessProtocolGuid
|
||||
gEfiHiiFontProtocolGuid
|
||||
gEfiLoadFileProtocolGuid
|
||||
gEfiLoadFile2ProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiLoadedImageDevicePathProtocolGuid
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextInputExProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -204,8 +204,6 @@
|
||||
|
||||
[Components]
|
||||
MdeModulePkg/Application/Ventoy/Ventoy.inf
|
||||
MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
|
||||
MdeModulePkg/Application/VDiskChain/VDiskChain.inf
|
||||
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
||||
MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
|
||||
MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
|
||||
|
@ -743,8 +743,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||
if (!ctx.filename && dirent.namelen == 1 && name[0] == 1)
|
||||
ctx.filename = (char *) "..";
|
||||
|
||||
if (g_fs_name_nocase)
|
||||
ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||
if (g_fs_name_nocase)
|
||||
ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||
|
||||
/* The filename was not stored in a rock ridge entry. Read it
|
||||
from the iso9660 filesystem. */
|
||||
|
@ -70,10 +70,10 @@ SetLogging(VOID)
|
||||
CHAR16 LogVar[4];
|
||||
UINTN i, LogVarSize = sizeof(LogVar);
|
||||
|
||||
i = LogVarSize;
|
||||
i = LogVarSize;
|
||||
Status = RT->GetVariable(L"FS_NAME_NOCASE", &ShellVariable, NULL, &i, LogVar);
|
||||
if (Status == EFI_SUCCESS)
|
||||
g_fs_name_nocase = 1;
|
||||
if (Status == EFI_SUCCESS)
|
||||
g_fs_name_nocase = 1;
|
||||
|
||||
Status = RT->GetVariable(L"FS_LOGGING", &ShellVariable, NULL, &LogVarSize, LogVar);
|
||||
if (Status == EFI_SUCCESS)
|
||||
|
@ -1 +0,0 @@
|
||||
1
|
@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f ventoy_efiboot.img.*
|
||||
|
||||
cd ISO
|
||||
mkisofs -R -D -sysid VENTOY -V VENTOY -P "longpanda admin@ventoy.net" -p 'https://www.ventoy.net' -o ../ventoy_efiboot.img ./
|
||||
cd ..
|
||||
|
||||
xz --check=crc32 ventoy_efiboot.img
|
||||
|
||||
rm -f ../INSTALL/ventoy/ventoy_efiboot.img.xz
|
||||
cp -a ventoy_efiboot.img.xz ../INSTALL/ventoy/
|
||||
|
@ -1,32 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CUR="$PWD"
|
||||
|
||||
if ! [ -e LIBFUSE ]; then
|
||||
./buidlibfuse.sh
|
||||
fi
|
||||
|
||||
rm -f EXFAT/shared/*
|
||||
|
||||
|
||||
rm -rf exfat-1.3.0
|
||||
unzip exfat-1.3.0.zip
|
||||
sed "/printf.*VERSION/a\ if (access(\"/etc/initrd-release\", F_OK) >= 0) argv[0][0] = '@';" -i exfat-1.3.0/fuse/main.c
|
||||
|
||||
cd exfat-1.3.0
|
||||
autoreconf --install
|
||||
./configure --prefix="$CUR" CFLAGS='-O2 -D_FILE_OFFSET_BITS=64' FUSE_CFLAGS="-I$CUR/LIBFUSE/include/" FUSE_LIBS="$CUR/LIBFUSE/lib/libfuse.a -lpthread -ldl"
|
||||
make
|
||||
|
||||
strip --strip-all fuse/mount.exfat-fuse
|
||||
strip --strip-all mkfs/mkexfatfs
|
||||
|
||||
cp fuse/mount.exfat-fuse ../EXFAT/shared/mount.exfat-fuse
|
||||
cp mkfs/mkexfatfs ../EXFAT/shared/mkexfatfs
|
||||
|
||||
cd ..
|
||||
rm -rf exfat-1.3.0
|
||||
|
||||
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CUR="$PWD"
|
||||
|
||||
rm -rf libfuse
|
||||
rm -rf LIBFUSE
|
||||
|
||||
if [ -e mirrors-libfuse-fuse-2.9.9.zip ]; then
|
||||
unzip mirrors-libfuse-fuse-2.9.9.zip
|
||||
cd libfuse
|
||||
else
|
||||
unzip libfuse-fuse-2.9.9.zip
|
||||
cd libfuse-fuse-2.9.9
|
||||
fi
|
||||
|
||||
./makeconf.sh
|
||||
|
||||
./configure --prefix="$CUR/LIBFUSE"
|
||||
|
||||
sed '/#define *__u64/d' -i include/fuse_kernel.h
|
||||
sed '/#define *__s64/d' -i include/fuse_kernel.h
|
||||
|
||||
sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h
|
||||
sed 's/__s64/int64_t/g' -i include/fuse_kernel.h
|
||||
|
||||
make -j 16
|
||||
make install
|
||||
cd ..
|
||||
rm -rf libfuse
|
@ -11,16 +11,10 @@ else
|
||||
opt=-lrt
|
||||
fi
|
||||
|
||||
#
|
||||
# use musl-c to build for x86_64
|
||||
#
|
||||
|
||||
export C_INCLUDE_PATH=$LIBFUSE_DIR/include
|
||||
|
||||
rm -f $name
|
||||
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c $LIBFUSE_DIR/lib/libfuse.a -o $name
|
||||
|
||||
strip --strip-all $name
|
||||
gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a -lpthread -ldl $opt
|
||||
|
||||
if [ -e $name ]; then
|
||||
echo -e "\n############### SUCCESS $name ##################\n"
|
||||
|
@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CUR="$PWD"
|
||||
|
||||
LIBFUSE_DIR=$CUR/LIBFUSE
|
||||
|
||||
name=vtoy_fuse_iso_aa64
|
||||
|
||||
export C_INCLUDE_PATH=$LIBFUSE_DIR/include
|
||||
|
||||
rm -f $name
|
||||
aarch64-buildroot-linux-uclibc-gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a
|
||||
|
||||
if [ -e $name ]; then
|
||||
echo -e "\n############### SUCCESS $name ##################\n"
|
||||
else
|
||||
echo -e "\n############### FAILED $name ##################\n"
|
||||
fi
|
||||
|
||||
aarch64-buildroot-linux-uclibc-strip --strip-all $name
|
||||
|
@ -7,8 +7,6 @@
|
||||
#
|
||||
#
|
||||
|
||||
# use mini-native-x86_64 UCLIBC to build for x86_64
|
||||
|
||||
|
||||
CUR="$PWD"
|
||||
LIBFUSE_DIR=$CUR/LIBFUSE
|
||||
@ -33,7 +31,7 @@ fi
|
||||
|
||||
./makeconf.sh
|
||||
|
||||
./configure --prefix="$LIBFUSE_DIR" CFLAGS='-specs /usr/local/musl/lib/musl-gcc.specs'
|
||||
./configure --prefix="$LIBFUSE_DIR"
|
||||
make -j 16
|
||||
make install
|
||||
cd ..
|
||||
|
@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
#
|
||||
# Package Dependency:
|
||||
# gcc automake autoconf gettext gettext-devel libtool unzip
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
CUR="$PWD"
|
||||
LIBFUSE_DIR=$CUR/LIBFUSE
|
||||
|
||||
rm -rf libfuse
|
||||
rm -rf $LIBFUSE_DIR
|
||||
|
||||
# please download https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9
|
||||
if [ -e ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip ]; then
|
||||
rm -rf libfuse
|
||||
unzip ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip
|
||||
cd libfuse
|
||||
elif [ -e ../ExFAT/libfuse-fuse-2.9.9.zip ]; then
|
||||
rm -rf libfuse-fuse-2.9.9
|
||||
unzip ../ExFAT/libfuse-fuse-2.9.9.zip
|
||||
cd libfuse-fuse-2.9.9
|
||||
else
|
||||
echo "Please download mirrors-libfuse-fuse-2.9.9.zip first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
./makeconf.sh
|
||||
|
||||
sed '/#define *__u64/d' -i include/fuse_kernel.h
|
||||
sed '/#define *__s64/d' -i include/fuse_kernel.h
|
||||
|
||||
sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h
|
||||
sed 's/__s64/int64_t/g' -i include/fuse_kernel.h
|
||||
|
||||
./configure --prefix="$LIBFUSE_DIR" --host=aarch64 CC=aarch64-buildroot-linux-uclibc-gcc
|
||||
|
||||
|
||||
make -j 16
|
||||
make install
|
||||
cd ..
|
||||
rm -rf libfuse
|
@ -114,12 +114,11 @@ static int ventoy_iso_open(const char *path, struct fuse_file_info *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, char *buf)
|
||||
static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, void *buf)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t leftSec = 0;
|
||||
uint32_t readSec = 0;
|
||||
off_t offset = 0;
|
||||
dmtable_entry *entry = NULL;
|
||||
|
||||
for (i = 0; i < g_disk_entry_num && num > 0; i++)
|
||||
@ -128,15 +127,14 @@ static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, char *buf)
|
||||
|
||||
if (sector >= entry->isoSector && sector < entry->isoSector + entry->sectorNum)
|
||||
{
|
||||
offset = (entry->diskSector + (sector - entry->isoSector)) * 512;
|
||||
lseek(g_disk_fd, (entry->diskSector + (sector - entry->isoSector)) * 512, SEEK_SET);
|
||||
|
||||
leftSec = entry->sectorNum - (sector - entry->isoSector);
|
||||
readSec = (leftSec > num) ? num : leftSec;
|
||||
|
||||
pread(g_disk_fd, buf, readSec * 512, offset);
|
||||
read(g_disk_fd, buf, readSec * 512);
|
||||
|
||||
sector += readSec;
|
||||
buf += readSec * 512;
|
||||
num -= readSec;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,909 +0,0 @@
|
||||
#! /usr/bin/python
|
||||
# GRUB -- GRand Unified Bootloader
|
||||
# Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# GRUB is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GRUB is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
from optparse import OptionParser
|
||||
import re
|
||||
|
||||
#
|
||||
# This is the python script used to generate Makefile.*.am
|
||||
#
|
||||
|
||||
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
|
||||
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
|
||||
"i386_xen", "x86_64_xen", "i386_xen_pvh",
|
||||
"mips_loongson", "mips64_efi", "sparc64_ieee1275",
|
||||
"powerpc_ieee1275", "mips_arc", "ia64_efi",
|
||||
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
|
||||
"arm_coreboot", "riscv32_efi", "riscv64_efi" ]
|
||||
|
||||
GROUPS = {}
|
||||
|
||||
GROUPS["common"] = GRUB_PLATFORMS[:]
|
||||
|
||||
# Groups based on CPU
|
||||
GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ]
|
||||
GROUPS["x86_64"] = [ "x86_64_efi" ]
|
||||
GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
|
||||
GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
|
||||
GROUPS["mips64"] = [ "mips64_efi" ]
|
||||
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
||||
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
||||
GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ]
|
||||
GROUPS["arm64"] = [ "arm64_efi" ]
|
||||
GROUPS["riscv32"] = [ "riscv32_efi" ]
|
||||
GROUPS["riscv64"] = [ "riscv64_efi" ]
|
||||
|
||||
# Groups based on firmware
|
||||
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "mips64_efi",
|
||||
"riscv32_efi", "riscv64_efi" ]
|
||||
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
|
||||
GROUPS["uboot"] = [ "arm_uboot" ]
|
||||
GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
|
||||
GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ]
|
||||
|
||||
# emu is a special case so many core functionality isn't needed on this platform
|
||||
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
|
||||
|
||||
# Groups based on hardware features
|
||||
GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips",
|
||||
"sparc64_ieee1275", "powerpc_ieee1275"]
|
||||
GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi");
|
||||
GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
|
||||
GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"]
|
||||
|
||||
# If gfxterm is main output console integrate it into kernel
|
||||
GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ]
|
||||
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
|
||||
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
|
||||
|
||||
# Similar for terminfo
|
||||
GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
|
||||
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
|
||||
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
|
||||
|
||||
# Flattened Device Trees (FDT)
|
||||
GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ]
|
||||
|
||||
# Needs software helpers for division
|
||||
# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
|
||||
GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"]
|
||||
GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
|
||||
for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
|
||||
|
||||
# Miscellaneous groups scheduled to disappear in future
|
||||
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
|
||||
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
|
||||
|
||||
#
|
||||
# Create platform => groups reverse map, where groups covering that
|
||||
# platform are ordered by their sizes
|
||||
#
|
||||
RMAP = {}
|
||||
for platform in GRUB_PLATFORMS:
|
||||
# initialize with platform itself as a group
|
||||
RMAP[platform] = [ platform ]
|
||||
|
||||
for k in GROUPS.keys():
|
||||
v = GROUPS[k]
|
||||
# skip groups that don't cover this platform
|
||||
if platform not in v: continue
|
||||
|
||||
bigger = []
|
||||
smaller = []
|
||||
# partition currently known groups based on their size
|
||||
for group in RMAP[platform]:
|
||||
if group in GRUB_PLATFORMS: smaller.append(group)
|
||||
elif len(GROUPS[group]) < len(v): smaller.append(group)
|
||||
else: bigger.append(group)
|
||||
# insert in the middle
|
||||
RMAP[platform] = smaller + [ k ] + bigger
|
||||
|
||||
#
|
||||
# Input
|
||||
#
|
||||
|
||||
# We support a subset of the AutoGen definitions file syntax. Specifically,
|
||||
# compound names are disallowed; some preprocessing directives are
|
||||
# disallowed (though #if/#endif are allowed; note that, like AutoGen, #if
|
||||
# skips everything to the next #endif regardless of the value of the
|
||||
# conditional); and shell-generated strings, Scheme-generated strings, and
|
||||
# here strings are disallowed.
|
||||
|
||||
class AutogenToken:
|
||||
(autogen, definitions, eof, var_name, other_name, string, number,
|
||||
semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14)
|
||||
|
||||
class AutogenState:
|
||||
(init, need_def, need_tpl, need_semi, need_name, have_name, need_value,
|
||||
need_idx, need_rbracket, indx_name, have_value, done) = range(12)
|
||||
|
||||
class AutogenParseError(Exception):
|
||||
def __init__(self, message, path, line):
|
||||
super(AutogenParseError, self).__init__(message)
|
||||
self.path = path
|
||||
self.line = line
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
super(AutogenParseError, self).__str__() +
|
||||
" at file %s line %d" % (self.path, self.line))
|
||||
|
||||
class AutogenDefinition(list):
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return super(AutogenDefinition, self).__getitem__(key)
|
||||
except TypeError:
|
||||
for name, value in self:
|
||||
if name == key:
|
||||
return value
|
||||
|
||||
def __contains__(self, key):
|
||||
for name, value in self:
|
||||
if name == key:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get(self, key, default):
|
||||
for name, value in self:
|
||||
if name == key:
|
||||
return value
|
||||
else:
|
||||
return default
|
||||
|
||||
def find_all(self, key):
|
||||
for name, value in self:
|
||||
if name == key:
|
||||
yield value
|
||||
|
||||
class AutogenParser:
|
||||
def __init__(self):
|
||||
self.definitions = AutogenDefinition()
|
||||
self.def_stack = [("", self.definitions)]
|
||||
self.curdef = None
|
||||
self.new_name = None
|
||||
self.cur_path = None
|
||||
self.cur_line = 0
|
||||
|
||||
@staticmethod
|
||||
def is_unquotable_char(c):
|
||||
return (ord(c) in range(ord("!"), ord("~") + 1) and
|
||||
c not in "#,;<=>[\\]`{}?*'\"()")
|
||||
|
||||
@staticmethod
|
||||
def is_value_name_char(c):
|
||||
return c in ":^-_" or c.isalnum()
|
||||
|
||||
def error(self, message):
|
||||
raise AutogenParseError(message, self.cur_file, self.cur_line)
|
||||
|
||||
def read_tokens(self, f):
|
||||
data = f.read()
|
||||
end = len(data)
|
||||
offset = 0
|
||||
while offset < end:
|
||||
while offset < end and data[offset].isspace():
|
||||
if data[offset] == "\n":
|
||||
self.cur_line += 1
|
||||
offset += 1
|
||||
if offset >= end:
|
||||
break
|
||||
c = data[offset]
|
||||
if c == "#":
|
||||
offset += 1
|
||||
try:
|
||||
end_directive = data.index("\n", offset)
|
||||
directive = data[offset:end_directive]
|
||||
offset = end_directive
|
||||
except ValueError:
|
||||
directive = data[offset:]
|
||||
offset = end
|
||||
name, value = directive.split(None, 1)
|
||||
if name == "if":
|
||||
try:
|
||||
end_if = data.index("\n#endif", offset)
|
||||
new_offset = end_if + len("\n#endif")
|
||||
self.cur_line += data[offset:new_offset].count("\n")
|
||||
offset = new_offset
|
||||
except ValueError:
|
||||
self.error("#if without matching #endif")
|
||||
else:
|
||||
self.error("Unhandled directive '#%s'" % name)
|
||||
elif c == "{":
|
||||
yield AutogenToken.lbrace, c
|
||||
offset += 1
|
||||
elif c == "=":
|
||||
yield AutogenToken.equals, c
|
||||
offset += 1
|
||||
elif c == "}":
|
||||
yield AutogenToken.rbrace, c
|
||||
offset += 1
|
||||
elif c == "[":
|
||||
yield AutogenToken.lbracket, c
|
||||
offset += 1
|
||||
elif c == "]":
|
||||
yield AutogenToken.rbracket, c
|
||||
offset += 1
|
||||
elif c == ";":
|
||||
yield AutogenToken.semicolon, c
|
||||
offset += 1
|
||||
elif c == ",":
|
||||
yield AutogenToken.comma, c
|
||||
offset += 1
|
||||
elif c in ("'", '"'):
|
||||
s = []
|
||||
while True:
|
||||
offset += 1
|
||||
if offset >= end:
|
||||
self.error("EOF in quoted string")
|
||||
if data[offset] == "\n":
|
||||
self.cur_line += 1
|
||||
if data[offset] == "\\":
|
||||
offset += 1
|
||||
if offset >= end:
|
||||
self.error("EOF in quoted string")
|
||||
if data[offset] == "\n":
|
||||
self.cur_line += 1
|
||||
# Proper escaping unimplemented; this can be filled
|
||||
# out if needed.
|
||||
s.append("\\")
|
||||
s.append(data[offset])
|
||||
elif data[offset] == c:
|
||||
offset += 1
|
||||
break
|
||||
else:
|
||||
s.append(data[offset])
|
||||
yield AutogenToken.string, "".join(s)
|
||||
elif c == "/":
|
||||
offset += 1
|
||||
if data[offset] == "*":
|
||||
offset += 1
|
||||
try:
|
||||
end_comment = data.index("*/", offset)
|
||||
new_offset = end_comment + len("*/")
|
||||
self.cur_line += data[offset:new_offset].count("\n")
|
||||
offset = new_offset
|
||||
except ValueError:
|
||||
self.error("/* without matching */")
|
||||
elif data[offset] == "/":
|
||||
try:
|
||||
offset = data.index("\n", offset)
|
||||
except ValueError:
|
||||
pass
|
||||
elif (c.isdigit() or
|
||||
(c == "-" and offset < end - 1 and
|
||||
data[offset + 1].isdigit())):
|
||||
end_number = offset + 1
|
||||
while end_number < end and data[end_number].isdigit():
|
||||
end_number += 1
|
||||
yield AutogenToken.number, data[offset:end_number]
|
||||
offset = end_number
|
||||
elif self.is_unquotable_char(c):
|
||||
end_name = offset
|
||||
while (end_name < end and
|
||||
self.is_value_name_char(data[end_name])):
|
||||
end_name += 1
|
||||
if end_name < end and self.is_unquotable_char(data[end_name]):
|
||||
while (end_name < end and
|
||||
self.is_unquotable_char(data[end_name])):
|
||||
end_name += 1
|
||||
yield AutogenToken.other_name, data[offset:end_name]
|
||||
offset = end_name
|
||||
else:
|
||||
s = data[offset:end_name]
|
||||
if s.lower() == "autogen":
|
||||
yield AutogenToken.autogen, s
|
||||
elif s.lower() == "definitions":
|
||||
yield AutogenToken.definitions, s
|
||||
else:
|
||||
yield AutogenToken.var_name, s
|
||||
offset = end_name
|
||||
else:
|
||||
self.error("Invalid input character '%s'" % c)
|
||||
yield AutogenToken.eof, None
|
||||
|
||||
def do_need_name_end(self, token):
|
||||
if len(self.def_stack) > 1:
|
||||
self.error("Definition blocks were left open")
|
||||
|
||||
def do_need_name_var_name(self, token):
|
||||
self.new_name = token
|
||||
|
||||
def do_end_block(self, token):
|
||||
if len(self.def_stack) <= 1:
|
||||
self.error("Too many close braces")
|
||||
new_name, parent_def = self.def_stack.pop()
|
||||
parent_def.append((new_name, self.curdef))
|
||||
self.curdef = parent_def
|
||||
|
||||
def do_empty_val(self, token):
|
||||
self.curdef.append((self.new_name, ""))
|
||||
|
||||
def do_str_value(self, token):
|
||||
self.curdef.append((self.new_name, token))
|
||||
|
||||
def do_start_block(self, token):
|
||||
self.def_stack.append((self.new_name, self.curdef))
|
||||
self.curdef = AutogenDefinition()
|
||||
|
||||
def do_indexed_name(self, token):
|
||||
self.new_name = token
|
||||
|
||||
def read_definitions_file(self, f):
|
||||
self.curdef = self.definitions
|
||||
self.cur_line = 0
|
||||
state = AutogenState.init
|
||||
|
||||
# The following transition table was reduced from the Autogen
|
||||
# documentation:
|
||||
# info -f autogen -n 'Full Syntax'
|
||||
transitions = {
|
||||
AutogenState.init: {
|
||||
AutogenToken.autogen: (AutogenState.need_def, None),
|
||||
},
|
||||
AutogenState.need_def: {
|
||||
AutogenToken.definitions: (AutogenState.need_tpl, None),
|
||||
},
|
||||
AutogenState.need_tpl: {
|
||||
AutogenToken.var_name: (AutogenState.need_semi, None),
|
||||
AutogenToken.other_name: (AutogenState.need_semi, None),
|
||||
AutogenToken.string: (AutogenState.need_semi, None),
|
||||
},
|
||||
AutogenState.need_semi: {
|
||||
AutogenToken.semicolon: (AutogenState.need_name, None),
|
||||
},
|
||||
AutogenState.need_name: {
|
||||
AutogenToken.autogen: (AutogenState.need_def, None),
|
||||
AutogenToken.eof: (AutogenState.done, self.do_need_name_end),
|
||||
AutogenToken.var_name: (
|
||||
AutogenState.have_name, self.do_need_name_var_name),
|
||||
AutogenToken.rbrace: (
|
||||
AutogenState.have_value, self.do_end_block),
|
||||
},
|
||||
AutogenState.have_name: {
|
||||
AutogenToken.semicolon: (
|
||||
AutogenState.need_name, self.do_empty_val),
|
||||
AutogenToken.equals: (AutogenState.need_value, None),
|
||||
AutogenToken.lbracket: (AutogenState.need_idx, None),
|
||||
},
|
||||
AutogenState.need_value: {
|
||||
AutogenToken.var_name: (
|
||||
AutogenState.have_value, self.do_str_value),
|
||||
AutogenToken.other_name: (
|
||||
AutogenState.have_value, self.do_str_value),
|
||||
AutogenToken.string: (
|
||||
AutogenState.have_value, self.do_str_value),
|
||||
AutogenToken.number: (
|
||||
AutogenState.have_value, self.do_str_value),
|
||||
AutogenToken.lbrace: (
|
||||
AutogenState.need_name, self.do_start_block),
|
||||
},
|
||||
AutogenState.need_idx: {
|
||||
AutogenToken.var_name: (
|
||||
AutogenState.need_rbracket, self.do_indexed_name),
|
||||
AutogenToken.number: (
|
||||
AutogenState.need_rbracket, self.do_indexed_name),
|
||||
},
|
||||
AutogenState.need_rbracket: {
|
||||
AutogenToken.rbracket: (AutogenState.indx_name, None),
|
||||
},
|
||||
AutogenState.indx_name: {
|
||||
AutogenToken.semicolon: (
|
||||
AutogenState.need_name, self.do_empty_val),
|
||||
AutogenToken.equals: (AutogenState.need_value, None),
|
||||
},
|
||||
AutogenState.have_value: {
|
||||
AutogenToken.semicolon: (AutogenState.need_name, None),
|
||||
AutogenToken.comma: (AutogenState.need_value, None),
|
||||
},
|
||||
}
|
||||
|
||||
for code, token in self.read_tokens(f):
|
||||
if code in transitions[state]:
|
||||
state, handler = transitions[state][code]
|
||||
if handler is not None:
|
||||
handler(token)
|
||||
else:
|
||||
self.error(
|
||||
"Parse error in state %s: unexpected token '%s'" % (
|
||||
state, token))
|
||||
if state == AutogenState.done:
|
||||
break
|
||||
|
||||
def read_definitions(self, path):
|
||||
self.cur_file = path
|
||||
with open(path) as f:
|
||||
self.read_definitions_file(f)
|
||||
|
||||
defparser = AutogenParser()
|
||||
|
||||
#
|
||||
# Output
|
||||
#
|
||||
|
||||
outputs = {}
|
||||
|
||||
def output(s, section=''):
|
||||
if s == "":
|
||||
return
|
||||
outputs.setdefault(section, [])
|
||||
outputs[section].append(s)
|
||||
|
||||
def write_output(section=''):
|
||||
for s in outputs.get(section, []):
|
||||
print(s, end='')
|
||||
|
||||
#
|
||||
# Global variables
|
||||
#
|
||||
|
||||
def gvar_add(var, value):
|
||||
output(var + " += " + value + "\n")
|
||||
|
||||
#
|
||||
# Per PROGRAM/SCRIPT variables
|
||||
#
|
||||
|
||||
seen_vars = set()
|
||||
|
||||
def vars_init(defn, *var_list):
|
||||
name = defn['name']
|
||||
|
||||
if name not in seen_target and name not in seen_vars:
|
||||
for var in var_list:
|
||||
output(var + " = \n", section='decl')
|
||||
seen_vars.add(name)
|
||||
|
||||
def var_set(var, value):
|
||||
output(var + " = " + value + "\n")
|
||||
|
||||
def var_add(var, value):
|
||||
output(var + " += " + value + "\n")
|
||||
|
||||
#
|
||||
# Variable names and rules
|
||||
#
|
||||
|
||||
canonical_name_re = re.compile(r'[^0-9A-Za-z@_]')
|
||||
canonical_name_suffix = ""
|
||||
|
||||
def set_canonical_name_suffix(suffix):
|
||||
global canonical_name_suffix
|
||||
canonical_name_suffix = suffix
|
||||
|
||||
def cname(defn):
|
||||
return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix)
|
||||
|
||||
def rule(target, source, cmd):
|
||||
if cmd[0] == "\n":
|
||||
output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n")
|
||||
else:
|
||||
output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n")
|
||||
|
||||
#
|
||||
# Handle keys with platform names as values, for example:
|
||||
#
|
||||
# kernel = {
|
||||
# nostrip = emu;
|
||||
# ...
|
||||
# }
|
||||
#
|
||||
def platform_tagged(defn, platform, tag):
|
||||
for value in defn.find_all(tag):
|
||||
for group in RMAP[platform]:
|
||||
if value == group:
|
||||
return True
|
||||
return False
|
||||
|
||||
def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None):
|
||||
if platform_tagged(defn, platform, tag):
|
||||
return snippet_if
|
||||
elif snippet_else is not None:
|
||||
return snippet_else
|
||||
|
||||
#
|
||||
# Handle tagged values
|
||||
#
|
||||
# module = {
|
||||
# extra_dist = ...
|
||||
# extra_dist = ...
|
||||
# ...
|
||||
# };
|
||||
#
|
||||
def foreach_value(defn, tag, closure):
|
||||
r = []
|
||||
for value in defn.find_all(tag):
|
||||
r.append(closure(value))
|
||||
return ''.join(r)
|
||||
|
||||
#
|
||||
# Handle best matched values for a platform, for example:
|
||||
#
|
||||
# module = {
|
||||
# cflags = '-Wall';
|
||||
# emu_cflags = '-Wall -DGRUB_EMU=1';
|
||||
# ...
|
||||
# }
|
||||
#
|
||||
def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure):
|
||||
r = []
|
||||
for group in RMAP[platform]:
|
||||
values = list(defn.find_all(group + suffix))
|
||||
if values:
|
||||
for value in values:
|
||||
r.append(closure(value))
|
||||
break
|
||||
else:
|
||||
for value in defn.find_all(nonetag):
|
||||
r.append(closure(value))
|
||||
return ''.join(r)
|
||||
|
||||
#
|
||||
# Handle values from sum of all groups for a platform, for example:
|
||||
#
|
||||
# module = {
|
||||
# common = kern/misc.c;
|
||||
# emu = kern/emu/misc.c;
|
||||
# ...
|
||||
# }
|
||||
#
|
||||
def foreach_platform_value(defn, platform, suffix, closure):
|
||||
r = []
|
||||
for group in RMAP[platform]:
|
||||
for value in defn.find_all(group + suffix):
|
||||
r.append(closure(value))
|
||||
return ''.join(r)
|
||||
|
||||
def platform_conditional(platform, closure):
|
||||
output("\nif COND_" + platform + "\n")
|
||||
closure(platform)
|
||||
output("endif\n")
|
||||
|
||||
#
|
||||
# Handle guarding with platform-specific "enable" keys, for example:
|
||||
#
|
||||
# module = {
|
||||
# name = pci;
|
||||
# noemu = bus/pci.c;
|
||||
# emu = bus/emu/pci.c;
|
||||
# emu = commands/lspci.c;
|
||||
#
|
||||
# enable = emu;
|
||||
# enable = i386_pc;
|
||||
# enable = x86_efi;
|
||||
# enable = i386_ieee1275;
|
||||
# enable = i386_coreboot;
|
||||
# };
|
||||
#
|
||||
def foreach_enabled_platform(defn, closure):
|
||||
if 'enable' in defn:
|
||||
for platform in GRUB_PLATFORMS:
|
||||
if platform_tagged(defn, platform, "enable"):
|
||||
platform_conditional(platform, closure)
|
||||
else:
|
||||
for platform in GRUB_PLATFORMS:
|
||||
platform_conditional(platform, closure)
|
||||
|
||||
#
|
||||
# Handle guarding with platform-specific automake conditionals, for example:
|
||||
#
|
||||
# module = {
|
||||
# name = usb;
|
||||
# common = bus/usb/usb.c;
|
||||
# noemu = bus/usb/usbtrans.c;
|
||||
# noemu = bus/usb/usbhub.c;
|
||||
# enable = emu;
|
||||
# enable = i386;
|
||||
# enable = mips_loongson;
|
||||
# emu_condition = COND_GRUB_EMU_SDL;
|
||||
# };
|
||||
#
|
||||
def under_platform_specific_conditionals(defn, platform, closure):
|
||||
output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n"))
|
||||
closure(defn, platform)
|
||||
output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n"))
|
||||
|
||||
def platform_specific_values(defn, platform, suffix, nonetag):
|
||||
return foreach_platform_specific_value(defn, platform, suffix, nonetag,
|
||||
lambda value: value + " ")
|
||||
|
||||
def platform_values(defn, platform, suffix):
|
||||
return foreach_platform_value(defn, platform, suffix, lambda value: value + " ")
|
||||
|
||||
def extra_dist(defn):
|
||||
return foreach_value(defn, "extra_dist", lambda value: value + " ")
|
||||
|
||||
def platform_sources(defn, p): return platform_values(defn, p, "")
|
||||
def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist")
|
||||
|
||||
def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup")
|
||||
def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd")
|
||||
def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies")
|
||||
def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags")
|
||||
def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags")
|
||||
def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags")
|
||||
def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags")
|
||||
def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags")
|
||||
def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags")
|
||||
|
||||
#
|
||||
# Emit snippet only the first time through for the current name.
|
||||
#
|
||||
seen_target = set()
|
||||
|
||||
def first_time(defn, snippet):
|
||||
if defn['name'] not in seen_target:
|
||||
return snippet
|
||||
return ''
|
||||
|
||||
def is_platform_independent(defn):
|
||||
if 'enable' in defn:
|
||||
return False
|
||||
for suffix in [ "", "_nodist" ]:
|
||||
template = platform_values(defn, GRUB_PLATFORMS[0], suffix)
|
||||
for platform in GRUB_PLATFORMS[1:]:
|
||||
if template != platform_values(defn, platform, suffix):
|
||||
return False
|
||||
|
||||
for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]:
|
||||
template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix)
|
||||
for platform in GRUB_PLATFORMS[1:]:
|
||||
if template != platform_specific_values(defn, platform, "_" + suffix, suffix):
|
||||
return False
|
||||
for tag in [ "nostrip" ]:
|
||||
template = platform_tagged(defn, GRUB_PLATFORMS[0], tag)
|
||||
for platform in GRUB_PLATFORMS[1:]:
|
||||
if template != platform_tagged(defn, platform, tag):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def module(defn, platform):
|
||||
name = defn['name']
|
||||
set_canonical_name_suffix(".module")
|
||||
|
||||
gvar_add("platform_PROGRAMS", name + ".module")
|
||||
gvar_add("MODULE_FILES", name + ".module$(EXEEXT)")
|
||||
|
||||
var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources")
|
||||
var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources")
|
||||
var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
|
||||
var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform))
|
||||
var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform))
|
||||
var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform))
|
||||
var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform))
|
||||
var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform))
|
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
|
||||
gvar_add("MOD_FILES", name + ".mod")
|
||||
gvar_add("MARKER_FILES", name + ".marker")
|
||||
gvar_add("CLEANFILES", name + ".marker")
|
||||
output("""
|
||||
""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES)
|
||||
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
|
||||
grep 'MARKER' $@.new > $@; rm -f $@.new
|
||||
""")
|
||||
|
||||
def kernel(defn, platform):
|
||||
name = defn['name']
|
||||
set_canonical_name_suffix(".exec")
|
||||
gvar_add("platform_PROGRAMS", name + ".exec")
|
||||
var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform))
|
||||
var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform))
|
||||
var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources")
|
||||
var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
|
||||
var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform))
|
||||
var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform))
|
||||
var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform))
|
||||
var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform))
|
||||
var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform))
|
||||
var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)")
|
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
|
||||
gvar_add("platform_DATA", name + ".img")
|
||||
gvar_add("CLEANFILES", name + ".img")
|
||||
rule(name + ".img", name + ".exec$(EXEEXT)",
|
||||
if_platform_tagged(defn, platform, "nostrip",
|
||||
"""if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||
$(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \
|
||||
elif test ! -z '$(TARGET_OBJ2ELF)'; then \
|
||||
$(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \
|
||||
else cp $< $@; fi""",
|
||||
"""if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||
$(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \
|
||||
$(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \
|
||||
rm -f $@.bin; \
|
||||
elif test ! -z '$(TARGET_OBJ2ELF)'; then \
|
||||
""" + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \
|
||||
$(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \
|
||||
rm -f $@.bin; \
|
||||
else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \
|
||||
fi"""))
|
||||
|
||||
def image(defn, platform):
|
||||
name = defn['name']
|
||||
set_canonical_name_suffix(".image")
|
||||
gvar_add("platform_PROGRAMS", name + ".image")
|
||||
var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
|
||||
var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources")
|
||||
var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
|
||||
var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform))
|
||||
var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform))
|
||||
var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform))
|
||||
var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform))
|
||||
var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform))
|
||||
# var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
|
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
|
||||
gvar_add("platform_DATA", name + ".img")
|
||||
gvar_add("CLEANFILES", name + ".img")
|
||||
rule(name + ".img", name + ".image$(EXEEXT)", """
|
||||
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||
$(MACHO2IMG) $< $@; \
|
||||
else \
|
||||
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \
|
||||
fi
|
||||
""")
|
||||
|
||||
def library(defn, platform):
|
||||
name = defn['name']
|
||||
set_canonical_name_suffix("")
|
||||
|
||||
vars_init(defn,
|
||||
cname(defn) + "_SOURCES",
|
||||
"nodist_" + cname(defn) + "_SOURCES",
|
||||
cname(defn) + "_CFLAGS",
|
||||
cname(defn) + "_CPPFLAGS",
|
||||
cname(defn) + "_CCASFLAGS")
|
||||
# cname(defn) + "_DEPENDENCIES")
|
||||
|
||||
if name not in seen_target:
|
||||
gvar_add("noinst_LIBRARIES", name)
|
||||
var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform))
|
||||
var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
|
||||
var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform))
|
||||
var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform))
|
||||
var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform))
|
||||
# var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
|
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
if name not in seen_target:
|
||||
gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
|
||||
def installdir(defn, default="bin"):
|
||||
return defn.get('installdir', default)
|
||||
|
||||
def manpage(defn, adddeps):
|
||||
name = defn['name']
|
||||
mansection = defn['mansection']
|
||||
|
||||
output("if COND_MAN_PAGES\n")
|
||||
gvar_add("man_MANS", name + "." + mansection)
|
||||
rule(name + "." + mansection, name + " " + adddeps, """
|
||||
chmod a+x """ + name + """
|
||||
PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """
|
||||
""")
|
||||
gvar_add("CLEANFILES", name + "." + mansection)
|
||||
output("endif\n")
|
||||
|
||||
def program(defn, platform, test=False):
|
||||
name = defn['name']
|
||||
set_canonical_name_suffix("")
|
||||
|
||||
if 'testcase' in defn:
|
||||
gvar_add("check_PROGRAMS", name)
|
||||
gvar_add("TESTS", name)
|
||||
else:
|
||||
var_add(installdir(defn) + "_PROGRAMS", name)
|
||||
if 'mansection' in defn:
|
||||
manpage(defn, "")
|
||||
|
||||
var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
|
||||
var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
|
||||
var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
|
||||
var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform))
|
||||
var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform))
|
||||
var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform))
|
||||
var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform))
|
||||
# var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
|
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
|
||||
|
||||
def data(defn, platform):
|
||||
var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||
|
||||
def transform_data(defn, platform):
|
||||
name = defn['name']
|
||||
|
||||
var_add(installdir(defn) + "_DATA", name)
|
||||
|
||||
rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
|
||||
(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
|
||||
chmod a+x """ + name + """
|
||||
""")
|
||||
|
||||
gvar_add("CLEANFILES", name)
|
||||
gvar_add("EXTRA_DIST", extra_dist(defn))
|
||||
gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
|
||||
|
||||
def script(defn, platform):
|
||||
name = defn['name']
|
||||
|
||||
if 'testcase' in defn:
|
||||
gvar_add("check_SCRIPTS", name)
|
||||
gvar_add ("TESTS", name)
|
||||
else:
|
||||
var_add(installdir(defn) + "_SCRIPTS", name)
|
||||
if 'mansection' in defn:
|
||||
manpage(defn, "grub-mkconfig_lib")
|
||||
|
||||
rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
|
||||
(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
|
||||
chmod a+x """ + name + """
|
||||
""")
|
||||
|
||||
gvar_add("CLEANFILES", name)
|
||||
gvar_add("EXTRA_DIST", extra_dist(defn))
|
||||
gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
|
||||
|
||||
def rules(target, closure):
|
||||
seen_target.clear()
|
||||
seen_vars.clear()
|
||||
|
||||
for defn in defparser.definitions.find_all(target):
|
||||
if is_platform_independent(defn):
|
||||
under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure)
|
||||
else:
|
||||
foreach_enabled_platform(
|
||||
defn,
|
||||
lambda p: under_platform_specific_conditionals(defn, p, closure))
|
||||
# Remember that we've seen this target.
|
||||
seen_target.add(defn['name'])
|
||||
|
||||
parser = OptionParser(usage="%prog DEFINITION-FILES")
|
||||
_, args = parser.parse_args()
|
||||
|
||||
for arg in args:
|
||||
defparser.read_definitions(arg)
|
||||
|
||||
rules("module", module)
|
||||
rules("kernel", kernel)
|
||||
rules("image", image)
|
||||
rules("library", library)
|
||||
rules("program", program)
|
||||
rules("script", script)
|
||||
rules("data", data)
|
||||
rules("transform_data", transform_data)
|
||||
|
||||
write_output(section='decl')
|
||||
write_output()
|
@ -1,507 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = subdir-objects -Wno-portability
|
||||
|
||||
DEPDIR=.deps-core
|
||||
|
||||
include $(top_srcdir)/conf/Makefile.common
|
||||
|
||||
CC=$(TARGET_CC)
|
||||
CPP=$(TARGET_CC)
|
||||
CCAS=$(TARGET_CC)
|
||||
RANLIB=$(TARGET_RANLIB)
|
||||
STRIP=$(TARGET_STRIP)
|
||||
|
||||
MACHO2IMG=$(top_builddir)/grub-macho2img
|
||||
|
||||
AM_CFLAGS = $(TARGET_CFLAGS)
|
||||
AM_LDFLAGS = $(TARGET_LDFLAGS)
|
||||
AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT)
|
||||
AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT)
|
||||
|
||||
CFLAGS_PROGRAM += $(CFLAGS_PLATFORM)
|
||||
LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM)
|
||||
CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM)
|
||||
CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM)
|
||||
|
||||
CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin
|
||||
CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM)
|
||||
CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM)
|
||||
|
||||
build-grub-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=64 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pep2elf\" $^
|
||||
CLEANFILES += build-grub-pep2elf$(BUILD_EXEEXT)
|
||||
|
||||
build-grub-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=32 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pe2elf\" $^
|
||||
CLEANFILES += build-grub-pe2elf$(BUILD_EXEEXT)
|
||||
|
||||
# gentrigtables
|
||||
gentrigtables$(BUILD_EXEEXT): gentrigtables.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM)
|
||||
CLEANFILES += gentrigtables$(BUILD_EXEEXT)
|
||||
|
||||
build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^
|
||||
CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT)
|
||||
|
||||
# trigtables.c
|
||||
trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac
|
||||
./gentrigtables$(BUILD_EXEEXT) > $@
|
||||
CLEANFILES += trigtables.c
|
||||
|
||||
# XXX Use Automake's LEX & YACC support
|
||||
grub_script.tab.h: script/parser.y
|
||||
$(YACC) -d -p grub_script_yy -b grub_script $<
|
||||
grub_script.tab.c: grub_script.tab.h
|
||||
CLEANFILES += grub_script.tab.c grub_script.tab.h
|
||||
|
||||
# For the lexer.
|
||||
grub_script.yy.h: script/yylex.l
|
||||
$(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $<
|
||||
grub_script.yy.c: grub_script.yy.h
|
||||
|
||||
rs_decoder.h: $(srcdir)/lib/reed_solomon.c
|
||||
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding
|
||||
|
||||
CLEANFILES += grub_script.yy.c grub_script.yy.h
|
||||
|
||||
include $(srcdir)/Makefile.core.am
|
||||
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||||
if COND_emu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
|
||||
else
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h
|
||||
endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||
|
||||
if COND_i386_pc
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_xen_pvh
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
|
||||
endif
|
||||
|
||||
if COND_i386_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_i386_coreboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_i386_multiboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_i386_qemu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_xen
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
endif
|
||||
|
||||
if COND_x86_64_xen
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
endif
|
||||
|
||||
if COND_x86_64_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_ia64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
|
||||
endif
|
||||
|
||||
if COND_mips_arc
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
endif
|
||||
|
||||
if COND_mips_qemu_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_mips_loongson
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_mips_qemu_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
endif
|
||||
|
||||
if COND_mips64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h
|
||||
endif
|
||||
|
||||
if COND_powerpc_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_sparc64_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_arm_uboot
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
|
||||
endif
|
||||
|
||||
if COND_arm_coreboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h
|
||||
endif
|
||||
|
||||
if COND_arm_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_arm64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv32_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_emu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
if COND_GRUB_EMU_SDL
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
|
||||
endif
|
||||
if COND_GRUB_EMU_PCI
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h
|
||||
endif
|
||||
endif
|
||||
|
||||
symlist.h: $(top_builddir)/config.h $(KERNEL_HEADER_FILES)
|
||||
@list='$^'; \
|
||||
for p in $$list; do \
|
||||
echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \
|
||||
done
|
||||
CLEANFILES += symlist.h
|
||||
BUILT_SOURCES += symlist.h
|
||||
|
||||
symlist.c: symlist.h gensymlist.sh
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
|
||||
cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
|
||||
rm -f symlist.p
|
||||
CLEANFILES += symlist.c
|
||||
BUILT_SOURCES += symlist.c
|
||||
|
||||
if COND_HAVE_ASM_USCORE
|
||||
ASM_PREFIX=_
|
||||
else
|
||||
ASM_PREFIX=
|
||||
endif
|
||||
|
||||
noinst_DATA += kernel_syms.lst
|
||||
|
||||
kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input
|
||||
cat kernel_syms.input | grep -v '^#' | sed -n \
|
||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
|
||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
|
||||
| sort -u >$@
|
||||
rm -f kernel_syms.input
|
||||
CLEANFILES += kernel_syms.lst
|
||||
|
||||
if COND_emu
|
||||
kern/emu/grub_emu-main.$(OBJEXT):grub_emu_init.h
|
||||
grub_emu-grub_emu_init.$(OBJEXT):grub_emu_init.h
|
||||
kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h
|
||||
grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h
|
||||
|
||||
grub_emu_init.h: genemuinitheader.sh $(MODULE_FILES)
|
||||
rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@
|
||||
CLEANFILES += grub_emu_init.h
|
||||
|
||||
grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MODULE_FILES)
|
||||
rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@
|
||||
CLEANFILES += grub_emu_init.c
|
||||
endif
|
||||
|
||||
# List files
|
||||
|
||||
fs.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += fs.lst
|
||||
CLEANFILES += fs.lst
|
||||
|
||||
command.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += command.lst
|
||||
CLEANFILES += command.lst
|
||||
|
||||
partmap.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += partmap.lst
|
||||
CLEANFILES += partmap.lst
|
||||
|
||||
terminal.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
|
||||
-e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += terminal.lst
|
||||
CLEANFILES += terminal.lst
|
||||
|
||||
fdt.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
|
||||
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += fdt.lst
|
||||
CLEANFILES += fdt.lst
|
||||
|
||||
parttool.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += parttool.lst
|
||||
CLEANFILES += parttool.lst
|
||||
|
||||
video.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += video.lst
|
||||
CLEANFILES += video.lst
|
||||
|
||||
# but, crypto.lst is simply copied
|
||||
crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst
|
||||
cp $^ $@
|
||||
platform_DATA += crypto.lst
|
||||
CLEANFILES += crypto.lst
|
||||
|
||||
syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES)
|
||||
cat kernel_syms.lst > $@.new
|
||||
for m in $(MODULE_FILES); do \
|
||||
sh $< $$m >> $@.new || exit 1; \
|
||||
done
|
||||
mv $@.new $@
|
||||
|
||||
# generate global module dependencies list
|
||||
moddep.lst: syminfo.lst genmoddep.awk video.lst
|
||||
cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1)
|
||||
platform_DATA += moddep.lst
|
||||
CLEANFILES += config.log syminfo.lst moddep.lst
|
||||
|
||||
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT)
|
||||
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
|
||||
platform_DATA += $(MOD_FILES)
|
||||
platform_DATA += modinfo.sh
|
||||
CLEANFILES += $(MOD_FILES)
|
||||
|
||||
if COND_ENABLE_EFIEMU
|
||||
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
|
||||
-rm -f $@
|
||||
-rm -f $@.bin
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $<
|
||||
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
|
||||
$(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
|
||||
rm -f $@.bin ; \
|
||||
elif test ! -z "$(TARGET_OBJ2ELF)"; then \
|
||||
$(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \
|
||||
mv $@.bin $@ ; \
|
||||
else \
|
||||
mv $@.bin $@ ; \
|
||||
fi
|
||||
|
||||
# Link format -arch,x86_64 means Apple linker
|
||||
efiemu64_c.o: efiemu/runtime/efiemu.c
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
|
||||
|
||||
efiemu64_s.o: efiemu/runtime/efiemu.S
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
|
||||
|
||||
efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
|
||||
-rm -f $@
|
||||
-rm -f $@.bin
|
||||
$(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^
|
||||
if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \
|
||||
$(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
|
||||
rm -f $@.bin; \
|
||||
else \
|
||||
mv $@.bin $@ ; \
|
||||
fi
|
||||
|
||||
platform_DATA += efiemu32.o efiemu64.o
|
||||
CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
|
||||
endif
|
||||
|
||||
windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
|
||||
windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
|
||||
test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform)
|
||||
for x in $(platform_DATA); do \
|
||||
cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \
|
||||
done
|
@ -100,10 +100,6 @@ kernel = {
|
||||
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
||||
arm_uboot_ldflags = '-Wl,-r,-d';
|
||||
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
||||
|
||||
mips64_efi_ldflags = '-Wl,-r,-d';
|
||||
mips64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame -R .MIPS.abiflags';
|
||||
|
||||
arm_coreboot_ldflags = '-Wl,-r,-d';
|
||||
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
||||
|
||||
@ -118,7 +114,6 @@ kernel = {
|
||||
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
||||
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
||||
mips_startup = kern/mips/startup.S;
|
||||
mips64_efi_startup = kern/mips64/efi/startup.S;
|
||||
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
|
||||
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
|
||||
arm_uboot_startup = kern/arm/startup.S;
|
||||
@ -315,15 +310,6 @@ kernel = {
|
||||
extra_dist = video/sis315_init.c;
|
||||
mips_loongson = commands/keylayouts.c;
|
||||
|
||||
mips64 = kern/mips64/init.c;
|
||||
mips64 = kern/mips64/dl.c;
|
||||
mips64 = kern/mips64/cache.S;
|
||||
mips64 = kern/generic/rtc_get_time_ms.c;
|
||||
mips64_efi = kern/mips64/efi/init.c;
|
||||
mips64_efi = kern/mips64/efi/loongson.c;
|
||||
mips64_efi = lib/mips64/efi/loongson.c;
|
||||
mips64_efi = lib/mips64/efi/loongson_asm.S;
|
||||
|
||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
@ -823,16 +809,6 @@ module = {
|
||||
common = commands/blocklist.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = blscfg;
|
||||
common = commands/blscfg.c;
|
||||
common = commands/loadenv.h;
|
||||
enable = powerpc_ieee1275;
|
||||
enable = efi;
|
||||
enable = i386_pc;
|
||||
enable = emu;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = boot;
|
||||
common = commands/boot.c;
|
||||
@ -842,7 +818,6 @@ module = {
|
||||
enable = sparc64_ieee1275;
|
||||
enable = powerpc_ieee1275;
|
||||
enable = mips_arc;
|
||||
enable = mips64_efi;
|
||||
enable = ia64_efi;
|
||||
enable = arm_efi;
|
||||
enable = arm64_efi;
|
||||
@ -913,12 +888,6 @@ module = {
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = fwload;
|
||||
efi = commands/efi/fwload.c;
|
||||
enable = efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = gptsync;
|
||||
common = commands/gptsync.c;
|
||||
@ -1017,7 +986,6 @@ module = {
|
||||
module = {
|
||||
name = loadenv;
|
||||
common = commands/loadenv.c;
|
||||
common = commands/loadenv.h;
|
||||
common = lib/envblk.c;
|
||||
};
|
||||
|
||||
@ -1129,21 +1097,6 @@ module = {
|
||||
common = commands/sleep.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = smbios;
|
||||
|
||||
common = commands/smbios.c;
|
||||
efi = commands/efi/smbios.c;
|
||||
i386_pc = commands/i386/pc/smbios.c;
|
||||
i386_coreboot = commands/i386/pc/smbios.c;
|
||||
i386_multiboot = commands/i386/pc/smbios.c;
|
||||
|
||||
enable = efi;
|
||||
enable = i386_pc;
|
||||
enable = i386_coreboot;
|
||||
enable = i386_multiboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = suspend;
|
||||
ieee1275 = commands/ieee1275/suspend.c;
|
||||
@ -1533,7 +1486,7 @@ module = {
|
||||
name = squash4;
|
||||
common = fs/squash4.c;
|
||||
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H';
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
|
||||
};
|
||||
|
||||
module = {
|
||||
@ -1624,29 +1577,12 @@ module = {
|
||||
module = {
|
||||
name = ventoy;
|
||||
common = ventoy/ventoy.c;
|
||||
common = ventoy/ventoy_cmd.c;
|
||||
common = ventoy/ventoy_linux.c;
|
||||
common = ventoy/ventoy_unix.c;
|
||||
common = ventoy/ventoy_windows.c;
|
||||
common = ventoy/ventoy_vhd.c;
|
||||
common = ventoy/ventoy_plugin.c;
|
||||
common = ventoy/ventoy_json.c;
|
||||
common = ventoy/ventoy_browser.c;
|
||||
common = ventoy/lzx.c;
|
||||
common = ventoy/xpress.c;
|
||||
common = ventoy/huffman.c;
|
||||
common = ventoy/miniz.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = setkey;
|
||||
common = term/setkey.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = mouse;
|
||||
efi = term/efi/mouse.c;
|
||||
enable = efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
@ -1711,8 +1647,6 @@ module = {
|
||||
efi = lib/efi/relocator.c;
|
||||
mips = lib/mips/relocator_asm.S;
|
||||
mips = lib/mips/relocator.c;
|
||||
mips64 = lib/mips64/relocator_asm.S;
|
||||
mips64 = lib/mips64/relocator.c;
|
||||
powerpc = lib/powerpc/relocator_asm.S;
|
||||
powerpc = lib/powerpc/relocator.c;
|
||||
xen = lib/xen/relocator.c;
|
||||
@ -1725,7 +1659,6 @@ module = {
|
||||
extra_dist = kern/powerpc/cache_flush.S;
|
||||
|
||||
enable = mips;
|
||||
enable = mips64;
|
||||
enable = powerpc;
|
||||
enable = x86;
|
||||
enable = i386_xen_pvh;
|
||||
@ -1856,7 +1789,6 @@ module = {
|
||||
i386_pc = lib/i386/pc/vesa_modes_table.c;
|
||||
i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
|
||||
mips = loader/mips/linux.c;
|
||||
mips64 = loader/mips64/linux.c;
|
||||
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
||||
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
||||
ia64_efi = loader/ia64/efi/linux.c;
|
||||
@ -1963,7 +1895,6 @@ module = {
|
||||
enable = riscv32_efi;
|
||||
enable = riscv64_efi;
|
||||
enable = mips;
|
||||
enable = mips64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -479,7 +479,7 @@ LOCAL(stop):
|
||||
jmp LOCAL(stop)
|
||||
|
||||
ventoy_uuid: .ascii "XXXXXXXXXXXXXXXX"
|
||||
notification_string: .asciz "VT"
|
||||
notification_string: .asciz "GR"
|
||||
geometry_error_string: .asciz "Ge"
|
||||
hd_probe_error_string: .asciz "HD"
|
||||
read_error_string: .asciz "Rd"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
|
||||
|
||||
static grub_efi_status_t
|
||||
grub_efi_connect_all (void)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t handle_count;
|
||||
grub_efi_handle_t *handle_buffer;
|
||||
grub_efi_uintn_t index;
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_dprintf ("efi", "Connecting ...\n");
|
||||
b = grub_efi_system_table->boot_services;
|
||||
status = efi_call_5 (b->locate_handle_buffer,
|
||||
GRUB_EFI_ALL_HANDLES, NULL, NULL,
|
||||
&handle_count, &handle_buffer);
|
||||
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
for (index = 0; index < handle_count; index++)
|
||||
{
|
||||
status = efi_call_4 (b->connect_controller,
|
||||
handle_buffer[index], NULL, NULL, 1);
|
||||
}
|
||||
|
||||
if (handle_buffer)
|
||||
{
|
||||
efi_call_1 (b->free_pool, handle_buffer);
|
||||
}
|
||||
return GRUB_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_efi_load_driver (grub_size_t size, void *boot_image, int connect)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_handle_t driver_handle;
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_efi_loaded_image_t *loaded_image;
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
|
||||
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, NULL,
|
||||
boot_image, size, &driver_handle);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
|
||||
else
|
||||
grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
goto fail;
|
||||
}
|
||||
loaded_image = grub_efi_get_loaded_image (driver_handle);
|
||||
if (! loaded_image)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
|
||||
goto fail;
|
||||
}
|
||||
grub_dprintf ("efi", "Registering loaded image\n");
|
||||
status = efi_call_3 (b->handle_protocol, driver_handle,
|
||||
&loaded_image_guid, (void **)&loaded_image);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "not a dirver");
|
||||
goto fail;
|
||||
}
|
||||
grub_dprintf ("efi", "StartImage: %p\n", boot_image);
|
||||
status = efi_call_3 (b->start_image, driver_handle, NULL, NULL);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "StartImage failed");
|
||||
goto fail;
|
||||
}
|
||||
if (connect)
|
||||
{
|
||||
status = grub_efi_connect_all ();
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "cannot connect controllers\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
grub_dprintf ("efi", "Driver installed\n");
|
||||
return 0;
|
||||
fail:
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static const struct grub_arg_option options_fwload[] =
|
||||
{
|
||||
{"nc", 'n', 0, N_("Loads the driver, but does not connect the driver."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_fwload (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int connect = 1;
|
||||
grub_file_t file = 0;
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t pages = 0;
|
||||
grub_ssize_t size;
|
||||
grub_efi_physical_address_t address;
|
||||
void *boot_image = 0;
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
if (argc != 1)
|
||||
goto fail;
|
||||
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
|
||||
if (! file)
|
||||
goto fail;
|
||||
size = grub_file_size (file);
|
||||
if (!size)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
|
||||
goto fail;
|
||||
}
|
||||
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
|
||||
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
|
||||
GRUB_EFI_LOADER_CODE, pages, &address);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
goto fail;
|
||||
}
|
||||
boot_image = (void *) ((grub_addr_t) address);
|
||||
if (grub_file_read (file, boot_image, size) != size)
|
||||
{
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
|
||||
goto fail;
|
||||
}
|
||||
grub_file_close (file);
|
||||
if (state[0].set)
|
||||
connect = 0;
|
||||
if (grub_efi_load_driver (size, boot_image, connect))
|
||||
goto fail;
|
||||
return GRUB_ERR_NONE;
|
||||
fail:
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
if (address)
|
||||
efi_call_2 (b->free_pages, address, pages);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_fwconnect (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_connect_all ();
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd_fwload, cmd_fwconnect;
|
||||
|
||||
GRUB_MOD_INIT(fwload)
|
||||
{
|
||||
cmd_fwload = grub_register_extcmd ("fwload", grub_cmd_fwload, 0, N_("FILE"),
|
||||
N_("Install UEFI driver."), options_fwload);
|
||||
cmd_fwconnect = grub_register_extcmd ("fwconnect", grub_cmd_fwconnect, 0,
|
||||
NULL, N_("Connect drivers."), 0);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(fwload)
|
||||
{
|
||||
grub_unregister_extcmd (cmd_fwload);
|
||||
grub_unregister_extcmd (cmd_fwconnect);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/* smbios.c - get smbios tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/smbios.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/api.h>
|
||||
|
||||
struct grub_smbios_eps *
|
||||
grub_machine_smbios_get_eps (void)
|
||||
{
|
||||
unsigned i;
|
||||
static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
{
|
||||
grub_efi_packed_guid_t *guid =
|
||||
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||
|
||||
if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t)))
|
||||
return (struct grub_smbios_eps *)
|
||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct grub_smbios_eps3 *
|
||||
grub_machine_smbios_get_eps3 (void)
|
||||
{
|
||||
unsigned i;
|
||||
static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
{
|
||||
grub_efi_packed_guid_t *guid =
|
||||
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||
|
||||
if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t)))
|
||||
return (struct grub_smbios_eps3 *)
|
||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,351 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
|
||||
{"check", 'c', 0, N_("Check hashes of files with hash list FILE."),
|
||||
N_("FILE"), ARG_TYPE_STRING},
|
||||
{"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"),
|
||||
ARG_TYPE_STRING},
|
||||
{"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
|
||||
{"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct { const char *name; const char *hashname; } aliases[] =
|
||||
{
|
||||
{"sha256sum", "sha256"},
|
||||
{"sha512sum", "sha512"},
|
||||
{"sha1sum", "sha1"},
|
||||
{"md5sum", "md5"},
|
||||
{"crc", "crc32"},
|
||||
};
|
||||
|
||||
static inline int
|
||||
hextoval (char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
|
||||
{
|
||||
int progress = 0;
|
||||
grub_uint64_t ro = 0;
|
||||
grub_uint64_t div = 0;
|
||||
grub_uint64_t total = 0;
|
||||
void *context;
|
||||
grub_uint8_t *readbuf;
|
||||
#define BUF_SIZE 1024 * 1024
|
||||
readbuf = grub_malloc (BUF_SIZE);
|
||||
if (!readbuf)
|
||||
return grub_errno;
|
||||
context = grub_zalloc (hash->contextsize);
|
||||
if (!readbuf || !context)
|
||||
goto fail;
|
||||
|
||||
if (file->size > 16 * 1024 * 1024)
|
||||
progress = 1;
|
||||
|
||||
hash->init (context);
|
||||
while (1)
|
||||
{
|
||||
grub_ssize_t r;
|
||||
r = grub_file_read (file, readbuf, BUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0)
|
||||
break;
|
||||
hash->write (context, readbuf, r);
|
||||
if (progress)
|
||||
{
|
||||
total += r;
|
||||
div = grub_divmod64(total * 100, (grub_uint64_t)file->size, &ro);
|
||||
grub_printf("\rCalculating %s %d%% ", hash->name, (int)div);
|
||||
grub_refresh();
|
||||
}
|
||||
}
|
||||
hash->final (context);
|
||||
grub_memcpy (result, hash->read (context), hash->mdlen);
|
||||
|
||||
grub_free (readbuf);
|
||||
grub_free (context);
|
||||
if (progress)
|
||||
{
|
||||
grub_printf("\rCalculating %s 100%% \n\r\n", hash->name);
|
||||
grub_refresh();
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
grub_free (readbuf);
|
||||
grub_free (context);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||
const char *prefix, int keep, int uncompress)
|
||||
{
|
||||
grub_file_t hashlist, file;
|
||||
char *buf = NULL;
|
||||
grub_uint8_t expected[GRUB_CRYPTO_MAX_MDLEN];
|
||||
grub_uint8_t actual[GRUB_CRYPTO_MAX_MDLEN];
|
||||
grub_err_t err;
|
||||
unsigned i;
|
||||
unsigned unread = 0, mismatch = 0;
|
||||
|
||||
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||
|
||||
hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST);
|
||||
if (!hashlist)
|
||||
return grub_errno;
|
||||
|
||||
while (grub_free (buf), (buf = grub_file_getline (hashlist)))
|
||||
{
|
||||
const char *p = buf;
|
||||
while (grub_isspace (p[0]))
|
||||
p++;
|
||||
for (i = 0; i < hash->mdlen; i++)
|
||||
{
|
||||
int high, low;
|
||||
high = hextoval (*p++);
|
||||
low = hextoval (*p++);
|
||||
if (high < 0 || low < 0)
|
||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||
expected[i] = (high << 4) | low;
|
||||
}
|
||||
if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t'))
|
||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||
p += 2;
|
||||
if (prefix)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = grub_xasprintf ("%s/%s", prefix, p);
|
||||
if (!filename)
|
||||
return grub_errno;
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: GRUB_FILE_TYPE_NONE));
|
||||
grub_free (filename);
|
||||
}
|
||||
else
|
||||
file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: GRUB_FILE_TYPE_NONE));
|
||||
if (!file)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
grub_free (buf);
|
||||
return grub_errno;
|
||||
}
|
||||
err = hash_file (file, hash, actual);
|
||||
grub_file_close (file);
|
||||
if (err)
|
||||
{
|
||||
grub_printf_ (N_("%s: READ ERROR\n"), p);
|
||||
if (!keep)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
grub_free (buf);
|
||||
return err;
|
||||
}
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
|
||||
{
|
||||
grub_printf_ (N_("%s: HASH MISMATCH\n"), p);
|
||||
if (!keep)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
grub_free (buf);
|
||||
return grub_error (GRUB_ERR_TEST_FAILURE,
|
||||
"hash of '%s' mismatches", p);
|
||||
}
|
||||
mismatch++;
|
||||
continue;
|
||||
}
|
||||
grub_printf_ (N_("%s: OK\n"), p);
|
||||
}
|
||||
if (mismatch || unread)
|
||||
return grub_error (GRUB_ERR_TEST_FAILURE,
|
||||
"%d files couldn't be read and hash "
|
||||
"of %d files mismatches", unread, mismatch);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
const char *hashname = NULL;
|
||||
const char *prefix = NULL;
|
||||
const gcry_md_spec_t *hash;
|
||||
unsigned i;
|
||||
int keep = state[3].set;
|
||||
int uncompress = state[4].set;
|
||||
unsigned unread = 0;
|
||||
int len = 0;
|
||||
char hashsum[256];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (aliases); i++)
|
||||
if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0)
|
||||
hashname = aliases[i].hashname;
|
||||
if (state[0].set)
|
||||
hashname = state[0].arg;
|
||||
|
||||
if (!hashname)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified");
|
||||
|
||||
hash = grub_crypto_lookup_md_by_name (hashname);
|
||||
if (!hash)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash");
|
||||
|
||||
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||
|
||||
if (state[2].set)
|
||||
prefix = state[2].arg;
|
||||
|
||||
if (state[1].set)
|
||||
{
|
||||
if (argc != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"--check is incompatible with file list");
|
||||
return check_list (hash, state[1].arg, prefix, keep, uncompress);
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned) argc; i++)
|
||||
{
|
||||
GRUB_PROPERLY_ALIGNED_ARRAY (result, GRUB_CRYPTO_MAX_MDLEN);
|
||||
grub_file_t file;
|
||||
grub_err_t err;
|
||||
unsigned j;
|
||||
int vlnk = 0;
|
||||
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: GRUB_FILE_TYPE_NONE));
|
||||
if (!file)
|
||||
{
|
||||
if (!keep)
|
||||
return grub_errno;
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
vlnk = file->vlnk;
|
||||
err = hash_file (file, hash, result);
|
||||
grub_file_close (file);
|
||||
if (err)
|
||||
{
|
||||
if (!keep)
|
||||
return err;
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < hash->mdlen; j++)
|
||||
{
|
||||
grub_printf ("%02x", ((grub_uint8_t *) result)[j]);
|
||||
len += grub_snprintf(hashsum + len, sizeof(hashsum) - len, "%02x", ((grub_uint8_t *) result)[j]);
|
||||
}
|
||||
grub_printf (" %s\n", vlnk ? grub_file_get_vlnk(args[i], NULL) : args[i]);
|
||||
grub_env_set("VT_LAST_CHECK_SUM", hashsum);
|
||||
}
|
||||
|
||||
if (unread)
|
||||
return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read",
|
||||
unread);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc;
|
||||
|
||||
GRUB_MOD_INIT(hashsum)
|
||||
{
|
||||
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0,
|
||||
N_("-h HASH [-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
/* TRANSLATORS: "hash checksum" is just to
|
||||
be a bit more precise, you can treat it as
|
||||
just "hash". */
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
|
||||
cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(hashsum)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_md5);
|
||||
grub_unregister_extcmd (cmd_sha1);
|
||||
grub_unregister_extcmd (cmd_sha256);
|
||||
grub_unregister_extcmd (cmd_sha512);
|
||||
grub_unregister_extcmd (cmd_crc);
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* smbios.c - get smbios tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/smbios.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
struct grub_smbios_eps *
|
||||
grub_machine_smbios_get_eps (void)
|
||||
{
|
||||
grub_uint8_t *ptr;
|
||||
|
||||
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
||||
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
||||
return (struct grub_smbios_eps *) ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct grub_smbios_eps3 *
|
||||
grub_machine_smbios_get_eps3 (void)
|
||||
{
|
||||
grub_uint8_t *ptr;
|
||||
|
||||
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
||||
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
||||
return (struct grub_smbios_eps3 *) ptr;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,894 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000, 2001, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/legacy_parse.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/auth.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Helper for legacy_file. */
|
||||
static grub_err_t
|
||||
legacy_file_getline (char **line, int cont __attribute__ ((unused)),
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
*line = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
legacy_file (const char *filename)
|
||||
{
|
||||
grub_file_t file;
|
||||
char *entryname = NULL, *entrysrc = NULL;
|
||||
grub_menu_t menu;
|
||||
char *suffix = grub_strdup ("");
|
||||
|
||||
if (!suffix)
|
||||
return grub_errno;
|
||||
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG);
|
||||
if (! file)
|
||||
{
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
menu = grub_env_get_menu ();
|
||||
if (! menu)
|
||||
{
|
||||
menu = grub_zalloc (sizeof (*menu));
|
||||
if (! menu)
|
||||
{
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_env_set_menu (menu);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *buf = grub_file_getline (file);
|
||||
char *parsed = NULL;
|
||||
|
||||
if (!buf && grub_errno)
|
||||
{
|
||||
grub_file_close (file);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
break;
|
||||
|
||||
{
|
||||
char *oldname = NULL;
|
||||
char *newsuffix;
|
||||
char *ptr;
|
||||
|
||||
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
|
||||
|
||||
oldname = entryname;
|
||||
parsed = grub_legacy_parse (ptr, &entryname, &newsuffix);
|
||||
grub_free (buf);
|
||||
buf = NULL;
|
||||
if (newsuffix)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = suffix;
|
||||
suffix = grub_realloc (suffix, grub_strlen (suffix)
|
||||
+ grub_strlen (newsuffix) + 1);
|
||||
if (!suffix)
|
||||
{
|
||||
grub_free (t);
|
||||
grub_free (entrysrc);
|
||||
grub_free (parsed);
|
||||
grub_free (newsuffix);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (suffix + grub_strlen (suffix), newsuffix,
|
||||
grub_strlen (newsuffix) + 1);
|
||||
grub_free (newsuffix);
|
||||
newsuffix = NULL;
|
||||
}
|
||||
if (oldname != entryname && oldname)
|
||||
{
|
||||
const char **args = grub_malloc (sizeof (args[0]));
|
||||
if (!args)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
args[0] = oldname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
|
||||
NULL, NULL,
|
||||
entrysrc, 0, NULL, NULL);
|
||||
grub_free (args);
|
||||
entrysrc[0] = 0;
|
||||
grub_free (oldname);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed && !entryname)
|
||||
{
|
||||
grub_normal_parse_line (parsed, legacy_file_getline, NULL);
|
||||
grub_print_error ();
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
else if (parsed)
|
||||
{
|
||||
if (!entrysrc)
|
||||
entrysrc = parsed;
|
||||
else
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = entrysrc;
|
||||
entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
|
||||
+ grub_strlen (parsed) + 1);
|
||||
if (!entrysrc)
|
||||
{
|
||||
grub_free (t);
|
||||
grub_free (parsed);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed,
|
||||
grub_strlen (parsed) + 1);
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
grub_file_close (file);
|
||||
|
||||
if (entryname)
|
||||
{
|
||||
const char **args = grub_malloc (sizeof (args[0]));
|
||||
if (!args)
|
||||
{
|
||||
grub_file_close (file);
|
||||
grub_free (suffix);
|
||||
grub_free (entrysrc);
|
||||
return grub_errno;
|
||||
}
|
||||
args[0] = entryname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
|
||||
NULL, NULL, entrysrc, 0, NULL,
|
||||
NULL);
|
||||
grub_free (args);
|
||||
}
|
||||
|
||||
grub_normal_parse_line (suffix, legacy_file_getline, NULL);
|
||||
grub_print_error ();
|
||||
grub_free (suffix);
|
||||
grub_free (entrysrc);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_source (struct grub_command *cmd,
|
||||
int argc, char **args)
|
||||
{
|
||||
int new_env, extractor;
|
||||
grub_err_t ret;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
extractor = (cmd->name[0] == 'e');
|
||||
new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1)
|
||||
: (sizeof ("legacy_") - 1)] == 'c');
|
||||
|
||||
if (new_env)
|
||||
grub_cls ();
|
||||
|
||||
if (new_env && !extractor)
|
||||
grub_env_context_open ();
|
||||
if (extractor)
|
||||
grub_env_extractor_open (!new_env);
|
||||
|
||||
ret = legacy_file (args[0]);
|
||||
|
||||
if (new_env)
|
||||
{
|
||||
grub_menu_t menu;
|
||||
menu = grub_env_get_menu ();
|
||||
if (menu && menu->size)
|
||||
grub_show_menu (menu, 1, 0);
|
||||
if (!extractor)
|
||||
grub_env_context_close ();
|
||||
}
|
||||
if (extractor)
|
||||
grub_env_extractor_close (!new_env);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum
|
||||
{
|
||||
GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD
|
||||
} kernel_type;
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
#ifdef TODO
|
||||
int no_mem_option = 0;
|
||||
#endif
|
||||
struct grub_command *cmd;
|
||||
char **cutargs;
|
||||
int cutargc;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* FIXME: really support this. */
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0)
|
||||
{
|
||||
#ifdef TODO
|
||||
no_mem_option = 1;
|
||||
#endif
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* linux16 handles both zImages and bzImages. */
|
||||
if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0
|
||||
|| grub_strcmp (args[0], "--type=biglinux") == 0))
|
||||
{
|
||||
kernel_type = LINUX;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0)
|
||||
{
|
||||
kernel_type = MULTIBOOT;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0)
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0)
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0)
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
|
||||
if (!cutargs)
|
||||
return grub_errno;
|
||||
cutargc = argc - 1;
|
||||
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
|
||||
cutargs[0] = args[0];
|
||||
|
||||
do
|
||||
{
|
||||
/* First try Linux. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == LINUX)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
cmd = grub_command_find ("linux16");
|
||||
#else
|
||||
cmd = grub_command_find ("linux");
|
||||
#endif
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = LINUX;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Then multiboot. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT)
|
||||
{
|
||||
cmd = grub_command_find ("multiboot");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, argc, args))
|
||||
{
|
||||
kernel_type = MULTIBOOT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
{
|
||||
int bsd_device = -1;
|
||||
int bsd_slice = -1;
|
||||
int bsd_part = -1;
|
||||
{
|
||||
grub_device_t dev;
|
||||
const char *hdbiasstr;
|
||||
int hdbias = 0;
|
||||
hdbiasstr = grub_env_get ("legacy_hdbias");
|
||||
if (hdbiasstr)
|
||||
{
|
||||
hdbias = grub_strtoul (hdbiasstr, 0, 0);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk
|
||||
&& dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID
|
||||
&& dev->disk->id >= 0x80 && dev->disk->id <= 0x90)
|
||||
{
|
||||
struct grub_partition *part = dev->disk->partition;
|
||||
bsd_device = dev->disk->id - 0x80 - hdbias;
|
||||
if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "openbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "bsd") == 0))
|
||||
{
|
||||
bsd_part = part->number;
|
||||
part = part->parent;
|
||||
}
|
||||
if (part && grub_strcmp (part->partmap->name, "msdos") == 0)
|
||||
bsd_slice = part->number;
|
||||
}
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
}
|
||||
|
||||
/* k*BSD didn't really work well with grub-legacy. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == KFREEBSD)
|
||||
{
|
||||
char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")];
|
||||
if (bsd_device != -1)
|
||||
{
|
||||
if (bsd_slice != -1 && bsd_part != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device,
|
||||
bsd_slice, 'a' + bsd_part);
|
||||
else if (bsd_slice != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device,
|
||||
bsd_slice);
|
||||
else
|
||||
grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device);
|
||||
grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf);
|
||||
}
|
||||
else
|
||||
grub_env_unset ("kFreeBSD.vfs.root.mountfrom");
|
||||
cmd = grub_command_find ("kfreebsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
{
|
||||
char **bsdargs;
|
||||
int bsdargc;
|
||||
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
|
||||
int found = 0;
|
||||
|
||||
if (bsd_device == -1)
|
||||
{
|
||||
bsdargs = cutargs;
|
||||
bsdargc = cutargc;
|
||||
}
|
||||
else
|
||||
{
|
||||
char rbuf[3] = "-r";
|
||||
bsdargc = cutargc + 2;
|
||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
||||
if (!bsdargs)
|
||||
{
|
||||
err = grub_errno;
|
||||
goto out;
|
||||
}
|
||||
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
|
||||
bsdargs[argc] = rbuf;
|
||||
bsdargs[argc + 1] = bsddevname;
|
||||
grub_snprintf (bsddevname, sizeof (bsddevname),
|
||||
"wd%d%c", bsd_device,
|
||||
bsd_part != -1 ? bsd_part + 'a' : 'c');
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
|
||||
{
|
||||
cmd = grub_command_find ("knetbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
found = 1;
|
||||
goto free_bsdargs;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
|
||||
{
|
||||
cmd = grub_command_find ("kopenbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
found = 1;
|
||||
goto free_bsdargs;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
free_bsdargs:
|
||||
if (bsdargs != cutargs)
|
||||
grub_free (bsdargs);
|
||||
if (found)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
|
||||
args[0]);
|
||||
out:
|
||||
grub_free (cutargs);
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_command *cmd;
|
||||
|
||||
if (kernel_type == LINUX)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
cmd = grub_command_find ("initrd16");
|
||||
#else
|
||||
cmd = grub_command_find ("initrd");
|
||||
#endif
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
"initrd16"
|
||||
#else
|
||||
"initrd"
|
||||
#endif
|
||||
);
|
||||
|
||||
return cmd->func (cmd, argc ? 1 : 0, args);
|
||||
}
|
||||
if (kernel_type == MULTIBOOT)
|
||||
{
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"module");
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_command *cmd;
|
||||
|
||||
if (kernel_type == LINUX)
|
||||
{
|
||||
cmd = grub_command_find ("initrd16");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"initrd16");
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
}
|
||||
if (kernel_type == MULTIBOOT)
|
||||
{
|
||||
char **newargs;
|
||||
grub_err_t err;
|
||||
char nounzipbuf[10] = "--nounzip";
|
||||
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"module");
|
||||
|
||||
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
|
||||
if (!newargs)
|
||||
return grub_errno;
|
||||
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
|
||||
newargs[0] = nounzipbuf;
|
||||
|
||||
err = cmd->func (cmd, argc + 1, newargs);
|
||||
grub_free (newargs);
|
||||
return err;
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_password_deny (const char *user __attribute__ ((unused)),
|
||||
const char *entered __attribute__ ((unused)),
|
||||
void *password __attribute__ ((unused)))
|
||||
{
|
||||
return GRUB_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
#define MD5_HASHLEN 16
|
||||
|
||||
struct legacy_md5_password
|
||||
{
|
||||
grub_uint8_t *salt;
|
||||
int saltlen;
|
||||
grub_uint8_t hash[MD5_HASHLEN];
|
||||
};
|
||||
|
||||
static int
|
||||
check_password_md5_real (const char *entered,
|
||||
struct legacy_md5_password *pw)
|
||||
{
|
||||
grub_size_t enteredlen = grub_strlen (entered);
|
||||
unsigned char alt_result[MD5_HASHLEN];
|
||||
unsigned char *digest;
|
||||
grub_uint8_t *ctx;
|
||||
grub_size_t i;
|
||||
int ret;
|
||||
|
||||
ctx = grub_zalloc (GRUB_MD_MD5->contextsize);
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
grub_memcpy (alt_result, digest, MD5_HASHLEN);
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */
|
||||
for (i = enteredlen; i > 16; i -= 16)
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
GRUB_MD_MD5->write (ctx, alt_result, i);
|
||||
|
||||
for (i = enteredlen; i > 0; i >>= 1)
|
||||
GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
grub_memcpy (alt_result, digest, 16);
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
if ((i & 1) != 0)
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
else
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
|
||||
if (i % 3 != 0)
|
||||
GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
|
||||
|
||||
if (i % 7 != 0)
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
|
||||
if ((i & 1) != 0)
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
else
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
}
|
||||
|
||||
ret = (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0);
|
||||
grub_free (ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_password_md5 (const char *user,
|
||||
const char *entered,
|
||||
void *password)
|
||||
{
|
||||
if (!check_password_md5_real (entered, password))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
grub_auth_authenticate (user);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ib64t (char c)
|
||||
{
|
||||
if (c == '.')
|
||||
return 0;
|
||||
if (c == '/')
|
||||
return 1;
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0' + 2;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return c - 'A' + 12;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 'a' + 38;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct legacy_md5_password *
|
||||
parse_legacy_md5 (int argc, char **args)
|
||||
{
|
||||
const char *salt, *saltend;
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0)
|
||||
goto fail;
|
||||
if (argc == 1)
|
||||
goto fail;
|
||||
if (grub_strlen(args[1]) <= 3)
|
||||
goto fail;
|
||||
salt = args[1];
|
||||
saltend = grub_strchr (salt + 3, '$');
|
||||
if (!saltend)
|
||||
goto fail;
|
||||
pw = grub_malloc (sizeof (*pw));
|
||||
if (!pw)
|
||||
goto fail;
|
||||
|
||||
p = saltend + 1;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
int n;
|
||||
grub_uint32_t w = 0;
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
int ww = ib64t(*p++);
|
||||
if (ww == -1)
|
||||
goto fail;
|
||||
w |= ww << (n * 6);
|
||||
}
|
||||
pw->hash[i == 4 ? 5 : 12+i] = w & 0xff;
|
||||
pw->hash[6+i] = (w >> 8) & 0xff;
|
||||
pw->hash[i] = (w >> 16) & 0xff;
|
||||
}
|
||||
{
|
||||
int n;
|
||||
grub_uint32_t w = 0;
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
int ww = ib64t(*p++);
|
||||
if (ww == -1)
|
||||
goto fail;
|
||||
w |= ww << (6 * n);
|
||||
}
|
||||
if (w >= 0x100)
|
||||
goto fail;
|
||||
pw->hash[11] = w;
|
||||
}
|
||||
|
||||
pw->saltlen = saltend - salt;
|
||||
pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen);
|
||||
if (!pw->salt)
|
||||
goto fail;
|
||||
|
||||
return pw;
|
||||
|
||||
fail:
|
||||
grub_free (pw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
if (args[0][0] != '-' || args[0][1] != '-')
|
||||
return grub_normal_set_password ("legacy", args[0]);
|
||||
|
||||
pw = parse_legacy_md5 (argc, args);
|
||||
|
||||
if (pw)
|
||||
return grub_auth_register_authentication ("legacy", check_password_md5, pw);
|
||||
else
|
||||
/* This is to imitate minor difference between grub-legacy in GRUB2.
|
||||
If 2 password commands are executed in a row and second one fails
|
||||
on GRUB2 the password of first one is used, whereas in grub-legacy
|
||||
authenthication is denied. In case of no password command was executed
|
||||
early both versions deny any access. */
|
||||
return grub_auth_register_authentication ("legacy", check_password_deny,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
grub_legacy_check_md5_password (int argc, char **args,
|
||||
char *entered)
|
||||
{
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
int ret;
|
||||
|
||||
if (args[0][0] != '-' || args[0][1] != '-')
|
||||
{
|
||||
char correct[GRUB_AUTH_MAX_PASSLEN];
|
||||
|
||||
grub_memset (correct, 0, sizeof (correct));
|
||||
grub_strncpy (correct, args[0], sizeof (correct));
|
||||
|
||||
return grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) == 0;
|
||||
}
|
||||
|
||||
pw = parse_legacy_md5 (argc, args);
|
||||
|
||||
if (!pw)
|
||||
return 0;
|
||||
|
||||
ret = check_password_md5_real (entered, pw);
|
||||
grub_free (pw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
grub_puts_ (N_("Enter password: "));
|
||||
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
if (!grub_legacy_check_md5_password (argc, args,
|
||||
entered))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd_source, cmd_configfile;
|
||||
static grub_command_t cmd_source_extract, cmd_configfile_extract;
|
||||
static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip;
|
||||
static grub_command_t cmd_password, cmd_check_password;
|
||||
|
||||
GRUB_MOD_INIT(legacycfg)
|
||||
{
|
||||
cmd_source
|
||||
= grub_register_command ("legacy_source",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
/* TRANSLATORS: "legacy config" means
|
||||
"config as used by grub-legacy". */
|
||||
N_("Parse legacy config in same context"));
|
||||
cmd_configfile
|
||||
= grub_register_command ("legacy_configfile",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in new context"));
|
||||
cmd_source_extract
|
||||
= grub_register_command ("extract_legacy_entries_source",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in same context taking only menu entries"));
|
||||
cmd_configfile_extract
|
||||
= grub_register_command ("extract_legacy_entries_configfile",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in new context taking only menu entries"));
|
||||
|
||||
cmd_kernel = grub_register_command ("legacy_kernel",
|
||||
grub_cmd_legacy_kernel,
|
||||
N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy `kernel' command"));
|
||||
|
||||
cmd_initrd = grub_register_command ("legacy_initrd",
|
||||
grub_cmd_legacy_initrd,
|
||||
N_("FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy `initrd' command"));
|
||||
cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip",
|
||||
grub_cmd_legacy_initrdnounzip,
|
||||
N_("FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy `modulenounzip' command"));
|
||||
|
||||
cmd_password = grub_register_command ("legacy_password",
|
||||
grub_cmd_legacy_password,
|
||||
N_("[--md5] PASSWD [FILE]"),
|
||||
N_("Simulate grub-legacy `password' command"));
|
||||
|
||||
cmd_check_password = grub_register_command ("legacy_check_password",
|
||||
grub_cmd_legacy_check_password,
|
||||
N_("[--md5] PASSWD [FILE]"),
|
||||
N_("Simulate grub-legacy `password' command in menu entry mode"));
|
||||
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(legacycfg)
|
||||
{
|
||||
grub_unregister_command (cmd_source);
|
||||
grub_unregister_command (cmd_configfile);
|
||||
grub_unregister_command (cmd_source_extract);
|
||||
grub_unregister_command (cmd_configfile_extract);
|
||||
|
||||
grub_unregister_command (cmd_kernel);
|
||||
grub_unregister_command (cmd_initrd);
|
||||
grub_unregister_command (cmd_initrdnounzip);
|
||||
|
||||
grub_unregister_command (cmd_password);
|
||||
grub_unregister_command (cmd_check_password);
|
||||
}
|
@ -1,397 +0,0 @@
|
||||
/* loadenv.c - command to load/save environment variable. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/lib/envblk.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
#include "loadenv.h"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
/* TRANSLATORS: This option is used to override default filename
|
||||
for loading and storing environment. */
|
||||
{"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME},
|
||||
{"skip-sig", 's', 0,
|
||||
N_("Skip signature-checking of the environment file."), 0, ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* Opens 'filename' with compression filters disabled. Optionally disables the
|
||||
PUBKEY filter (that insists upon properly signed files) as well. PUBKEY
|
||||
filter is restored before the function returns. */
|
||||
static grub_file_t
|
||||
open_envblk_file (char *filename,
|
||||
enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
char *buf = 0;
|
||||
|
||||
if (! filename)
|
||||
{
|
||||
const char *prefix;
|
||||
int len;
|
||||
|
||||
prefix = grub_env_get ("prefix");
|
||||
if (! prefix)
|
||||
{
|
||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = grub_strlen (prefix);
|
||||
buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
|
||||
if (! buf)
|
||||
return 0;
|
||||
filename = buf;
|
||||
|
||||
grub_strcpy (filename, prefix);
|
||||
filename[len] = '/';
|
||||
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
|
||||
}
|
||||
|
||||
file = grub_file_open (filename, type);
|
||||
|
||||
grub_free (buf);
|
||||
return file;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
grub_env_whitelist_t whitelist;
|
||||
|
||||
whitelist.len = argc;
|
||||
whitelist.list = args;
|
||||
|
||||
/* state[0] is the -f flag; state[1] is the --skip-sig flag */
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
GRUB_FILE_TYPE_LOADENV
|
||||
| (state[1].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE));
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
envblk = read_envblk_file (file);
|
||||
if (! envblk)
|
||||
goto fail;
|
||||
|
||||
/* argc > 0 indicates caller provided a whitelist of variables to read. */
|
||||
grub_envblk_iterate (envblk, argc > 0 ? &whitelist : 0, set_var);
|
||||
grub_envblk_close (envblk);
|
||||
|
||||
fail:
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
/* Print all variables in current context. */
|
||||
static int
|
||||
print_var (const char *name, const char *value,
|
||||
void *hook_data __attribute__ ((unused)))
|
||||
{
|
||||
grub_printf ("%s=%s\n", name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_list_env (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
GRUB_FILE_TYPE_LOADENV
|
||||
| (state[1].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE));
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
envblk = read_envblk_file (file);
|
||||
if (! envblk)
|
||||
goto fail;
|
||||
|
||||
grub_envblk_iterate (envblk, NULL, print_var);
|
||||
grub_envblk_close (envblk);
|
||||
|
||||
fail:
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
/* Used to maintain a variable length of blocklists internally. */
|
||||
struct blocklist
|
||||
{
|
||||
grub_disk_addr_t sector;
|
||||
unsigned offset;
|
||||
unsigned length;
|
||||
struct blocklist *next;
|
||||
};
|
||||
|
||||
static void
|
||||
free_blocklists (struct blocklist *p)
|
||||
{
|
||||
struct blocklist *q;
|
||||
|
||||
for (; p; p = q)
|
||||
{
|
||||
q = p->next;
|
||||
grub_free (p);
|
||||
}
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
||||
grub_file_t file)
|
||||
{
|
||||
grub_size_t total_length;
|
||||
grub_size_t index;
|
||||
grub_disk_t disk;
|
||||
grub_disk_addr_t part_start;
|
||||
struct blocklist *p;
|
||||
char *buf;
|
||||
|
||||
/* Sanity checks. */
|
||||
total_length = 0;
|
||||
for (p = blocklists; p; p = p->next)
|
||||
{
|
||||
struct blocklist *q;
|
||||
/* Check if any pair of blocks overlap. */
|
||||
for (q = p->next; q; q = q->next)
|
||||
{
|
||||
grub_disk_addr_t s1, s2;
|
||||
grub_disk_addr_t e1, e2;
|
||||
|
||||
s1 = p->sector;
|
||||
e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
s2 = q->sector;
|
||||
e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
if (s1 < e2 && s2 < e1)
|
||||
{
|
||||
/* This might be actually valid, but it is unbelievable that
|
||||
any filesystem makes such a silly allocation. */
|
||||
return grub_error (GRUB_ERR_BAD_FS, "malformed file");
|
||||
}
|
||||
}
|
||||
|
||||
total_length += p->length;
|
||||
}
|
||||
|
||||
if (total_length != grub_file_size (file))
|
||||
{
|
||||
/* Maybe sparse, unallocated sectors. No way in GRUB. */
|
||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed");
|
||||
}
|
||||
|
||||
/* One more sanity check. Re-read all sectors by blocklists, and compare
|
||||
those with the data read via a file. */
|
||||
disk = file->device->disk;
|
||||
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
|
||||
buf = grub_envblk_buffer (envblk);
|
||||
char *blockbuf = NULL;
|
||||
grub_size_t blockbuf_len = 0;
|
||||
for (p = blocklists, index = 0; p; index += p->length, p = p->next)
|
||||
{
|
||||
if (p->length > blockbuf_len)
|
||||
{
|
||||
grub_free (blockbuf);
|
||||
blockbuf_len = 2 * p->length;
|
||||
blockbuf = grub_malloc (blockbuf_len);
|
||||
if (!blockbuf)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_disk_read (disk, p->sector - part_start,
|
||||
p->offset, p->length, blockbuf))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_memcmp (buf + index, blockbuf, p->length) != 0)
|
||||
return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist");
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
||||
grub_file_t file)
|
||||
{
|
||||
char *buf;
|
||||
grub_disk_t disk;
|
||||
grub_disk_addr_t part_start;
|
||||
struct blocklist *p;
|
||||
grub_size_t index;
|
||||
|
||||
buf = grub_envblk_buffer (envblk);
|
||||
disk = file->device->disk;
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
|
||||
index = 0;
|
||||
for (p = blocklists; p; index += p->length, p = p->next)
|
||||
{
|
||||
if (grub_disk_write (disk, p->sector - part_start,
|
||||
p->offset, p->length, buf + index))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Context for grub_cmd_save_env. */
|
||||
struct grub_cmd_save_env_ctx
|
||||
{
|
||||
struct blocklist *head, *tail;
|
||||
};
|
||||
|
||||
/* Store blocklists in a linked list. */
|
||||
static void
|
||||
save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
|
||||
void *data)
|
||||
{
|
||||
struct grub_cmd_save_env_ctx *ctx = data;
|
||||
struct blocklist *block;
|
||||
|
||||
block = grub_malloc (sizeof (*block));
|
||||
if (! block)
|
||||
return;
|
||||
|
||||
block->sector = sector;
|
||||
block->offset = offset;
|
||||
block->length = length;
|
||||
|
||||
/* Slightly complicated, because the list should be FIFO. */
|
||||
block->next = 0;
|
||||
if (ctx->tail)
|
||||
ctx->tail->next = block;
|
||||
ctx->tail = block;
|
||||
if (! ctx->head)
|
||||
ctx->head = block;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
struct grub_cmd_save_env_ctx ctx = {
|
||||
.head = 0,
|
||||
.tail = 0
|
||||
};
|
||||
|
||||
if (! argc)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
|
||||
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
GRUB_FILE_TYPE_SAVEENV
|
||||
| GRUB_FILE_TYPE_SKIP_SIGNATURE);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
if (! file->device->disk)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
|
||||
}
|
||||
|
||||
file->read_hook = save_env_read_hook;
|
||||
file->read_hook_data = &ctx;
|
||||
envblk = read_envblk_file (file);
|
||||
file->read_hook = 0;
|
||||
if (! envblk)
|
||||
goto fail;
|
||||
|
||||
if (check_blocklists (envblk, ctx.head, file))
|
||||
goto fail;
|
||||
|
||||
while (argc)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
value = grub_env_get (args[0]);
|
||||
if (value)
|
||||
{
|
||||
if (! grub_envblk_set (envblk, args[0], value))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
grub_envblk_delete (envblk, args[0]);
|
||||
|
||||
argc--;
|
||||
args++;
|
||||
}
|
||||
|
||||
write_blocklists (envblk, ctx.head, file);
|
||||
|
||||
fail:
|
||||
if (envblk)
|
||||
grub_envblk_close (envblk);
|
||||
free_blocklists (ctx.head);
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd_load, cmd_list, cmd_save;
|
||||
|
||||
GRUB_MOD_INIT(loadenv)
|
||||
{
|
||||
cmd_load =
|
||||
grub_register_extcmd ("load_env", grub_cmd_load_env, 0,
|
||||
N_("[-f FILE] [-s|--skip-sig] [variable_name_to_whitelist] [...]"),
|
||||
N_("Load variables from environment block file."),
|
||||
options);
|
||||
cmd_list =
|
||||
grub_register_extcmd ("list_env", grub_cmd_list_env, 0, N_("[-f FILE]"),
|
||||
N_("List variables from environment block file."),
|
||||
options);
|
||||
cmd_save =
|
||||
grub_register_extcmd ("save_env", grub_cmd_save_env, 0,
|
||||
N_("[-f FILE] variable_name [...]"),
|
||||
N_("Save variables to environment block file."),
|
||||
options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(loadenv)
|
||||
{
|
||||
grub_unregister_extcmd (cmd_load);
|
||||
grub_unregister_extcmd (cmd_list);
|
||||
grub_unregister_extcmd (cmd_save);
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/* loadenv.c - command to load/save environment variable. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static grub_envblk_t UNUSED
|
||||
read_envblk_file (grub_file_t file)
|
||||
{
|
||||
grub_off_t offset = 0;
|
||||
char *buf;
|
||||
grub_size_t size = grub_file_size (file);
|
||||
grub_envblk_t envblk;
|
||||
|
||||
buf = grub_malloc (size);
|
||||
if (! buf)
|
||||
return 0;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
grub_ssize_t ret;
|
||||
|
||||
ret = grub_file_read (file, buf + offset, size);
|
||||
if (ret <= 0)
|
||||
{
|
||||
grub_free (buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size -= ret;
|
||||
offset += ret;
|
||||
}
|
||||
|
||||
envblk = grub_envblk_open (buf, offset);
|
||||
if (! envblk)
|
||||
{
|
||||
grub_free (buf);
|
||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return envblk;
|
||||
}
|
||||
|
||||
struct grub_env_whitelist
|
||||
{
|
||||
grub_size_t len;
|
||||
char **list;
|
||||
};
|
||||
typedef struct grub_env_whitelist grub_env_whitelist_t;
|
||||
|
||||
static int UNUSED
|
||||
test_whitelist_membership (const char* name,
|
||||
const grub_env_whitelist_t* whitelist)
|
||||
{
|
||||
grub_size_t i;
|
||||
|
||||
for (i = 0; i < whitelist->len; i++)
|
||||
if (grub_strcmp (name, whitelist->list[i]) == 0)
|
||||
return 1; /* found it */
|
||||
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
/* Helper for grub_cmd_load_env. */
|
||||
static int UNUSED
|
||||
set_var (const char *name, const char *value, void *whitelist)
|
||||
{
|
||||
if (! whitelist)
|
||||
{
|
||||
grub_env_set (name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_whitelist_membership (name,
|
||||
(const grub_env_whitelist_t *) whitelist))
|
||||
grub_env_set (name, value);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,349 +0,0 @@
|
||||
/* menuentry.c - menuentry command */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/normal.h>
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
{"class", 1, GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING},
|
||||
{"users", 2, 0,
|
||||
N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"),
|
||||
ARG_TYPE_STRING},
|
||||
{"hotkey", 3, 0,
|
||||
N_("Keyboard key to quickly boot this entry."), N_("KEYBOARD_KEY"), ARG_TYPE_STRING},
|
||||
{"source", 4, 0,
|
||||
N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING},
|
||||
{"id", 0, 0, N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING},
|
||||
/* TRANSLATORS: menu entry can either be bootable by anyone or only by
|
||||
handful of users. By default when security is active only superusers can
|
||||
boot a given menu entry. With --unrestricted (this option)
|
||||
anyone can boot it. */
|
||||
{"unrestricted", 0, 0, N_("This entry can be booted by any user."),
|
||||
0, ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
int key;
|
||||
} hotkey_aliases[] =
|
||||
{
|
||||
{"backspace", GRUB_TERM_BACKSPACE},
|
||||
{"tab", GRUB_TERM_TAB},
|
||||
{"delete", GRUB_TERM_KEY_DC},
|
||||
{"insert", GRUB_TERM_KEY_INSERT},
|
||||
{"f1", GRUB_TERM_KEY_F1},
|
||||
{"f2", GRUB_TERM_KEY_F2},
|
||||
{"f3", GRUB_TERM_KEY_F3},
|
||||
{"f4", GRUB_TERM_KEY_F4},
|
||||
{"f5", GRUB_TERM_KEY_F5},
|
||||
{"f6", GRUB_TERM_KEY_F6},
|
||||
{"f7", GRUB_TERM_KEY_F7},
|
||||
{"f8", GRUB_TERM_KEY_F8},
|
||||
{"f9", GRUB_TERM_KEY_F9},
|
||||
{"f10", GRUB_TERM_KEY_F10},
|
||||
{"f11", GRUB_TERM_KEY_F11},
|
||||
{"f12", GRUB_TERM_KEY_F12},
|
||||
};
|
||||
|
||||
/* Add a menu entry to the current menu context (as given by the environment
|
||||
variable data slot `menu'). As the configuration file is read, the script
|
||||
parser calls this when a menu entry is to be created. */
|
||||
grub_err_t
|
||||
grub_normal_add_menu_entry (int argc, const char **args,
|
||||
char **classes, const char *id,
|
||||
const char *users, const char *hotkey,
|
||||
const char *prefix, const char *sourcecode,
|
||||
int submenu, int *index, struct bls_entry *bls)
|
||||
{
|
||||
int menu_hotkey = 0;
|
||||
char **menu_args = NULL;
|
||||
char *menu_users = NULL;
|
||||
char *menu_title = NULL;
|
||||
char *menu_sourcecode = NULL;
|
||||
char *menu_id = NULL;
|
||||
struct grub_menu_entry_class *menu_classes = NULL;
|
||||
|
||||
grub_menu_t menu;
|
||||
grub_menu_entry_t *last;
|
||||
|
||||
menu = grub_env_get_menu ();
|
||||
if (! menu)
|
||||
return grub_error (GRUB_ERR_MENU, "no menu context");
|
||||
|
||||
last = &menu->entry_list;
|
||||
|
||||
menu_sourcecode = grub_xasprintf ("%s%s", prefix ?: "", sourcecode);
|
||||
if (! menu_sourcecode)
|
||||
return grub_errno;
|
||||
|
||||
if (classes && classes[0])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; classes[i]; i++); /* count # of menuentry classes */
|
||||
menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class)
|
||||
* (i + 1));
|
||||
if (! menu_classes)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; classes[i]; i++)
|
||||
{
|
||||
menu_classes[i].name = grub_strdup (classes[i]);
|
||||
if (! menu_classes[i].name)
|
||||
goto fail;
|
||||
menu_classes[i].next = classes[i + 1] ? &menu_classes[i + 1] : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (users)
|
||||
{
|
||||
menu_users = grub_strdup (users);
|
||||
if (! menu_users)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hotkey)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++)
|
||||
if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0)
|
||||
{
|
||||
menu_hotkey = hotkey_aliases[i].key;
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE (hotkey_aliases))
|
||||
menu_hotkey = hotkey[0];
|
||||
}
|
||||
|
||||
if (! argc)
|
||||
{
|
||||
grub_error (GRUB_ERR_MENU, "menuentry is missing title");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
menu_title = grub_strdup (args[0]);
|
||||
if (! menu_title)
|
||||
goto fail;
|
||||
|
||||
grub_dprintf ("menu", "id:\"%s\"\n", id);
|
||||
grub_dprintf ("menu", "title:\"%s\"\n", menu_title);
|
||||
menu_id = grub_strdup (id ? : menu_title);
|
||||
if (! menu_id)
|
||||
goto fail;
|
||||
grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id);
|
||||
|
||||
/* Save argc, args to pass as parameters to block arg later. */
|
||||
menu_args = grub_malloc (sizeof (char*) * (argc + 1));
|
||||
if (! menu_args)
|
||||
goto fail;
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
menu_args[i] = grub_strdup (args[i]);
|
||||
if (! menu_args[i])
|
||||
goto fail;
|
||||
}
|
||||
menu_args[argc] = NULL;
|
||||
}
|
||||
|
||||
/* Add the menu entry at the end of the list. */
|
||||
int ind=0;
|
||||
while (*last)
|
||||
{
|
||||
ind++;
|
||||
last = &(*last)->next;
|
||||
}
|
||||
|
||||
*last = grub_zalloc (sizeof (**last));
|
||||
if (! *last)
|
||||
goto fail;
|
||||
|
||||
(*last)->title = menu_title;
|
||||
(*last)->id = menu_id;
|
||||
(*last)->hotkey = menu_hotkey;
|
||||
(*last)->classes = menu_classes;
|
||||
if (menu_users)
|
||||
(*last)->restricted = 1;
|
||||
(*last)->users = menu_users;
|
||||
(*last)->argc = argc;
|
||||
(*last)->args = menu_args;
|
||||
(*last)->sourcecode = menu_sourcecode;
|
||||
(*last)->submenu = submenu;
|
||||
(*last)->bls = bls;
|
||||
|
||||
menu->size++;
|
||||
if (index)
|
||||
*index = ind;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
||||
grub_free (menu_sourcecode);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; menu_classes && menu_classes[i].name; i++)
|
||||
grub_free (menu_classes[i].name);
|
||||
grub_free (menu_classes);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; menu_args && menu_args[i]; i++)
|
||||
grub_free (menu_args[i]);
|
||||
grub_free (menu_args);
|
||||
}
|
||||
|
||||
grub_free (menu_users);
|
||||
grub_free (menu_title);
|
||||
grub_free (menu_id);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static char *
|
||||
setparams_prefix (int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char *p;
|
||||
char *result;
|
||||
grub_size_t len = 10;
|
||||
|
||||
/* Count resulting string length */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
len += 3; /* 3 = 1 space + 2 quotes */
|
||||
p = args[i];
|
||||
while (*p)
|
||||
len += (*p++ == '\'' ? 3 : 1);
|
||||
}
|
||||
|
||||
result = grub_malloc (len + 2);
|
||||
if (! result)
|
||||
return 0;
|
||||
|
||||
grub_strcpy (result, "setparams");
|
||||
p = result + 9;
|
||||
|
||||
for (j = 0; j < argc; j++)
|
||||
{
|
||||
*p++ = ' ';
|
||||
*p++ = '\'';
|
||||
p = grub_strchrsub (p, args[j], '\'', "'\\''");
|
||||
*p++ = '\'';
|
||||
}
|
||||
*p++ = '\n';
|
||||
*p = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
char ch;
|
||||
char *src;
|
||||
char *prefix;
|
||||
unsigned len;
|
||||
grub_err_t r;
|
||||
const char *users;
|
||||
|
||||
if (! argc)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
|
||||
|
||||
if (ctxt->state[3].set && ctxt->script)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple menuentry definitions");
|
||||
|
||||
if (! ctxt->state[3].set && ! ctxt->script)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition");
|
||||
|
||||
if (ctxt->state[1].set)
|
||||
users = ctxt->state[1].arg;
|
||||
else if (ctxt->state[5].set)
|
||||
users = NULL;
|
||||
else
|
||||
users = "";
|
||||
|
||||
if (! ctxt->script)
|
||||
return grub_normal_add_menu_entry (argc, (const char **) args,
|
||||
(ctxt->state[0].set ? ctxt->state[0].args
|
||||
: NULL),
|
||||
ctxt->state[4].arg,
|
||||
users,
|
||||
ctxt->state[2].arg, 0,
|
||||
ctxt->state[3].arg,
|
||||
ctxt->extcmd->cmd->name[0] == 's',
|
||||
NULL, NULL);
|
||||
|
||||
src = args[argc - 1];
|
||||
args[argc - 1] = NULL;
|
||||
|
||||
len = grub_strlen(src);
|
||||
ch = src[len - 1];
|
||||
src[len - 1] = '\0';
|
||||
|
||||
prefix = setparams_prefix (argc - 1, args);
|
||||
if (! prefix)
|
||||
return grub_errno;
|
||||
|
||||
r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
|
||||
ctxt->state[0].args, ctxt->state[4].arg,
|
||||
users,
|
||||
ctxt->state[2].arg, prefix, src + 1,
|
||||
ctxt->extcmd->cmd->name[0] == 's', NULL,
|
||||
NULL);
|
||||
|
||||
src[len - 1] = ch;
|
||||
args[argc - 1] = src;
|
||||
grub_free (prefix);
|
||||
return r;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd, cmd_sub;
|
||||
|
||||
void
|
||||
grub_menu_init (void)
|
||||
{
|
||||
cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BLOCKS
|
||||
| GRUB_COMMAND_ACCEPT_DASH
|
||||
| GRUB_COMMAND_FLAG_EXTRACTOR,
|
||||
N_("BLOCK"), N_("Define a menu entry."), options);
|
||||
cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BLOCKS
|
||||
| GRUB_COMMAND_ACCEPT_DASH
|
||||
| GRUB_COMMAND_FLAG_EXTRACTOR,
|
||||
N_("BLOCK"), N_("Define a submenu."),
|
||||
options);
|
||||
}
|
||||
|
||||
void
|
||||
grub_menu_fini (void)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_sub);
|
||||
}
|
@ -1,353 +0,0 @@
|
||||
/* search.c - search devices based on a file or a filesystem label */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/search.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static int g_no_vtoyefi_part = 0;
|
||||
static char g_vtoyefi_dosname[64];
|
||||
static char g_vtoyefi_gptname[64];
|
||||
|
||||
struct cache_entry
|
||||
{
|
||||
struct cache_entry *next;
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
static struct cache_entry *cache;
|
||||
|
||||
/* Context for FUNC_NAME. */
|
||||
struct search_ctx
|
||||
{
|
||||
const char *key;
|
||||
const char *var;
|
||||
int no_floppy;
|
||||
char **hints;
|
||||
unsigned nhints;
|
||||
int count;
|
||||
int is_cache;
|
||||
};
|
||||
|
||||
/* Helper for FUNC_NAME. */
|
||||
static int
|
||||
iterate_device (const char *name, void *data)
|
||||
{
|
||||
struct search_ctx *ctx = data;
|
||||
int found = 0;
|
||||
|
||||
/* Skip floppy drives when requested. */
|
||||
if (ctx->no_floppy &&
|
||||
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
||||
return 0;
|
||||
|
||||
if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#define compare_fn grub_strcasecmp
|
||||
#else
|
||||
#define compare_fn grub_strcmp
|
||||
#endif
|
||||
|
||||
#ifdef DO_SEARCH_FILE
|
||||
{
|
||||
char *buf;
|
||||
grub_file_t file;
|
||||
|
||||
buf = grub_xasprintf ("(%s)%s", name, ctx->key);
|
||||
if (! buf)
|
||||
return 1;
|
||||
|
||||
file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (file)
|
||||
{
|
||||
found = 1;
|
||||
grub_file_close (file);
|
||||
}
|
||||
grub_free (buf);
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* SEARCH_FS_UUID or SEARCH_LABEL */
|
||||
grub_device_t dev;
|
||||
grub_fs_t fs;
|
||||
char *quid;
|
||||
|
||||
dev = grub_device_open (name);
|
||||
if (dev)
|
||||
{
|
||||
fs = grub_fs_probe (dev);
|
||||
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#define read_fn fs_uuid
|
||||
#else
|
||||
#define read_fn fs_label
|
||||
#endif
|
||||
|
||||
if (fs && fs->read_fn)
|
||||
{
|
||||
fs->read_fn (dev, &quid);
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && quid)
|
||||
{
|
||||
if (compare_fn (quid, ctx->key) == 0)
|
||||
found = 1;
|
||||
|
||||
grub_free (quid);
|
||||
}
|
||||
}
|
||||
|
||||
grub_device_close (dev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ctx->is_cache && found && ctx->count == 0)
|
||||
{
|
||||
struct cache_entry *cache_ent;
|
||||
cache_ent = grub_malloc (sizeof (*cache_ent));
|
||||
if (cache_ent)
|
||||
{
|
||||
cache_ent->key = grub_strdup (ctx->key);
|
||||
cache_ent->value = grub_strdup (name);
|
||||
if (cache_ent->value && cache_ent->key)
|
||||
{
|
||||
cache_ent->next = cache;
|
||||
cache = cache_ent;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_free (cache_ent->value);
|
||||
grub_free (cache_ent->key);
|
||||
grub_free (cache_ent);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
ctx->count++;
|
||||
if (ctx->var)
|
||||
grub_env_set (ctx->var, name);
|
||||
else
|
||||
grub_printf (" %s", name);
|
||||
}
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return (found && ctx->var);
|
||||
}
|
||||
|
||||
/* Helper for FUNC_NAME. */
|
||||
static int
|
||||
part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
|
||||
{
|
||||
struct search_ctx *ctx = data;
|
||||
char *partition_name, *devname;
|
||||
int ret;
|
||||
|
||||
partition_name = grub_partition_get_name (partition);
|
||||
if (! partition_name)
|
||||
return 1;
|
||||
|
||||
devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
|
||||
grub_free (partition_name);
|
||||
if (!devname)
|
||||
return 1;
|
||||
ret = iterate_device (devname, ctx);
|
||||
grub_free (devname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper for FUNC_NAME. */
|
||||
static void
|
||||
try (struct search_ctx *ctx)
|
||||
{
|
||||
unsigned i;
|
||||
struct cache_entry **prev;
|
||||
struct cache_entry *cache_ent;
|
||||
|
||||
for (prev = &cache, cache_ent = *prev; cache_ent;
|
||||
prev = &cache_ent->next, cache_ent = *prev)
|
||||
if (compare_fn (cache_ent->key, ctx->key) == 0)
|
||||
break;
|
||||
if (cache_ent)
|
||||
{
|
||||
ctx->is_cache = 1;
|
||||
if (iterate_device (cache_ent->value, ctx))
|
||||
{
|
||||
ctx->is_cache = 0;
|
||||
return;
|
||||
}
|
||||
ctx->is_cache = 0;
|
||||
/* Cache entry was outdated. Remove it. */
|
||||
if (!ctx->count)
|
||||
{
|
||||
*prev = cache_ent->next;
|
||||
grub_free (cache_ent->key);
|
||||
grub_free (cache_ent->value);
|
||||
grub_free (cache_ent);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->nhints; i++)
|
||||
{
|
||||
char *end;
|
||||
if (!ctx->hints[i][0])
|
||||
continue;
|
||||
end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1;
|
||||
if (*end == ',')
|
||||
*end = 0;
|
||||
if (iterate_device (ctx->hints[i], ctx))
|
||||
{
|
||||
if (!*end)
|
||||
*end = ',';
|
||||
return;
|
||||
}
|
||||
if (!*end)
|
||||
{
|
||||
grub_device_t dev;
|
||||
int ret;
|
||||
dev = grub_device_open (ctx->hints[i]);
|
||||
if (!dev)
|
||||
{
|
||||
if (!*end)
|
||||
*end = ',';
|
||||
continue;
|
||||
}
|
||||
if (!dev->disk)
|
||||
{
|
||||
grub_device_close (dev);
|
||||
if (!*end)
|
||||
*end = ',';
|
||||
continue;
|
||||
}
|
||||
ret = grub_partition_iterate (dev->disk, part_hook, ctx);
|
||||
if (!*end)
|
||||
*end = ',';
|
||||
grub_device_close (dev);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
}
|
||||
grub_device_iterate (iterate_device, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
FUNC_NAME (const char *key, const char *var, int no_floppy,
|
||||
char **hints, unsigned nhints)
|
||||
{
|
||||
struct search_ctx ctx = {
|
||||
.key = key,
|
||||
.var = var,
|
||||
.no_floppy = no_floppy,
|
||||
.hints = hints,
|
||||
.nhints = nhints,
|
||||
.count = 0,
|
||||
.is_cache = 0
|
||||
};
|
||||
grub_fs_autoload_hook_t saved_autoload;
|
||||
|
||||
g_no_vtoyefi_part = 0;
|
||||
if (grub_env_get("VTOY_SEARCH_NO_VTOYEFI"))
|
||||
{
|
||||
grub_snprintf(g_vtoyefi_dosname, sizeof(g_vtoyefi_dosname), "%s,msdos2", grub_env_get("vtoydev"));
|
||||
grub_snprintf(g_vtoyefi_gptname, sizeof(g_vtoyefi_gptname), "%s,gpt2", grub_env_get("vtoydev"));
|
||||
g_no_vtoyefi_part = 1;
|
||||
}
|
||||
|
||||
/* First try without autoloading if we're setting variable. */
|
||||
if (var)
|
||||
{
|
||||
saved_autoload = grub_fs_autoload_hook;
|
||||
grub_fs_autoload_hook = 0;
|
||||
try (&ctx);
|
||||
|
||||
/* Restore autoload hook. */
|
||||
grub_fs_autoload_hook = saved_autoload;
|
||||
|
||||
/* Retry with autoload if nothing found. */
|
||||
if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
|
||||
try (&ctx);
|
||||
}
|
||||
else
|
||||
try (&ctx);
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
|
||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc,
|
||||
char **args)
|
||||
{
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
|
||||
FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2),
|
||||
argc > 2 ? argc - 2 : 0);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
#ifdef DO_SEARCH_FILE
|
||||
GRUB_MOD_INIT(search_fs_file)
|
||||
#elif defined (DO_SEARCH_FS_UUID)
|
||||
GRUB_MOD_INIT(search_fs_uuid)
|
||||
#else
|
||||
GRUB_MOD_INIT(search_label)
|
||||
#endif
|
||||
{
|
||||
cmd =
|
||||
grub_register_command (COMMAND_NAME, grub_cmd_do_search,
|
||||
N_("NAME [VARIABLE] [HINTS]"),
|
||||
HELP_MESSAGE);
|
||||
}
|
||||
|
||||
#ifdef DO_SEARCH_FILE
|
||||
GRUB_MOD_FINI(search_fs_file)
|
||||
#elif defined (DO_SEARCH_FS_UUID)
|
||||
GRUB_MOD_FINI(search_fs_uuid)
|
||||
#else
|
||||
GRUB_MOD_FINI(search_label)
|
||||
#endif
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
@ -1,399 +0,0 @@
|
||||
/* smbios.c - retrieve smbios information. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/smbios.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
|
||||
static struct {
|
||||
grub_addr_t start;
|
||||
grub_addr_t end;
|
||||
grub_uint16_t structures;
|
||||
} table_desc;
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
/* Locate the SMBIOS entry point structure depending on the hardware. */
|
||||
struct grub_smbios_eps *
|
||||
grub_smbios_get_eps (void)
|
||||
{
|
||||
static struct grub_smbios_eps *eps = NULL;
|
||||
|
||||
if (eps != NULL)
|
||||
return eps;
|
||||
|
||||
eps = grub_machine_smbios_get_eps ();
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
||||
static struct grub_smbios_eps3 *
|
||||
grub_smbios_get_eps3 (void)
|
||||
{
|
||||
static struct grub_smbios_eps3 *eps = NULL;
|
||||
|
||||
if (eps != NULL)
|
||||
return eps;
|
||||
|
||||
eps = grub_machine_smbios_get_eps3 ();
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
static char *
|
||||
linux_string (const char *value)
|
||||
{
|
||||
char *out = grub_malloc( grub_strlen (value) + 1);
|
||||
const char *src = value;
|
||||
char *dst = out;
|
||||
|
||||
for (; *src; src++)
|
||||
if (*src > ' ' && *src < 127 && *src != ':')
|
||||
*dst++ = *src;
|
||||
|
||||
*dst = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions convert values from the various SMBIOS structure field types
|
||||
* into a string formatted to be returned to the user. They expect that the
|
||||
* structure and offset were already validated. When the requested data is
|
||||
* successfully retrieved and formatted, the pointer to the string is returned;
|
||||
* otherwise, NULL is returned on failure. Don't free the result.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("255")];
|
||||
|
||||
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("65535")];
|
||||
|
||||
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%u", value);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("4294967295")];
|
||||
|
||||
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("18446744073709551615")];
|
||||
|
||||
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
const grub_uint8_t *ptr = structure + structure[1];
|
||||
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||
const grub_uint8_t referenced_string_number = structure[offset];
|
||||
grub_uint8_t i;
|
||||
|
||||
/* A string referenced with zero is interpreted as unset. */
|
||||
if (referenced_string_number == 0)
|
||||
return NULL;
|
||||
|
||||
/* Search the string set. */
|
||||
for (i = 1; *ptr != 0 && ptr < table_end; i++)
|
||||
if (i == referenced_string_number)
|
||||
{
|
||||
const char *str = (const char *)ptr;
|
||||
while (*ptr++ != 0)
|
||||
if (ptr >= table_end)
|
||||
return NULL; /* The string isn't terminated. */
|
||||
return str;
|
||||
}
|
||||
else
|
||||
while (*ptr++ != 0 && ptr < table_end);
|
||||
|
||||
/* The string number is greater than the number of strings in the set. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")];
|
||||
const grub_uint8_t *f = structure + offset; /* little-endian fields */
|
||||
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
||||
|
||||
grub_snprintf (buffer, sizeof (buffer),
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
|
||||
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
/* List the field formatting functions and the number of bytes they need. */
|
||||
static const struct {
|
||||
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
|
||||
grub_uint8_t field_length;
|
||||
} field_extractors[] = {
|
||||
{grub_smbios_format_byte, 1},
|
||||
{grub_smbios_format_word, 2},
|
||||
{grub_smbios_format_dword, 4},
|
||||
{grub_smbios_format_qword, 8},
|
||||
{grub_smbios_get_string, 1},
|
||||
{grub_smbios_format_uuid, 16}
|
||||
};
|
||||
|
||||
/* List command options, with structure field getters ordered as above. */
|
||||
#define FIRST_GETTER_OPT (3)
|
||||
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
|
||||
#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1)
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"type", 't', 0, N_("Match structures with the given type."),
|
||||
N_("type"), ARG_TYPE_INT},
|
||||
{"handle", 'h', 0, N_("Match structures with the given handle."),
|
||||
N_("handle"), ARG_TYPE_INT},
|
||||
{"match", 'm', 0, N_("Select a structure when several match."),
|
||||
N_("match"), ARG_TYPE_INT},
|
||||
{"get-byte", 'b', 0, N_("Get the byte's value at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"get-word", 'w', 0, N_("Get two bytes' value at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"get-string", 's', 0, N_("Get the string specified at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."),
|
||||
N_("offset"), ARG_TYPE_INT},
|
||||
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
||||
N_("variable"), ARG_TYPE_STRING},
|
||||
{"linux", '\0', 0, N_("Filter the result like linux does."),
|
||||
N_("variable"), ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Return a matching SMBIOS structure.
|
||||
*
|
||||
* This method can use up to three criteria for selecting a structure:
|
||||
* - The "type" field (use -1 to ignore)
|
||||
* - The "handle" field (use -1 to ignore)
|
||||
* - Which to return if several match (use 0 to ignore)
|
||||
*
|
||||
* The return value is a pointer to the first matching structure. If no
|
||||
* structures match the given parameters, NULL is returned.
|
||||
*/
|
||||
static const grub_uint8_t *
|
||||
grub_smbios_match_structure (const grub_int16_t type,
|
||||
const grub_int32_t handle,
|
||||
const grub_uint16_t match)
|
||||
{
|
||||
const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start;
|
||||
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||
grub_uint16_t structures = table_desc.structures;
|
||||
grub_uint16_t structure_count = 0;
|
||||
grub_uint16_t matches = 0;
|
||||
|
||||
while (ptr < table_end
|
||||
&& ptr[1] >= 4 /* Valid structures include the 4-byte header. */
|
||||
&& (structure_count++ < structures || structures == 0))
|
||||
{
|
||||
grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2);
|
||||
grub_uint8_t structure_type = ptr[0];
|
||||
|
||||
if ((handle < 0 || handle == structure_handle)
|
||||
&& (type < 0 || type == structure_type)
|
||||
&& (match == 0 || match == ++matches))
|
||||
return ptr;
|
||||
else
|
||||
{
|
||||
ptr += ptr[1];
|
||||
while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end);
|
||||
}
|
||||
|
||||
if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE)
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **argv __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
|
||||
grub_int16_t type = -1;
|
||||
grub_int32_t handle = -1;
|
||||
grub_uint16_t match = 0;
|
||||
grub_uint8_t offset = 0;
|
||||
|
||||
const grub_uint8_t *structure;
|
||||
const char *value;
|
||||
char *modified_value = NULL;
|
||||
grub_int32_t option;
|
||||
grub_int8_t field_type = -1;
|
||||
grub_uint8_t i;
|
||||
|
||||
if (table_desc.start == 0)
|
||||
return grub_error (GRUB_ERR_IO,
|
||||
N_("the SMBIOS entry point structure was not found"));
|
||||
|
||||
/* Read the given filtering options. */
|
||||
if (state[0].set)
|
||||
{
|
||||
option = grub_strtol (state[0].arg, NULL, 0);
|
||||
if (option < 0 || option > 255)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("the type must be between 0 and 255"));
|
||||
type = (grub_int16_t)option;
|
||||
}
|
||||
if (state[1].set)
|
||||
{
|
||||
option = grub_strtol (state[1].arg, NULL, 0);
|
||||
if (option < 0 || option > 65535)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("the handle must be between 0 and 65535"));
|
||||
handle = (grub_int32_t)option;
|
||||
}
|
||||
if (state[2].set)
|
||||
{
|
||||
option = grub_strtol (state[2].arg, NULL, 0);
|
||||
if (option <= 0 || option > 65535)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("the match must be a positive integer"));
|
||||
match = (grub_uint16_t)option;
|
||||
}
|
||||
|
||||
/* Determine the data type of the structure field to retrieve. */
|
||||
for (i = 0; i < ARRAY_SIZE(field_extractors); i++)
|
||||
if (state[FIRST_GETTER_OPT + i].set)
|
||||
{
|
||||
if (field_type >= 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("only one --get option is usable at a time"));
|
||||
field_type = i;
|
||||
}
|
||||
|
||||
/* Require a choice of a structure field to return. */
|
||||
if (field_type < 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("one of the --get options is required"));
|
||||
|
||||
/* Locate a matching SMBIOS structure. */
|
||||
structure = grub_smbios_match_structure (type, handle, match);
|
||||
if (structure == NULL)
|
||||
return grub_error (GRUB_ERR_IO,
|
||||
N_("no structure matched the given options"));
|
||||
|
||||
/* Ensure the requested byte offset is inside the structure. */
|
||||
option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0);
|
||||
if (option < 0 || option >= structure[1])
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
N_("the given offset is outside the structure"));
|
||||
|
||||
/* Ensure the requested data type at the offset is inside the structure. */
|
||||
offset = (grub_uint8_t)option;
|
||||
if (offset + field_extractors[field_type].field_length > structure[1])
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
N_("the field ends outside the structure"));
|
||||
|
||||
/* Format the requested structure field into a readable string. */
|
||||
value = field_extractors[field_type].format (structure, offset);
|
||||
if (value == NULL)
|
||||
return grub_error (GRUB_ERR_IO,
|
||||
N_("failed to retrieve the structure field"));
|
||||
|
||||
if (state[LINUX_OPT].set)
|
||||
value = modified_value = linux_string (value);
|
||||
|
||||
/* Store or print the formatted value. */
|
||||
if (state[SETTER_OPT].set)
|
||||
grub_env_set (state[SETTER_OPT].arg, value);
|
||||
else
|
||||
grub_printf ("%s\n", value);
|
||||
|
||||
grub_free(modified_value);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT(smbios)
|
||||
{
|
||||
struct grub_smbios_eps3 *eps3;
|
||||
struct grub_smbios_eps *eps;
|
||||
|
||||
if ((eps3 = grub_smbios_get_eps3 ()))
|
||||
{
|
||||
table_desc.start = (grub_addr_t)eps3->table_address;
|
||||
table_desc.end = table_desc.start + eps3->maximum_table_length;
|
||||
table_desc.structures = 0; /* SMBIOS3 drops the structure count. */
|
||||
}
|
||||
else if ((eps = grub_smbios_get_eps ()))
|
||||
{
|
||||
table_desc.start = (grub_addr_t)eps->intermediate.table_address;
|
||||
table_desc.end = table_desc.start + eps->intermediate.table_length;
|
||||
table_desc.structures = eps->intermediate.structures;
|
||||
}
|
||||
|
||||
cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0,
|
||||
N_("[-t type] [-h handle] [-m match] "
|
||||
"(-b|-w|-d|-q|-s|-u) offset "
|
||||
"[--set variable]"),
|
||||
N_("Retrieve SMBIOS information."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(smbios)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
||||
|
@ -1,533 +0,0 @@
|
||||
/* test.c -- The test command.. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static int g_test_case_insensitive = 0;
|
||||
|
||||
/* A simple implementation for signed numbers. */
|
||||
static int
|
||||
grub_strtosl (char *arg, char **end, int base)
|
||||
{
|
||||
if (arg[0] == '-')
|
||||
return -grub_strtoul (arg + 1, end, base);
|
||||
return grub_strtoul (arg, end, base);
|
||||
}
|
||||
|
||||
/* Context for test_parse. */
|
||||
struct test_parse_ctx
|
||||
{
|
||||
int invert;
|
||||
int or, and;
|
||||
int file_exists;
|
||||
struct grub_dirhook_info file_info;
|
||||
char *filename;
|
||||
};
|
||||
|
||||
/* Take care of discarding and inverting. */
|
||||
static void
|
||||
update_val (int val, struct test_parse_ctx *ctx)
|
||||
{
|
||||
ctx->and = ctx->and && (ctx->invert ? ! val : val);
|
||||
ctx->invert = 0;
|
||||
}
|
||||
|
||||
/* A hook for iterating directories. */
|
||||
static int
|
||||
find_file (const char *cur_filename, const struct grub_dirhook_info *info,
|
||||
void *data)
|
||||
{
|
||||
int case_insensitive = 0;
|
||||
struct test_parse_ctx *ctx = data;
|
||||
|
||||
if (g_test_case_insensitive || info->case_insensitive)
|
||||
case_insensitive = 1;
|
||||
|
||||
if ((case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename)
|
||||
: grub_strcmp (cur_filename, ctx->filename)) == 0)
|
||||
{
|
||||
ctx->file_info = *info;
|
||||
ctx->file_exists = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if file exists and fetch its information. */
|
||||
static void
|
||||
get_fileinfo (char *path, struct test_parse_ctx *ctx)
|
||||
{
|
||||
char *pathname;
|
||||
char *device_name;
|
||||
grub_fs_t fs;
|
||||
grub_device_t dev;
|
||||
|
||||
ctx->file_exists = 0;
|
||||
device_name = grub_file_get_device_name (path);
|
||||
dev = grub_device_open (device_name);
|
||||
if (! dev)
|
||||
{
|
||||
grub_free (device_name);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
grub_free (device_name);
|
||||
grub_device_close (dev);
|
||||
return;
|
||||
}
|
||||
|
||||
pathname = grub_strchr (path, ')');
|
||||
if (! pathname)
|
||||
pathname = path;
|
||||
else
|
||||
pathname++;
|
||||
|
||||
/* Remove trailing '/'. */
|
||||
while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
|
||||
pathname[grub_strlen (pathname) - 1] = 0;
|
||||
|
||||
/* Split into path and filename. */
|
||||
ctx->filename = grub_strrchr (pathname, '/');
|
||||
if (! ctx->filename)
|
||||
{
|
||||
path = grub_strdup ("/");
|
||||
ctx->filename = pathname;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->filename++;
|
||||
path = grub_strdup (pathname);
|
||||
path[ctx->filename - pathname] = 0;
|
||||
}
|
||||
|
||||
/* It's the whole device. */
|
||||
if (! *pathname)
|
||||
{
|
||||
ctx->file_exists = 1;
|
||||
grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info));
|
||||
/* Root is always a directory. */
|
||||
ctx->file_info.dir = 1;
|
||||
|
||||
/* Fetch writing time. */
|
||||
ctx->file_info.mtimeset = 0;
|
||||
if (fs->fs_mtime)
|
||||
{
|
||||
if (! fs->fs_mtime (dev, &ctx->file_info.mtime))
|
||||
ctx->file_info.mtimeset = 1;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
(fs->fs_dir) (dev, path, find_file, ctx);
|
||||
|
||||
grub_device_close (dev);
|
||||
grub_free (path);
|
||||
grub_free (device_name);
|
||||
}
|
||||
|
||||
/* Parse a test expression starting from *argn. */
|
||||
static int
|
||||
test_parse (char **args, int *argn, int argc)
|
||||
{
|
||||
struct test_parse_ctx ctx = {
|
||||
.and = 1,
|
||||
.or = 0,
|
||||
.invert = 0
|
||||
};
|
||||
|
||||
/* Here we have the real parsing. */
|
||||
while (*argn < argc)
|
||||
{
|
||||
/* First try 3 argument tests. */
|
||||
if (*argn + 2 < argc)
|
||||
{
|
||||
/* String tests. */
|
||||
if (grub_strcmp (args[*argn + 1], "=") == 0
|
||||
|| grub_strcmp (args[*argn + 1], "==") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "!=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* GRUB extension: lexicographical sorting. */
|
||||
if (grub_strcmp (args[*argn + 1], "<") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "<=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], ">") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], ">=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Number tests. */
|
||||
if (grub_strcmp (args[*argn + 1], "-eq") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
== grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-EQ") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
== grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
>= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-GE") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
>= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
> grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-GT") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
> grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-le") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
<= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-LE") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
<= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
< grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-LT") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
< grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
!= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn + 1], "-NE") == 0)
|
||||
{
|
||||
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||
!= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* GRUB extension: compare numbers skipping prefixes.
|
||||
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
|
||||
if (grub_strcmp (args[*argn + 1], "-pgt") == 0
|
||||
|| grub_strcmp (args[*argn + 1], "-plt") == 0)
|
||||
{
|
||||
int i;
|
||||
/* Skip common prefix. */
|
||||
for (i = 0; args[*argn][i] == args[*argn + 2][i]
|
||||
&& args[*argn][i]; i++);
|
||||
|
||||
/* Go the digits back. */
|
||||
i--;
|
||||
while (grub_isdigit (args[*argn][i]) && i > 0)
|
||||
i--;
|
||||
i++;
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
|
||||
update_val (grub_strtoul (args[*argn] + i, 0, 0)
|
||||
> grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
|
||||
else
|
||||
update_val (grub_strtoul (args[*argn] + i, 0, 0)
|
||||
< grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
|
||||
will be added to the first mtime. */
|
||||
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
|
||||
|| grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
|
||||
{
|
||||
struct grub_dirhook_info file1;
|
||||
int file1exists;
|
||||
int bias = 0;
|
||||
|
||||
/* Fetch fileinfo. */
|
||||
get_fileinfo (args[*argn], &ctx);
|
||||
file1 = ctx.file_info;
|
||||
file1exists = ctx.file_exists;
|
||||
get_fileinfo (args[*argn + 2], &ctx);
|
||||
|
||||
if (args[*argn + 1][3])
|
||||
bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
|
||||
|
||||
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
|
||||
update_val ((file1exists && ! ctx.file_exists)
|
||||
|| (file1.mtimeset && ctx.file_info.mtimeset
|
||||
&& file1.mtime + bias > ctx.file_info.mtime),
|
||||
&ctx);
|
||||
else
|
||||
update_val ((! file1exists && ctx.file_exists)
|
||||
|| (file1.mtimeset && ctx.file_info.mtimeset
|
||||
&& file1.mtime + bias < ctx.file_info.mtime),
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Two-argument tests. */
|
||||
if (*argn + 1 < argc)
|
||||
{
|
||||
/* File tests. */
|
||||
if (grub_strcmp (args[*argn], "-d") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-D") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-e") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
update_val (ctx.file_exists, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-E") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
update_val (ctx.file_exists, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-f") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
/* FIXME: check for other types. */
|
||||
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-F") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
/* FIXME: check for other types. */
|
||||
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-s") == 0)
|
||||
{
|
||||
grub_file_t file;
|
||||
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
update_val (file && (grub_file_size (file) != 0), &ctx);
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* String tests. */
|
||||
if (grub_strcmp (args[*argn], "-n") == 0)
|
||||
{
|
||||
update_val (args[*argn + 1][0], &ctx);
|
||||
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-z") == 0)
|
||||
{
|
||||
update_val (! args[*argn + 1][0], &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special modifiers. */
|
||||
|
||||
/* End of expression. return to parent. */
|
||||
if (grub_strcmp (args[*argn], ")") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
return ctx.or || ctx.and;
|
||||
}
|
||||
/* Recursively invoke if parenthesis. */
|
||||
if (grub_strcmp (args[*argn], "(") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
update_val (test_parse (args, argn, argc), &ctx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "!") == 0)
|
||||
{
|
||||
ctx.invert = ! ctx.invert;
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-a") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-o") == 0)
|
||||
{
|
||||
ctx.or = ctx.or || ctx.and;
|
||||
ctx.and = 1;
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No test found. Interpret if as just a string. */
|
||||
update_val (args[*argn][0], &ctx);
|
||||
(*argn)++;
|
||||
}
|
||||
return ctx.or || ctx.and;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
int argn = 0;
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
|
||||
argc--;
|
||||
|
||||
return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
|
||||
: grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
|
||||
}
|
||||
|
||||
static grub_command_t cmd_1, cmd_2;
|
||||
|
||||
GRUB_MOD_INIT(test)
|
||||
{
|
||||
cmd_1 = grub_register_command ("[", grub_cmd_test,
|
||||
N_("EXPRESSION ]"), N_("Evaluate an expression."));
|
||||
cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
cmd_2 = grub_register_command ("test", grub_cmd_test,
|
||||
N_("EXPRESSION"), N_("Evaluate an expression."));
|
||||
cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(test)
|
||||
{
|
||||
grub_unregister_command (cmd_1);
|
||||
grub_unregister_command (cmd_2);
|
||||
}
|
@ -1,257 +0,0 @@
|
||||
/* loopback.c - command to add loopback devices. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_loopback
|
||||
{
|
||||
char *devname;
|
||||
grub_file_t file;
|
||||
struct grub_loopback *next;
|
||||
unsigned long id;
|
||||
grub_off_t skip;
|
||||
};
|
||||
|
||||
static struct grub_loopback *loopback_list;
|
||||
static unsigned long last_id = 0;
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
/* TRANSLATORS: The disk is simply removed from the list of available ones,
|
||||
not wiped, avoid to scare user. */
|
||||
{"delete", 'd', 0, N_("Delete the specified loopback drive."), 0, 0},
|
||||
{"skip", 's', 0, "skip sectors of the file.", "SECTORS", ARG_TYPE_INT },
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* Delete the loopback device NAME. */
|
||||
static grub_err_t
|
||||
delete_loopback (const char *name)
|
||||
{
|
||||
struct grub_loopback *dev;
|
||||
struct grub_loopback **prev;
|
||||
|
||||
/* Search for the device. */
|
||||
for (dev = loopback_list, prev = &loopback_list;
|
||||
dev;
|
||||
prev = &dev->next, dev = dev->next)
|
||||
if (grub_strcmp (dev->devname, name) == 0)
|
||||
break;
|
||||
|
||||
if (! dev)
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "device not found");
|
||||
|
||||
/* Remove the device from the list. */
|
||||
*prev = dev->next;
|
||||
|
||||
grub_free (dev->devname);
|
||||
grub_file_close (dev->file);
|
||||
grub_free (dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The command to add and remove loopback devices. */
|
||||
static grub_err_t
|
||||
grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
struct grub_loopback *newdev;
|
||||
grub_err_t ret;
|
||||
grub_off_t skip = 0;
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
|
||||
/* Check if `-d' was used. */
|
||||
if (state[0].set)
|
||||
return delete_loopback (args[0]);
|
||||
|
||||
if (state[1].set)
|
||||
skip = (grub_off_t)grub_strtoull(state[1].arg, NULL, 10);
|
||||
|
||||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
/* First try to replace the old device. */
|
||||
for (newdev = loopback_list; newdev; newdev = newdev->next)
|
||||
if (grub_strcmp (newdev->devname, args[0]) == 0)
|
||||
break;
|
||||
|
||||
if (newdev)
|
||||
{
|
||||
grub_file_close (newdev->file);
|
||||
newdev->file = file;
|
||||
newdev->skip = skip;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unable to replace it, make a new entry. */
|
||||
newdev = grub_malloc (sizeof (struct grub_loopback));
|
||||
if (! newdev)
|
||||
goto fail;
|
||||
|
||||
newdev->devname = grub_strdup (args[0]);
|
||||
if (! newdev->devname)
|
||||
{
|
||||
grub_free (newdev);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newdev->file = file;
|
||||
newdev->skip = skip;
|
||||
newdev->id = last_id++;
|
||||
|
||||
/* Add the new entry to the list. */
|
||||
newdev->next = loopback_list;
|
||||
loopback_list = newdev;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
ret = grub_errno;
|
||||
grub_file_close (file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
||||
grub_disk_pull_t pull)
|
||||
{
|
||||
struct grub_loopback *d;
|
||||
if (pull != GRUB_DISK_PULL_NONE)
|
||||
return 0;
|
||||
for (d = loopback_list; d; d = d->next)
|
||||
{
|
||||
if (hook (d->devname, hook_data))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_loopback_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
struct grub_loopback *dev;
|
||||
|
||||
for (dev = loopback_list; dev; dev = dev->next)
|
||||
if (grub_strcmp (dev->devname, name) == 0)
|
||||
break;
|
||||
|
||||
if (! dev)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
|
||||
/* Use the filesize for the disk size, round up to a complete sector. */
|
||||
if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN)
|
||||
disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1)
|
||||
/ GRUB_DISK_SECTOR_SIZE);
|
||||
else
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
/* Avoid reading more than 512M. */
|
||||
disk->max_agglomerate = 1 << (29 - GRUB_DISK_SECTOR_BITS
|
||||
- GRUB_DISK_CACHE_BITS);
|
||||
|
||||
disk->id = dev->id;
|
||||
|
||||
disk->data = dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, char *buf)
|
||||
{
|
||||
grub_file_t file = ((struct grub_loopback *) disk->data)->file;
|
||||
grub_off_t skip = ((struct grub_loopback *) disk->data)->skip;
|
||||
grub_off_t pos;
|
||||
|
||||
grub_file_seek (file, (sector + skip) << GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
|
||||
/* In case there is more data read than there is available, in case
|
||||
of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
|
||||
the rest with zeros. */
|
||||
pos = (sector + skip + size) << GRUB_DISK_SECTOR_BITS;
|
||||
if (pos > file->size)
|
||||
{
|
||||
grub_size_t amount = pos - file->size;
|
||||
grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_loopback_write (grub_disk_t disk __attribute ((unused)),
|
||||
grub_disk_addr_t sector __attribute ((unused)),
|
||||
grub_size_t size __attribute ((unused)),
|
||||
const char *buf __attribute ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"loopback write is not supported");
|
||||
}
|
||||
|
||||
static struct grub_disk_dev grub_loopback_dev =
|
||||
{
|
||||
.name = "loopback",
|
||||
.id = GRUB_DISK_DEVICE_LOOPBACK_ID,
|
||||
.disk_iterate = grub_loopback_iterate,
|
||||
.disk_open = grub_loopback_open,
|
||||
.disk_read = grub_loopback_read,
|
||||
.disk_write = grub_loopback_write,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(loopback)
|
||||
{
|
||||
cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0,
|
||||
N_("[-d] DEVICENAME FILE."),
|
||||
/* TRANSLATORS: The file itself is not destroyed
|
||||
or transformed into drive. */
|
||||
N_("Make a virtual drive from a file."), options);
|
||||
grub_disk_dev_register (&grub_loopback_dev);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(loopback)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_disk_dev_unregister (&grub_loopback_dev);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -103,7 +103,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
|
||||
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
||||
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
||||
#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000
|
||||
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
|
||||
|
||||
/* The set of back-incompatible features this driver DOES support. Add (OR)
|
||||
@ -124,16 +123,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
* mmp: Not really back-incompatible - was added as such to
|
||||
* avoid multiple read-write mounts. Safe to ignore for this
|
||||
* RO driver.
|
||||
* checksum seed: Not really back-incompatible - was added to allow tools
|
||||
* such as tune2fs to change the UUID on a mounted metadata
|
||||
* checksummed filesystem. Safe to ignore for now since the
|
||||
* driver doesn't support checksum verification. But it must
|
||||
* be removed from this list if that support is added later.
|
||||
*
|
||||
*/
|
||||
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
|
||||
| EXT4_FEATURE_INCOMPAT_MMP \
|
||||
| EXT4_FEATURE_INCOMPAT_CSUM_SEED)
|
||||
| EXT4_FEATURE_INCOMPAT_MMP)
|
||||
|
||||
|
||||
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
|
||||
@ -731,11 +723,10 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||
if (! symlink)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the filesize of the symlink is equal to or bigger than 60 the symlink
|
||||
* is stored in a separate block, otherwise it is stored in the inode.
|
||||
*/
|
||||
if (grub_le_to_cpu32 (diro->inode.size) < sizeof (diro->inode.symlink))
|
||||
/* If the filesize of the symlink is bigger than
|
||||
60 the symlink is stored in a separate block,
|
||||
otherwise it is stored in the inode. */
|
||||
if (grub_le_to_cpu32 (diro->inode.size) <= sizeof (diro->inode.symlink))
|
||||
grub_memcpy (symlink,
|
||||
diro->inode.symlink,
|
||||
grub_le_to_cpu32 (diro->inode.size));
|
||||
|
@ -117,8 +117,6 @@ struct grub_fshelp_find_file_iter_ctx
|
||||
enum grub_fshelp_filetype *foundtype;
|
||||
};
|
||||
|
||||
int g_ventoy_case_insensitive = 0;
|
||||
|
||||
/* Helper for grub_fshelp_find_file. */
|
||||
static int
|
||||
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
@ -126,11 +124,6 @@ find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
{
|
||||
struct grub_fshelp_find_file_iter_ctx *ctx = data;
|
||||
|
||||
if (g_ventoy_case_insensitive)
|
||||
{
|
||||
filetype |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||
}
|
||||
|
||||
if (filetype == GRUB_FSHELP_UNKNOWN ||
|
||||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
|
||||
? grub_strcasecmp (ctx->name, filename)
|
||||
@ -426,7 +419,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
|
||||
if (grub_errno)
|
||||
return -1;
|
||||
}
|
||||
else if (read_hook != (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read)
|
||||
else if (read_hook != (grub_disk_read_hook_t)grub_disk_blocklist_read)
|
||||
grub_memset (buf, 0, blockend);
|
||||
|
||||
buf += blocksize - skipfirst;
|
||||
|
@ -32,8 +32,6 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static int g_ventoy_no_joliet = 0;
|
||||
static int g_ventoy_cur_joliet = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_pos = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_offset = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
|
||||
@ -452,7 +450,6 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||
|
||||
data->disk = disk;
|
||||
|
||||
g_ventoy_cur_joliet = 0;
|
||||
block = 16;
|
||||
do
|
||||
{
|
||||
@ -483,11 +480,8 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
|
||||
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
|
||||
{
|
||||
if (0 == g_ventoy_no_joliet) {
|
||||
copy_voldesc = 1;
|
||||
data->joliet = 1;
|
||||
g_ventoy_cur_joliet = 1;
|
||||
}
|
||||
copy_voldesc = 1;
|
||||
data->joliet = 1;
|
||||
}
|
||||
|
||||
if (copy_voldesc)
|
||||
@ -738,8 +732,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
|
||||
ctx.type = GRUB_FSHELP_DIR;
|
||||
else if ((dirent.flags & FLAG_TYPE) == 3)
|
||||
ctx.type = GRUB_FSHELP_DIR;
|
||||
else
|
||||
ctx.type = GRUB_FSHELP_REG;
|
||||
}
|
||||
@ -1116,16 +1108,6 @@ grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
|
||||
return err;
|
||||
}
|
||||
|
||||
void grub_iso9660_set_nojoliet(int nojoliet)
|
||||
{
|
||||
g_ventoy_no_joliet = nojoliet;
|
||||
}
|
||||
|
||||
int grub_iso9660_is_joliet(void)
|
||||
{
|
||||
return g_ventoy_cur_joliet;
|
||||
}
|
||||
|
||||
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file)
|
||||
{
|
||||
(void)file;
|
||||
|
@ -889,7 +889,6 @@ grub_ntfs_mount (grub_disk_t disk)
|
||||
struct grub_ntfs_bpb bpb;
|
||||
struct grub_ntfs_data *data = 0;
|
||||
grub_uint32_t spc;
|
||||
grub_uint32_t sectors_per_cluster;
|
||||
|
||||
if (!disk)
|
||||
goto fail;
|
||||
@ -904,18 +903,14 @@ grub_ntfs_mount (grub_disk_t disk)
|
||||
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
|
||||
goto fail;
|
||||
|
||||
sectors_per_cluster = bpb.sectors_per_cluster;
|
||||
if (sectors_per_cluster > 0x80)
|
||||
sectors_per_cluster = 1U << (256U - bpb.sectors_per_cluster);
|
||||
|
||||
if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0
|
||||
|| sectors_per_cluster == 0
|
||||
|| (sectors_per_cluster & (sectors_per_cluster - 1)) != 0
|
||||
|| bpb.sectors_per_cluster == 0
|
||||
|| (bpb.sectors_per_cluster & (bpb.sectors_per_cluster - 1)) != 0
|
||||
|| bpb.bytes_per_sector == 0
|
||||
|| (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0)
|
||||
goto fail;
|
||||
|
||||
spc = (((grub_uint32_t) sectors_per_cluster
|
||||
spc = (((grub_uint32_t) bpb.sectors_per_cluster
|
||||
* (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
|
||||
>> GRUB_NTFS_BLK_SHR);
|
||||
if (spc == 0)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,25 +23,11 @@
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define NSEC_PER_SEC ((grub_int64_t) 1000000000)
|
||||
|
||||
// GRUB 2.04 doesn't have safemath.h
|
||||
// #include <grub/safemath.h>
|
||||
|
||||
// gcc < 5.1 doesn't support __builtin_add_overflow and __builtin_mul_overflow
|
||||
// #define grub_add(a, b, res) __builtin_add_overflow(a, b, res)
|
||||
// #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
|
||||
// Warning: This is unsafe!
|
||||
#define grub_add(a, b, res) ({ *(res) = (a) + (b); 0; })
|
||||
|
||||
#define grub_mul(a, b, res) ({ *(res) = (a) * (b); 0; })
|
||||
|
||||
#define XFS_INODE_EXTENTS 9
|
||||
|
||||
#define XFS_INODE_FORMAT_INO 1
|
||||
@ -88,22 +74,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
XFS_SB_VERSION2_PROJID32BIT | \
|
||||
XFS_SB_VERSION2_FTYPE)
|
||||
|
||||
/* Inode flags2 flags */
|
||||
#define XFS_DIFLAG2_BIGTIME_BIT 3
|
||||
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
|
||||
#define XFS_DIFLAG2_NREXT64_BIT 4
|
||||
#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT)
|
||||
|
||||
/* incompat feature flags */
|
||||
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
|
||||
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
|
||||
#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
|
||||
#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE (1 << 6) /* exchangerange supported */
|
||||
#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */
|
||||
#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */
|
||||
|
||||
/*
|
||||
* Directory entries with ftype are explicitly handled by GRUB code.
|
||||
@ -113,26 +87,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
*
|
||||
* We do not currently verify metadata UUID, so it is safe to read filesystems
|
||||
* with the XFS_SB_FEAT_INCOMPAT_META_UUID feature.
|
||||
*
|
||||
* We do not currently replay the log, so it is safe to read filesystems
|
||||
* with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature.
|
||||
*
|
||||
* We do not currently read directory parent pointers, so it is safe to read
|
||||
* filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature.
|
||||
*
|
||||
* We do not currently look at realtime or quota metadata, so it is safe to
|
||||
* read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature.
|
||||
*/
|
||||
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
|
||||
XFS_SB_FEAT_INCOMPAT_SPINODES | \
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID | \
|
||||
XFS_SB_FEAT_INCOMPAT_BIGTIME | \
|
||||
XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
|
||||
XFS_SB_FEAT_INCOMPAT_NREXT64 | \
|
||||
XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \
|
||||
XFS_SB_FEAT_INCOMPAT_PARENT | \
|
||||
XFS_SB_FEAT_INCOMPAT_METADIR)
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
@ -217,49 +176,33 @@ struct grub_xfs_btree_root
|
||||
grub_uint64_t keys[1];
|
||||
} GRUB_PACKED;
|
||||
|
||||
struct grub_xfs_time_legacy
|
||||
struct grub_xfs_time
|
||||
{
|
||||
grub_uint32_t sec;
|
||||
grub_uint32_t nanosec;
|
||||
} GRUB_PACKED;
|
||||
|
||||
/*
|
||||
* The struct grub_xfs_inode layout was taken from the
|
||||
* struct xfs_dinode_core which is described here:
|
||||
* https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf
|
||||
*/
|
||||
struct grub_xfs_inode
|
||||
{
|
||||
grub_uint8_t magic[2];
|
||||
grub_uint16_t mode;
|
||||
grub_uint8_t version;
|
||||
grub_uint8_t format;
|
||||
grub_uint8_t unused2[18];
|
||||
grub_uint64_t nextents_big;
|
||||
grub_uint64_t atime;
|
||||
grub_uint64_t mtime;
|
||||
grub_uint64_t ctime;
|
||||
grub_uint8_t unused2[26];
|
||||
struct grub_xfs_time atime;
|
||||
struct grub_xfs_time mtime;
|
||||
struct grub_xfs_time ctime;
|
||||
grub_uint64_t size;
|
||||
grub_uint64_t nblocks;
|
||||
grub_uint32_t extsize;
|
||||
grub_uint32_t nextents;
|
||||
grub_uint16_t unused3;
|
||||
grub_uint8_t fork_offset;
|
||||
grub_uint8_t unused4[17]; /* Last member of inode v2. */
|
||||
grub_uint8_t unused5[20]; /* First member of inode v3. */
|
||||
grub_uint64_t flags2;
|
||||
grub_uint8_t unused6[48]; /* Last member of inode v3. */
|
||||
grub_uint8_t unused4[17];
|
||||
} GRUB_PACKED;
|
||||
|
||||
#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode)
|
||||
/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
|
||||
#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
|
||||
|
||||
struct grub_xfs_dir_leaf_entry
|
||||
{
|
||||
grub_uint32_t hashval;
|
||||
grub_uint32_t address;
|
||||
} GRUB_PACKED;
|
||||
#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
|
||||
#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)
|
||||
|
||||
struct grub_xfs_dirblock_tail
|
||||
{
|
||||
@ -277,7 +220,6 @@ struct grub_fshelp_node
|
||||
|
||||
struct grub_xfs_data
|
||||
{
|
||||
grub_size_t data_size;
|
||||
struct grub_xfs_sblock sblock;
|
||||
grub_disk_t disk;
|
||||
int pos;
|
||||
@ -290,6 +232,8 @@ struct grub_xfs_data
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
|
||||
|
||||
|
||||
static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
|
||||
{
|
||||
return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
|
||||
@ -352,21 +296,9 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_error (GRUB_ERR_BAD_FS, "unsupported XFS filesystem version");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_xfs_sb_needs_repair (struct grub_xfs_data *data)
|
||||
{
|
||||
return ((data->sblock.version &
|
||||
grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) ==
|
||||
grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) &&
|
||||
(data->sblock.sb_features_incompat &
|
||||
grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)));
|
||||
}
|
||||
|
||||
/* Filetype information as used in inodes. */
|
||||
#define FILETYPE_INO_MASK 0170000
|
||||
#define FILETYPE_INO_REG 0100000
|
||||
@ -422,6 +354,7 @@ GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex)
|
||||
return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1));
|
||||
}
|
||||
|
||||
|
||||
static inline grub_uint64_t
|
||||
grub_xfs_inode_block (struct grub_xfs_data *data,
|
||||
grub_uint64_t ino)
|
||||
@ -556,7 +489,7 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
||||
grub_uint64_t block = grub_xfs_inode_block (data, ino);
|
||||
int offset = grub_xfs_inode_offset (data, ino);
|
||||
|
||||
grub_dprintf("xfs", "Reading inode (%" PRIuGRUB_UINT64_T ") - %" PRIuGRUB_UINT64_T ", %d\n",
|
||||
grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n",
|
||||
ino, block, offset);
|
||||
/* Read the inode. */
|
||||
if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
|
||||
@ -576,26 +509,11 @@ get_fsb (const void *keys, int idx)
|
||||
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
|
||||
}
|
||||
|
||||
static int
|
||||
grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode)
|
||||
{
|
||||
return inode->version >= 3 &&
|
||||
(inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64));
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode)
|
||||
{
|
||||
return (grub_xfs_inode_has_large_extent_counts (inode)) ?
|
||||
grub_be_to_cpu64 (inode->nextents_big) :
|
||||
grub_be_to_cpu32 (inode->nextents);
|
||||
}
|
||||
|
||||
static grub_disk_addr_t
|
||||
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_xfs_btree_node *leaf = 0;
|
||||
grub_uint64_t ex, nrec;
|
||||
int ex, nrec;
|
||||
struct grub_xfs_extent *exts;
|
||||
grub_uint64_t ret = 0;
|
||||
|
||||
@ -620,18 +538,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
/ (2 * sizeof (grub_uint64_t));
|
||||
do
|
||||
{
|
||||
grub_uint64_t i;
|
||||
grub_addr_t keys_end, data_end;
|
||||
|
||||
if (grub_mul (sizeof (grub_uint64_t), nrec, &keys_end) ||
|
||||
grub_add ((grub_addr_t) keys, keys_end, &keys_end) ||
|
||||
grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
|
||||
keys_end > data_end)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS root keys");
|
||||
grub_free (leaf);
|
||||
return 0;
|
||||
}
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nrec; i++)
|
||||
{
|
||||
@ -649,10 +556,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
if (grub_disk_read (node->data->disk,
|
||||
GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
|
||||
0, node->data->bsize, leaf))
|
||||
{
|
||||
grub_free (leaf);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if ((!node->data->hascrc &&
|
||||
grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
|
||||
@ -675,20 +579,8 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
}
|
||||
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
|
||||
{
|
||||
grub_addr_t exts_end = 0;
|
||||
grub_addr_t data_end = 0;
|
||||
|
||||
nrec = grub_xfs_get_inode_nextents (&node->inode);
|
||||
nrec = grub_be_to_cpu32 (node->inode.nextents);
|
||||
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
|
||||
|
||||
if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
|
||||
grub_add ((grub_addr_t) node->data, exts_end, &exts_end) ||
|
||||
grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
|
||||
exts_end > data_end)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS extents");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -742,7 +634,6 @@ static char *
|
||||
grub_xfs_read_symlink (grub_fshelp_node_t node)
|
||||
{
|
||||
grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
|
||||
grub_size_t sz;
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
@ -764,12 +655,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
|
||||
if (node->data->hascrc)
|
||||
off = 56;
|
||||
|
||||
if (grub_add (size, 1, &sz))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
|
||||
return 0;
|
||||
}
|
||||
symlink = grub_malloc (sz);
|
||||
symlink = grub_malloc (size + 1);
|
||||
if (!symlink)
|
||||
return 0;
|
||||
|
||||
@ -819,15 +705,8 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
|
||||
{
|
||||
struct grub_fshelp_node *fdiro;
|
||||
grub_err_t err;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow"));
|
||||
grub_print_error ();
|
||||
return 0;
|
||||
}
|
||||
fdiro = grub_malloc (sz);
|
||||
fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
|
||||
if (!fdiro)
|
||||
{
|
||||
grub_print_error ();
|
||||
@ -843,7 +722,6 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
grub_free (fdiro);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -886,20 +764,12 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
if (iterate_dir_call_hook (parent, "..", &ctx))
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < head->count &&
|
||||
(grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++)
|
||||
for (i = 0; i < head->count; i++)
|
||||
{
|
||||
grub_uint64_t ino;
|
||||
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
|
||||
grub_uint8_t c;
|
||||
|
||||
if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "invalid XFS inode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* inopos might be unaligned. */
|
||||
if (smallino)
|
||||
ino = (((grub_uint32_t) inopos[0]) << 24)
|
||||
@ -954,49 +824,24 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
struct grub_xfs_dir2_entry *direntry =
|
||||
grub_xfs_first_de(dir->data, dirblock);
|
||||
int entries = -1;
|
||||
char *end = dirblock + dirblk_size;
|
||||
grub_uint32_t magic;
|
||||
int entries;
|
||||
struct grub_xfs_dirblock_tail *tail =
|
||||
grub_xfs_dir_tail(dir->data, dirblock);
|
||||
|
||||
numread = grub_xfs_read_file (dir, 0, 0,
|
||||
blk << dirblk_log2,
|
||||
dirblk_size, dirblock, 0);
|
||||
if (numread != dirblk_size)
|
||||
{
|
||||
grub_free (dirblock);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this data block isn't actually part of the extent list then
|
||||
* grub_xfs_read_file() returns a block of zeros. So, if the magic
|
||||
* number field is all zeros then this block should be skipped.
|
||||
*/
|
||||
magic = *(grub_uint32_t *)(void *) dirblock;
|
||||
if (!magic)
|
||||
entries = (grub_be_to_cpu32 (tail->leaf_count)
|
||||
- grub_be_to_cpu32 (tail->leaf_stale));
|
||||
|
||||
if (!entries)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Leaf and tail information are only in the data block if the number
|
||||
* of extents is 1.
|
||||
*/
|
||||
if (grub_xfs_get_inode_nextents (&dir->inode) == 1)
|
||||
{
|
||||
struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
|
||||
end = (char *) tail;
|
||||
|
||||
/* Subtract the space used by leaf nodes. */
|
||||
end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry);
|
||||
|
||||
entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
|
||||
if (!entries)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Iterate over all entries within this block. */
|
||||
while ((char *) direntry < (char *) end)
|
||||
while ((char *)direntry < (char *)tail)
|
||||
{
|
||||
grub_uint8_t *freetag;
|
||||
char *filename;
|
||||
@ -1016,34 +861,22 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
filename = (char *)(direntry + 1);
|
||||
if (filename + direntry->len + 1 > (char *) end)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The byte after the filename is for the filetype, padding, or
|
||||
tag, which is not used by GRUB. So it can be overwritten. */
|
||||
filename[direntry->len] = '\0';
|
||||
|
||||
if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
|
||||
if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
|
||||
filename, &ctx))
|
||||
{
|
||||
grub_free (dirblock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The expected number of directory entries is only tracked for the
|
||||
* single extent case.
|
||||
*/
|
||||
if (grub_xfs_get_inode_nextents (&dir->inode) == 1)
|
||||
{
|
||||
/* Check if last direntry in this block is reached. */
|
||||
entries--;
|
||||
if (!entries)
|
||||
break;
|
||||
}
|
||||
/* Check if last direntry in this block is
|
||||
reached. */
|
||||
entries--;
|
||||
if (!entries)
|
||||
break;
|
||||
|
||||
/* Select the next directory entry. */
|
||||
direntry = grub_xfs_next_de(dir->data, direntry);
|
||||
@ -1066,14 +899,11 @@ static struct grub_xfs_data *
|
||||
grub_xfs_mount (grub_disk_t disk)
|
||||
{
|
||||
struct grub_xfs_data *data = 0;
|
||||
grub_size_t sz;
|
||||
|
||||
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
data->data_size = sizeof (struct grub_xfs_data);
|
||||
|
||||
grub_dprintf("xfs", "Reading sb\n");
|
||||
/* Read the superblock. */
|
||||
if (grub_disk_read (disk, 0, 0,
|
||||
@ -1083,19 +913,14 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
if (!grub_xfs_sb_valid(data))
|
||||
goto fail;
|
||||
|
||||
if (grub_xfs_sb_needs_repair (data))
|
||||
grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n");
|
||||
|
||||
if (grub_add (grub_xfs_inode_size (data),
|
||||
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
|
||||
goto fail;
|
||||
|
||||
data = grub_realloc (data, sz);
|
||||
data = grub_realloc (data,
|
||||
sizeof (struct grub_xfs_data)
|
||||
- sizeof (struct grub_xfs_inode)
|
||||
+ grub_xfs_inode_size(data) + 1);
|
||||
|
||||
if (! data)
|
||||
goto fail;
|
||||
|
||||
data->data_size = sz;
|
||||
data->diropen.data = data;
|
||||
data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
|
||||
data->diropen.inode_read = 1;
|
||||
@ -1106,7 +931,7 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
|
||||
data->disk = disk;
|
||||
data->pos = 0;
|
||||
grub_dprintf("xfs", "Reading root ino %" PRIuGRUB_UINT64_T "\n",
|
||||
grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n",
|
||||
grub_cpu_to_be64(data->sblock.rootino));
|
||||
|
||||
grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
|
||||
@ -1114,7 +939,7 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
return data;
|
||||
fail:
|
||||
|
||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE)
|
||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");
|
||||
|
||||
grub_free (data);
|
||||
@ -1122,6 +947,7 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Context for grub_xfs_dir. */
|
||||
struct grub_xfs_dir_ctx
|
||||
{
|
||||
@ -1129,27 +955,6 @@ struct grub_xfs_dir_ctx
|
||||
void *hook_data;
|
||||
};
|
||||
|
||||
/* Bigtime inodes helpers. */
|
||||
#define XFS_BIGTIME_EPOCH_OFFSET (-(grub_int64_t) GRUB_INT32_MIN)
|
||||
|
||||
static int grub_xfs_inode_has_bigtime (const struct grub_xfs_inode *inode)
|
||||
{
|
||||
return inode->version >= 3 &&
|
||||
(inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_BIGTIME));
|
||||
}
|
||||
|
||||
static grub_int64_t
|
||||
grub_xfs_get_inode_time (struct grub_xfs_inode *inode)
|
||||
{
|
||||
struct grub_xfs_time_legacy *lts;
|
||||
|
||||
if (grub_xfs_inode_has_bigtime (inode))
|
||||
return grub_divmod64 (grub_be_to_cpu64 (inode->mtime), NSEC_PER_SEC, NULL) - XFS_BIGTIME_EPOCH_OFFSET;
|
||||
|
||||
lts = (struct grub_xfs_time_legacy *) &inode->mtime;
|
||||
return grub_be_to_cpu32 (lts->sec);
|
||||
}
|
||||
|
||||
/* Helper for grub_xfs_dir. */
|
||||
static int
|
||||
grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
@ -1162,9 +967,11 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
if (node->inode_read)
|
||||
{
|
||||
info.mtimeset = 1;
|
||||
info.mtime = grub_xfs_get_inode_time (&node->inode);
|
||||
info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
|
||||
}
|
||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||
if (!info.dir)
|
||||
info.size = node->inode.size;
|
||||
grub_free (node);
|
||||
return ctx->hook (filename, &info, ctx->hook_data);
|
||||
}
|
||||
@ -1327,6 +1134,8 @@ grub_xfs_uuid (grub_device_t device, char **uuid)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct grub_fs grub_xfs_fs =
|
||||
{
|
||||
.name = "xfs",
|
||||
@ -1345,7 +1154,6 @@ static struct grub_fs grub_xfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(xfs)
|
||||
{
|
||||
//grub_xfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_xfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-2013, Yann Collet.
|
||||
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
* - LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*/
|
||||
|
||||
#include <grub/err.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
|
||||
int isize, int maxOutputSize);
|
||||
|
||||
/*
|
||||
* CPU Feature Detection
|
||||
*/
|
||||
|
||||
/* 32 or 64 bits ? */
|
||||
#if (GRUB_CPU_SIZEOF_VOID_P == 8)
|
||||
#define LZ4_ARCH64 1
|
||||
#else
|
||||
#define LZ4_ARCH64 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compiler Options
|
||||
*/
|
||||
|
||||
|
||||
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
|
||||
#if (GCC_VERSION >= 302) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 800) || defined(__clang__)
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
#else
|
||||
#define expect(expr, value) (expr)
|
||||
#endif
|
||||
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
|
||||
/* Basic types */
|
||||
#define BYTE grub_uint8_t
|
||||
#define U16 grub_uint16_t
|
||||
#define U32 grub_uint32_t
|
||||
#define S32 grub_int32_t
|
||||
#define U64 grub_uint64_t
|
||||
|
||||
typedef struct _U16_S {
|
||||
U16 v;
|
||||
} GRUB_PACKED U16_S;
|
||||
typedef struct _U32_S {
|
||||
U32 v;
|
||||
} GRUB_PACKED U32_S;
|
||||
typedef struct _U64_S {
|
||||
U64 v;
|
||||
} GRUB_PACKED U64_S;
|
||||
|
||||
#define A64(x) (((U64_S *)(x))->v)
|
||||
#define A32(x) (((U32_S *)(x))->v)
|
||||
#define A16(x) (((U16_S *)(x))->v)
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
#define MINMATCH 4
|
||||
|
||||
#define COPYLENGTH 8
|
||||
#define LASTLITERALS 5
|
||||
|
||||
#define ML_BITS 4
|
||||
#define ML_MASK ((1U<<ML_BITS)-1)
|
||||
#define RUN_BITS (8-ML_BITS)
|
||||
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
||||
|
||||
/*
|
||||
* Architecture-specific macros
|
||||
*/
|
||||
#if LZ4_ARCH64
|
||||
#define STEPSIZE 8
|
||||
#define UARCH U64
|
||||
#define AARCH A64
|
||||
#define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8;
|
||||
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d)
|
||||
#define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e)
|
||||
#define HTYPE U32
|
||||
#define INITBASE(base) const BYTE* const base = ip
|
||||
#else
|
||||
#define STEPSIZE 4
|
||||
#define UARCH U32
|
||||
#define AARCH A32
|
||||
#define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4;
|
||||
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
|
||||
#define LZ4_SECURECOPY LZ4_WILDCOPY
|
||||
#define HTYPE const BYTE*
|
||||
#define INITBASE(base) const int base = 0
|
||||
#endif
|
||||
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - grub_le_to_cpu16 (A16 (p)); }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = grub_cpu_to_le16 (v); p += 2; }
|
||||
|
||||
/* Macros */
|
||||
#define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
|
||||
|
||||
/* Decompression functions */
|
||||
grub_err_t
|
||||
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len);
|
||||
|
||||
grub_err_t
|
||||
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len)
|
||||
{
|
||||
const BYTE *src = s_start;
|
||||
U32 bufsiz = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) |
|
||||
src[3];
|
||||
|
||||
/* invalid compressed buffer size encoded at start */
|
||||
if (bufsiz + 4 > s_len)
|
||||
return grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed.");
|
||||
|
||||
/*
|
||||
* Returns 0 on success (decompression function returned non-negative)
|
||||
* and appropriate error on failure (decompression function returned negative).
|
||||
*/
|
||||
return (LZ4_uncompress_unknownOutputSize((char*)s_start + 4, d_start, bufsiz,
|
||||
d_len) < 0)?grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."):0;
|
||||
}
|
||||
|
||||
int
|
||||
LZ4_uncompress_unknownOutputSize(const char *source,
|
||||
char *dest, int isize, int maxOutputSize)
|
||||
{
|
||||
/* Local Variables */
|
||||
const BYTE * ip = (const BYTE *) source;
|
||||
const BYTE *const iend = ip + isize;
|
||||
const BYTE * ref;
|
||||
|
||||
BYTE * op = (BYTE *) dest;
|
||||
BYTE *const oend = op + maxOutputSize;
|
||||
BYTE *cpy;
|
||||
|
||||
grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
|
||||
|
||||
/* Main Loop */
|
||||
while (ip < iend) {
|
||||
BYTE token;
|
||||
int length;
|
||||
|
||||
/* get runlength */
|
||||
token = *ip++;
|
||||
if ((length = (token >> ML_BITS)) == RUN_MASK) {
|
||||
int s = 255;
|
||||
while ((ip < iend) && (s == 255)) {
|
||||
s = *ip++;
|
||||
length += s;
|
||||
}
|
||||
}
|
||||
/* copy literals */
|
||||
if ((grub_addr_t) length > ~(grub_addr_t)op)
|
||||
goto _output_error;
|
||||
cpy = op + length;
|
||||
if ((cpy > oend - COPYLENGTH) ||
|
||||
(ip + length > iend - COPYLENGTH)) {
|
||||
if (cpy > oend)
|
||||
/*
|
||||
* Error: request to write beyond destination
|
||||
* buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
if (ip + length > iend)
|
||||
/*
|
||||
* Error : request to read beyond source
|
||||
* buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
grub_memcpy(op, ip, length);
|
||||
op += length;
|
||||
ip += length;
|
||||
if (ip < iend)
|
||||
/* Error : LZ4 format violation */
|
||||
goto _output_error;
|
||||
/* Necessarily EOF, due to parsing restrictions. */
|
||||
break;
|
||||
}
|
||||
LZ4_WILDCOPY(ip, op, cpy);
|
||||
ip -= (op - cpy);
|
||||
op = cpy;
|
||||
|
||||
/* get offset */
|
||||
LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
|
||||
ip += 2;
|
||||
if (ref < (BYTE * const) dest)
|
||||
/*
|
||||
* Error: offset creates reference outside of
|
||||
* destination buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
|
||||
/* get matchlength */
|
||||
if ((length = (token & ML_MASK)) == ML_MASK) {
|
||||
while (ip < iend) {
|
||||
int s = *ip++;
|
||||
length += s;
|
||||
if (s == 255)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* copy repeated sequence */
|
||||
if unlikely(op - ref < STEPSIZE) {
|
||||
#if LZ4_ARCH64
|
||||
grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
||||
grub_size_t dec2 = dec2table[op - ref];
|
||||
#else
|
||||
const int dec2 = 0;
|
||||
#endif
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
ref -= dec[op - ref];
|
||||
A32(op) = A32(ref);
|
||||
op += STEPSIZE - 4;
|
||||
ref -= dec2;
|
||||
} else {
|
||||
LZ4_COPYSTEP(ref, op);
|
||||
}
|
||||
cpy = op + length - (STEPSIZE - 4);
|
||||
if (cpy > oend - COPYLENGTH) {
|
||||
if (cpy > oend)
|
||||
/*
|
||||
* Error: request to write outside of
|
||||
* destination buffer.
|
||||
*/
|
||||
goto _output_error;
|
||||
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
|
||||
while (op < cpy)
|
||||
*op++ = *ref++;
|
||||
op = cpy;
|
||||
if (op == oend)
|
||||
/*
|
||||
* Check EOF (should never happen, since last
|
||||
* 5 bytes are supposed to be literals).
|
||||
*/
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
LZ4_SECURECOPY(ref, op, cpy);
|
||||
op = cpy; /* correction */
|
||||
}
|
||||
|
||||
/* end of decoding */
|
||||
return (int)(((char *)op) - dest);
|
||||
|
||||
/* write overflow error detected */
|
||||
_output_error:
|
||||
return (int)(-(((char *)ip) - source));
|
||||
}
|
@ -119,8 +119,6 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
||||
view->menu = menu;
|
||||
view->nested = nested;
|
||||
view->first_timeout = -1;
|
||||
if (menu->size)
|
||||
view->menu_title_offset = grub_zalloc (sizeof (*view->menu_title_offset) * menu->size);
|
||||
|
||||
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
|
||||
if (view->double_repaint)
|
||||
@ -136,8 +134,6 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
||||
instance->fini = grub_gfxmenu_viewer_fini;
|
||||
instance->print_timeout = grub_gfxmenu_print_timeout;
|
||||
instance->clear_timeout = grub_gfxmenu_clear_timeout;
|
||||
if (view->menu_title_offset)
|
||||
instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry;
|
||||
|
||||
grub_menu_register_viewer (instance);
|
||||
|
||||
|
@ -28,10 +28,7 @@
|
||||
|
||||
extern int g_ventoy_memdisk_mode;
|
||||
extern int g_ventoy_iso_raw;
|
||||
extern int g_ventoy_grub2_mode;
|
||||
extern int g_ventoy_wimboot_mode;
|
||||
extern int g_ventoy_iso_uefi_drv;
|
||||
extern char g_ventoy_hotkey_tip[256];
|
||||
|
||||
static const char *align_options[] =
|
||||
{
|
||||
@ -60,15 +57,11 @@ struct grub_gui_label
|
||||
grub_font_t font;
|
||||
grub_video_rgba_color_t color;
|
||||
int value;
|
||||
int vtoytip;
|
||||
enum align_mode align;
|
||||
};
|
||||
|
||||
typedef struct grub_gui_label *grub_gui_label_t;
|
||||
|
||||
extern const char * g_ventoy_tip_msg1;
|
||||
extern const char * g_ventoy_tip_msg2;
|
||||
|
||||
static void
|
||||
label_destroy (void *vself)
|
||||
{
|
||||
@ -95,7 +88,6 @@ label_is_instance (void *vself __attribute__((unused)), const char *type)
|
||||
static void
|
||||
label_paint (void *vself, const grub_video_rect_t *region)
|
||||
{
|
||||
const char *text;
|
||||
grub_gui_label_t self = vself;
|
||||
|
||||
if (! self->visible)
|
||||
@ -104,24 +96,16 @@ label_paint (void *vself, const grub_video_rect_t *region)
|
||||
if (!grub_video_have_common_points (region, &self->bounds))
|
||||
return;
|
||||
|
||||
if (self->vtoytip == 1) {
|
||||
text = g_ventoy_tip_msg1 ? g_ventoy_tip_msg1 : "";
|
||||
} else if (self->vtoytip == 2) {
|
||||
text = g_ventoy_tip_msg2 ? g_ventoy_tip_msg2 : "";
|
||||
} else {
|
||||
text = self->text;
|
||||
}
|
||||
|
||||
/* Calculate the starting x coordinate. */
|
||||
int left_x;
|
||||
if (self->align == align_left)
|
||||
left_x = 0;
|
||||
else if (self->align == align_center)
|
||||
left_x = (self->bounds.width
|
||||
- grub_font_get_string_width (self->font, text)) / 2;
|
||||
- grub_font_get_string_width (self->font, self->text)) / 2;
|
||||
else if (self->align == align_right)
|
||||
left_x = (self->bounds.width
|
||||
- grub_font_get_string_width (self->font, text));
|
||||
- grub_font_get_string_width (self->font, self->text));
|
||||
else
|
||||
return; /* Invalid alignment. */
|
||||
|
||||
@ -130,7 +114,7 @@ label_paint (void *vself, const grub_video_rect_t *region)
|
||||
|
||||
grub_video_rect_t vpsave;
|
||||
grub_gui_set_viewport (&self->bounds, &vpsave);
|
||||
grub_font_draw_string (text,
|
||||
grub_font_draw_string (self->text,
|
||||
self->font,
|
||||
grub_video_map_rgba_color (self->color),
|
||||
left_x,
|
||||
@ -170,8 +154,8 @@ static void
|
||||
label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
*width = grub_font_get_string_width (self->font, self->text);
|
||||
*height = (grub_font_get_ascent (self->font)
|
||||
*width = grub_font_get_string_width (self->font, self->text);
|
||||
*height = (grub_font_get_ascent (self->font)
|
||||
+ grub_font_get_descent (self->font));
|
||||
}
|
||||
|
||||
@ -221,21 +205,14 @@ label_set_property (void *vself, const char *name, const char *value)
|
||||
else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
|
||||
value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_GRUB2_MODE@") == 0) {
|
||||
value = g_ventoy_grub2_mode ? grub_env_get("VTOY_GRUB2_MODE_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_WIMBOOT_MODE@") == 0) {
|
||||
value = g_ventoy_wimboot_mode ? grub_env_get("VTOY_WIMBOOT_MODE_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) {
|
||||
value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
|
||||
value = g_ventoy_hotkey_tip;
|
||||
} else if (value[0] == '@' && value[1] == '@' && value[2]) {
|
||||
value = grub_env_get(value + 2);
|
||||
if (!value)
|
||||
value = " ";
|
||||
value = grub_env_get("VTOY_HOTKEY_TIP");
|
||||
if (value == NULL) {
|
||||
value = _(" ");
|
||||
}
|
||||
}
|
||||
|
||||
self->template = grub_strdup (value);
|
||||
@ -270,14 +247,8 @@ label_set_property (void *vself, const char *name, const char *value)
|
||||
{
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->id);
|
||||
if (value) {
|
||||
if (value)
|
||||
self->id = grub_strdup (value);
|
||||
if (grub_strcmp(value, "VTOY_MENU_TIP_1") == 0) {
|
||||
self->vtoytip = 1;
|
||||
} else if (grub_strcmp(value, "VTOY_MENU_TIP_2") == 0) {
|
||||
self->vtoytip = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
self->id = 0;
|
||||
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user