mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-12-14 07:46:20 +00:00
Compare commits
523 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
392d8ef4fa | ||
|
|
d1900c75cd | ||
|
|
fa7e1d5fa0 | ||
|
|
6ae8bf840d | ||
|
|
ce862da402 | ||
|
|
6d4f5ff00b | ||
|
|
ab0f25d097 | ||
|
|
ff14c07c4e | ||
|
|
f7fac26c91 | ||
|
|
ebae102f41 | ||
|
|
c3718d6001 | ||
|
|
d0744513a6 | ||
|
|
5b0fca8468 | ||
|
|
27918eb3f9 | ||
|
|
7859271b20 | ||
|
|
1c27c0b489 | ||
|
|
0f89c2767f | ||
|
|
d1584c10b4 | ||
|
|
43e921878b | ||
|
|
23f4f18e27 | ||
|
|
53b95ae17b | ||
|
|
e3506c0f10 | ||
|
|
9118d5fe45 | ||
|
|
f130325a9c | ||
|
|
1ca48923da | ||
|
|
730fdd5198 | ||
|
|
d0f3597b26 | ||
|
|
045f53d768 | ||
|
|
a173acaf17 | ||
|
|
96fdd594f0 | ||
|
|
62dc0033ad | ||
|
|
1c3fcbdfe9 | ||
|
|
7d37cab21d | ||
|
|
a1c6fe2d24 | ||
|
|
dbeb4023a2 | ||
|
|
58b1bbe0b5 | ||
|
|
86b13727ca | ||
|
|
006f26d07d | ||
|
|
9203aa1ab3 | ||
|
|
5291d66736 | ||
|
|
ba5978d298 | ||
|
|
7f717a7fe9 | ||
|
|
c57717aea2 | ||
|
|
be0e19fc5b | ||
|
|
34a36bfc3e | ||
|
|
82e99a3b37 | ||
|
|
b685431d66 | ||
|
|
8be8fd50b3 | ||
|
|
999b15c4ef | ||
|
|
28998edd94 | ||
|
|
2ad69decad | ||
|
|
c2cc0bd3dc | ||
|
|
b128a0b6d3 | ||
|
|
676831dbbe | ||
|
|
e5fa5e6d84 | ||
|
|
76a6b8061c | ||
|
|
036b58ff0c | ||
|
|
8e529c8559 | ||
|
|
b8e624b0a0 | ||
|
|
1f49265f29 | ||
|
|
25dc323522 | ||
|
|
446597d880 | ||
|
|
b9b6852631 | ||
|
|
4a44a82840 | ||
|
|
f2e82862ab | ||
|
|
368151aa3b | ||
|
|
b5dcaecffe | ||
|
|
a4cfbd6799 | ||
|
|
ab964932cb | ||
|
|
bcc81d31db | ||
|
|
91330b97bf | ||
|
|
fe7b9abcff | ||
|
|
68d3b55167 | ||
|
|
e1c26567a1 | ||
|
|
4131d95cef | ||
|
|
8c18f91ac1 | ||
|
|
73fabd0c65 | ||
|
|
0c140cf378 | ||
|
|
293f677cbf | ||
|
|
4bf43ab9d4 | ||
|
|
9eeb94e8b5 | ||
|
|
f4987fd7f4 | ||
|
|
157c6f13ec | ||
|
|
6a506ee7f3 | ||
|
|
32643ecdbb | ||
|
|
d2e5930520 | ||
|
|
944f376ffe | ||
|
|
d402338ade | ||
|
|
d938100eeb | ||
|
|
a4200ed99e | ||
|
|
e4ccd5115e | ||
|
|
cdb727dd22 | ||
|
|
6b4093fb93 | ||
|
|
21450d4a56 | ||
|
|
164c8d6505 | ||
|
|
37e7a539f9 | ||
|
|
b5a649f96f | ||
|
|
443a1344f2 | ||
|
|
d3de1a91f8 | ||
|
|
580ad598f6 | ||
|
|
0891e34d47 | ||
|
|
4d777090cb | ||
|
|
b0568922d2 | ||
|
|
69b6bb8fca | ||
|
|
3d686c27d7 | ||
|
|
90ba217ec7 | ||
|
|
fab070ef64 | ||
|
|
b3869b6894 | ||
|
|
563214ed40 | ||
|
|
b67f738b00 | ||
|
|
a9c539572b | ||
|
|
32602a79ab | ||
|
|
863eafd2cc | ||
|
|
0f135b6646 | ||
|
|
675c24ffa3 | ||
|
|
cd309eb663 | ||
|
|
5cdd6540a4 | ||
|
|
fde2e4430c | ||
|
|
9a471f4956 | ||
|
|
1f3b3afa35 | ||
|
|
6947f2a047 | ||
|
|
0a15e4e427 | ||
|
|
e763d7590f | ||
|
|
f842d46f90 | ||
|
|
cc1cc6c301 | ||
|
|
9f3d209798 | ||
|
|
fc742244ab | ||
|
|
3e66227dae | ||
|
|
f32d342f66 | ||
|
|
09d7ae68e7 | ||
|
|
68fefbc1fc | ||
|
|
8d893d4c94 | ||
|
|
84798a4f7a | ||
|
|
87f88eeb2b | ||
|
|
7b2615744c | ||
|
|
d7faff4438 | ||
|
|
f15dfd7409 | ||
|
|
09162e8d97 | ||
|
|
eb8fcc8f30 | ||
|
|
5fcb3971bc | ||
|
|
e47e4484ce | ||
|
|
7e26decb31 | ||
|
|
e713946fd0 | ||
|
|
a93b0f6656 | ||
|
|
836e1aa11e | ||
|
|
154bbc6e5f | ||
|
|
d151e74336 | ||
|
|
df87cafdfb | ||
|
|
09494a5b23 | ||
|
|
e15a1c5ece | ||
|
|
f5843f576b | ||
|
|
be5bc6f3b7 | ||
|
|
f3b65452f4 | ||
|
|
ec4b6c2a2c | ||
|
|
be8b6e8976 | ||
|
|
82b1faa132 | ||
|
|
52ae65f54d | ||
|
|
ee104bfa97 | ||
|
|
9cfd05811b | ||
|
|
0c66908935 | ||
|
|
f53de3bdb0 | ||
|
|
8516786b31 | ||
|
|
f7c78879c7 | ||
|
|
f3e267a09e | ||
|
|
7c1370dcb0 | ||
|
|
1b5aa9c61d | ||
|
|
d6eba15d71 | ||
|
|
734c7b8ac4 | ||
|
|
0fa25c4526 | ||
|
|
1473be0e4c | ||
|
|
cd9aa16b20 | ||
|
|
a9be2fd4d9 | ||
|
|
f354d2b733 | ||
|
|
aa033e1fb6 | ||
|
|
9351fe4f97 | ||
|
|
67b8a34e8c | ||
|
|
c18399e8b4 | ||
|
|
5a591c1ae7 | ||
|
|
e208199cca | ||
|
|
4c9065a60d | ||
|
|
4fd4977c3a | ||
|
|
93614c3251 | ||
|
|
1db0827463 | ||
|
|
72d0fd0dd4 | ||
|
|
47797f0285 | ||
|
|
849eb7bf2c | ||
|
|
32c5b5deea | ||
|
|
d72bb15956 | ||
|
|
89a34bac18 | ||
|
|
8cecdae8f9 | ||
|
|
471432fc50 | ||
|
|
a78e19608b | ||
|
|
5e97d56033 | ||
|
|
a5041ad43c | ||
|
|
3149a67599 | ||
|
|
d0b7927b51 | ||
|
|
8775684367 | ||
|
|
d148139227 | ||
|
|
dd2411d7d4 | ||
|
|
7db83dc0f1 | ||
|
|
787d950f28 | ||
|
|
892a819da4 | ||
|
|
bfc5eaebb9 | ||
|
|
e7d05df9fa | ||
|
|
ca07b52cb2 | ||
|
|
1a2a35f5bc | ||
|
|
d71514f23e | ||
|
|
c5af17e04e | ||
|
|
05e208ea2a | ||
|
|
112c557428 | ||
|
|
92db873b5c | ||
|
|
3c01eec4af | ||
|
|
5c6d18fcd4 | ||
|
|
84ec4b0de4 | ||
|
|
9615e7eaa0 | ||
|
|
6a244ff260 | ||
|
|
b5503a7375 | ||
|
|
0b7fa630a4 | ||
|
|
7babe823d6 | ||
|
|
6db513a067 | ||
|
|
bafac7479d | ||
|
|
d3138479d7 | ||
|
|
56a1543f7d | ||
|
|
659ac1cfe3 | ||
|
|
c83daa86b6 | ||
|
|
dfcfaa9967 | ||
|
|
188f9e707c | ||
|
|
8b975b5e80 | ||
|
|
2ab717cc66 | ||
|
|
88793d548a | ||
|
|
5fea6eab7e | ||
|
|
5d55dc68ae | ||
|
|
2c320aad60 | ||
|
|
b63034b2c7 | ||
|
|
6c113880e5 | ||
|
|
e2656c287b | ||
|
|
d8433985e7 | ||
|
|
b003105925 | ||
|
|
2ca2c83b6b | ||
|
|
dff7e495ca | ||
|
|
cf0f395c56 | ||
|
|
69bc90da42 | ||
|
|
ffc40234ca | ||
|
|
e57daa5065 | ||
|
|
5c733a20f8 | ||
|
|
069342ab9a | ||
|
|
32a964eded | ||
|
|
51b92f398a | ||
|
|
5d0ebf4510 | ||
|
|
cf94487ad5 | ||
|
|
af83f46a3d | ||
|
|
4910e9f380 | ||
|
|
fb38b321c2 | ||
|
|
7b78fe555e | ||
|
|
094ba61848 | ||
|
|
faa0e46d3a | ||
|
|
537f0eaa7e | ||
|
|
c8cf9b7ce2 | ||
|
|
4c71d7c190 | ||
|
|
47f9f2c42c | ||
|
|
fc3a5fae36 | ||
|
|
b3982d4930 | ||
|
|
c280baae27 | ||
|
|
425d640480 | ||
|
|
07d4140cf4 | ||
|
|
90ae07d227 | ||
|
|
e3e21eb6e6 | ||
|
|
c8ce2ae85a | ||
|
|
c02a6955c3 | ||
|
|
6b78603dd3 | ||
|
|
07a386c963 | ||
|
|
eb048c0075 | ||
|
|
37ac3f312f | ||
|
|
092cff8429 | ||
|
|
b347c1b5da | ||
|
|
da746c608f | ||
|
|
81aa56955a | ||
|
|
d1679871a6 | ||
|
|
f383052013 | ||
|
|
667f5bcc1b | ||
|
|
af69cb7f44 | ||
|
|
7bb13fc18a | ||
|
|
7fce7e0aba | ||
|
|
2a435084c2 | ||
|
|
c0c454a436 | ||
|
|
63924fa8bd | ||
|
|
3e47f5e8de | ||
|
|
b5eb347244 | ||
|
|
9225c940a6 | ||
|
|
a8edb99d28 | ||
|
|
ac3ab97686 | ||
|
|
c42a8c6d93 | ||
|
|
4b1dd4d3af | ||
|
|
f342be1d6c | ||
|
|
f4774ee0e4 | ||
|
|
d3cfa73631 | ||
|
|
331080fb95 | ||
|
|
99fbd14f08 | ||
|
|
1c5aeb35dc | ||
|
|
f7b3bd1729 | ||
|
|
672632a0c2 | ||
|
|
d07aa6ce07 | ||
|
|
93996cf7e2 | ||
|
|
ca62128f9b | ||
|
|
265b70f1c7 | ||
|
|
491f0bea8a | ||
|
|
47e77e003c | ||
|
|
d05eab2be1 | ||
|
|
849dfb463d | ||
|
|
7715bd705c | ||
|
|
042ca4b5e3 | ||
|
|
e1099e1e5b | ||
|
|
c6be35f2c0 | ||
|
|
b15a96b747 | ||
|
|
6bd0463d34 | ||
|
|
1ce568d971 | ||
|
|
f82475d950 | ||
|
|
aad154616c | ||
|
|
83c3a932d3 | ||
|
|
0aff8f5109 | ||
|
|
2750f0c5a7 | ||
|
|
f71a1fcce9 | ||
|
|
e252fab9a4 | ||
|
|
37212a8ea4 | ||
|
|
e71221cdba | ||
|
|
65a2cb1685 | ||
|
|
e23e76f54e | ||
|
|
8ded032c92 | ||
|
|
fc5cd0a00a | ||
|
|
6cc400b8d4 | ||
|
|
ffc915ca53 | ||
|
|
8ebe972f6e | ||
|
|
39975dd1c3 | ||
|
|
1a648d8689 | ||
|
|
8234961228 | ||
|
|
e1ffbad431 | ||
|
|
4a66104c6e | ||
|
|
32bcd8f87b | ||
|
|
26c1756e8d | ||
|
|
f4bbec65ba | ||
|
|
58d387f732 | ||
|
|
2e10aabe94 | ||
|
|
a63a41f79d | ||
|
|
64748308a3 | ||
|
|
33cc1e271a | ||
|
|
291e0a3a38 | ||
|
|
0717195481 | ||
|
|
26b3bca25b | ||
|
|
5d3285356e | ||
|
|
1e12969555 | ||
|
|
db892d5e12 | ||
|
|
7166164afe | ||
|
|
67e839b9f2 | ||
|
|
dce5d1b769 | ||
|
|
83d91c525f | ||
|
|
78df21fc40 | ||
|
|
1840cb8f38 | ||
|
|
b63ce2a3df | ||
|
|
bb7e10d93e | ||
|
|
324c97883a | ||
|
|
3c35345e38 | ||
|
|
9f357f8ed1 | ||
|
|
eb1a014d5b | ||
|
|
cbbd57eee5 | ||
|
|
7b08954e57 | ||
|
|
08634fba9f | ||
|
|
96c5a25263 | ||
|
|
43e8ec5785 | ||
|
|
7279ba9bc8 | ||
|
|
3929ed55ca | ||
|
|
fd6580be72 | ||
|
|
12e8ae26ae | ||
|
|
82977d9b8a | ||
|
|
3541735796 | ||
|
|
c82e4296d3 | ||
|
|
cc9ff41589 | ||
|
|
08d218fd82 | ||
|
|
2185556dfd | ||
|
|
97be7b8bfb | ||
|
|
3dd3b7d26f | ||
|
|
6ded335527 | ||
|
|
3545dfa29f | ||
|
|
b0208c8ce3 | ||
|
|
b1d5237041 | ||
|
|
a37c6af8d0 | ||
|
|
61d4248d51 | ||
|
|
dccefc5277 | ||
|
|
66d5946bd1 | ||
|
|
198dcd94a6 | ||
|
|
f26a927b3e | ||
|
|
08e7da50ef | ||
|
|
c7bb6270cc | ||
|
|
a5e998bcaf | ||
|
|
15570cd996 | ||
|
|
e76edf9286 | ||
|
|
195431479c | ||
|
|
18f35dafbf | ||
|
|
519fac719e | ||
|
|
ee81f89911 | ||
|
|
b1ad99cde0 | ||
|
|
715f410832 | ||
|
|
17da2e2a21 | ||
|
|
de6eb54853 | ||
|
|
85f6f3213f | ||
|
|
80a088babb | ||
|
|
183175cad2 | ||
|
|
390eec4218 | ||
|
|
620bcad324 | ||
|
|
bae671bd68 | ||
|
|
1e75385146 | ||
|
|
725a33f988 | ||
|
|
1f1769d235 | ||
|
|
a129996756 | ||
|
|
8632e56561 | ||
|
|
8f711c9db9 | ||
|
|
b0cacd6686 | ||
|
|
13b2192a59 | ||
|
|
807d313cd5 | ||
|
|
2f45cea46e | ||
|
|
7cdc7386a8 | ||
|
|
44bb72ca0a | ||
|
|
5e6b0800bd | ||
|
|
01c902e026 | ||
|
|
a68629a931 | ||
|
|
c84855bbee | ||
|
|
f2ed81b004 | ||
|
|
6434e453b2 | ||
|
|
041ccb7435 | ||
|
|
bfe194c190 | ||
|
|
fb7008f49a | ||
|
|
463d0b2004 | ||
|
|
4707b76bb2 | ||
|
|
ff0ad76d8d | ||
|
|
c8b2cca7c2 | ||
|
|
afbeba7cf5 | ||
|
|
bb3789f6fc | ||
|
|
ea8a9e83ab | ||
|
|
8b9901a6a5 | ||
|
|
0ac83bffda | ||
|
|
40c0504dfb | ||
|
|
ebaa4d954a | ||
|
|
2936666a78 | ||
|
|
784e3ae879 | ||
|
|
d8fbd79dda | ||
|
|
8c192a1807 | ||
|
|
e8d17f9bb1 | ||
|
|
2283c3e8b0 | ||
|
|
8bbd5a14a3 | ||
|
|
f7d7db6a18 | ||
|
|
147a23c9dd | ||
|
|
062c71b972 | ||
|
|
78ab7a0759 | ||
|
|
3ebd58c9df | ||
|
|
ce6d379564 | ||
|
|
40fdfa66b9 | ||
|
|
9ddee7394d | ||
|
|
c9b316a757 | ||
|
|
1ba23bcdff | ||
|
|
6630ab3585 | ||
|
|
c0d478c2dd | ||
|
|
0217c5a923 | ||
|
|
97312d351e | ||
|
|
906dc4cd41 | ||
|
|
82a8b59bc7 | ||
|
|
b53e1fb8a8 | ||
|
|
84abffc424 | ||
|
|
bf4e014023 | ||
|
|
4f840ed673 | ||
|
|
d02f184a8d | ||
|
|
774e38928f | ||
|
|
0faba673a5 | ||
|
|
3c649b281f | ||
|
|
5f409a1208 | ||
|
|
9eb334d99a | ||
|
|
260a3269b7 | ||
|
|
a287bf8907 | ||
|
|
48a1b80be0 | ||
|
|
b9ef72fbe9 | ||
|
|
390507fff7 | ||
|
|
a29bdfbc3c | ||
|
|
21735f92d6 | ||
|
|
9a8d4d0227 | ||
|
|
6ebe77792c | ||
|
|
d678e54956 | ||
|
|
8dce0adda6 | ||
|
|
1bf3e73373 | ||
|
|
a9996d6761 | ||
|
|
dafea731c8 | ||
|
|
6d093e88e7 | ||
|
|
58a93cdb40 | ||
|
|
9962775296 | ||
|
|
062f816020 | ||
|
|
89b7232b76 | ||
|
|
1186caba41 | ||
|
|
be50ea69aa | ||
|
|
433d854aab | ||
|
|
4cb9134e5c | ||
|
|
faceaf4267 | ||
|
|
37edd5a349 | ||
|
|
ed0f8721d7 | ||
|
|
d80a008c04 | ||
|
|
036e9cc167 | ||
|
|
26258653b7 | ||
|
|
754e754412 | ||
|
|
5af01de7c2 | ||
|
|
f9763a44b2 | ||
|
|
d063dbb7f2 | ||
|
|
89938e3c78 | ||
|
|
85840f626b | ||
|
|
7d1507906d | ||
|
|
0f8478fbe1 | ||
|
|
a6d3ecc7a9 | ||
|
|
5817b8b7b0 | ||
|
|
8493715fb4 | ||
|
|
3c46432d6f | ||
|
|
88dcceeabc | ||
|
|
ef204263ad | ||
|
|
e08e6705cf | ||
|
|
a8b2fdccc7 | ||
|
|
85348956df | ||
|
|
aa0a2ed067 | ||
|
|
49ceaa0f61 | ||
|
|
23986d742d |
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@@ -6,7 +6,7 @@ open_collective: # Replace with a single Open Collective username
|
|||||||
ko_fi: # Replace with a single Ko-fi username
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
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
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
liberapay: # Replace with a single Liberapay username
|
liberapay: Ventoy
|
||||||
issuehunt: # Replace with a single IssueHunt username
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
otechie: # Replace with a single Otechie username
|
otechie: # Replace with a single Otechie username
|
||||||
custom: ['https://www.ventoy.net/en/donation.html'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
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
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
100
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
100
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
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.71
|
||||||
|
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: 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
Normal file
101
.github/ISSUE_TEMPLATE/success_image_report.yml
vendored
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
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 envrionment
|
||||||
|
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
Normal file
37
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Ventoy CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Run docker-compose up
|
||||||
|
run: docker-compose up
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ventoy-windows
|
||||||
|
path: INSTALL/ventoy-*windows*
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ventoy-linux
|
||||||
|
path: INSTALL/ventoy-*linux*
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ventoy-livecd
|
||||||
|
path: INSTALL/ventoy-*livecd*
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: SHA256SUM
|
||||||
|
path: INSTALL/sha256.txt
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: xxx-build-log
|
||||||
|
path: DOC/build.log
|
||||||
25
.github/workflows/sync2gitee.yml
vendored
Normal file
25
.github/workflows/sync2gitee.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
1166
BUSYBOX/aarch64_ash.config
Normal file
1166
BUSYBOX/aarch64_ash.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/aarch64_hexdump.config
Normal file
1166
BUSYBOX/aarch64_hexdump.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/aarch64_xzcat.config
Normal file
1166
BUSYBOX/aarch64_xzcat.config
Normal file
File diff suppressed because it is too large
Load Diff
55
BUSYBOX/build.txt
Normal file
55
BUSYBOX/build.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
======== 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
33
BUSYBOX/chmod/build.sh
Normal file
33
BUSYBOX/chmod/build.sh
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/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/
|
||||||
|
|
||||||
34
BUSYBOX/chmod/vtchmod.c
Normal file
34
BUSYBOX/chmod/vtchmod.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
BIN
BUSYBOX/chmod/vtchmod32
Normal file
BIN
BUSYBOX/chmod/vtchmod32
Normal file
Binary file not shown.
BIN
BUSYBOX/chmod/vtchmod64
Normal file
BIN
BUSYBOX/chmod/vtchmod64
Normal file
Binary file not shown.
BIN
BUSYBOX/chmod/vtchmod64_musl
Normal file
BIN
BUSYBOX/chmod/vtchmod64_musl
Normal file
Binary file not shown.
BIN
BUSYBOX/chmod/vtchmodaa64
Normal file
BIN
BUSYBOX/chmod/vtchmodaa64
Normal file
Binary file not shown.
BIN
BUSYBOX/chmod/vtchmodm64e
Normal file
BIN
BUSYBOX/chmod/vtchmodm64e
Normal file
Binary file not shown.
1181
BUSYBOX/config
Normal file
1181
BUSYBOX/config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/mips64el_ash.config
Normal file
1166
BUSYBOX/mips64el_ash.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/mips64el_hexdump.config
Normal file
1166
BUSYBOX/mips64el_hexdump.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/mips64el_xzcat.config
Normal file
1166
BUSYBOX/mips64el_xzcat.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/x86_64_ash.config
Normal file
1166
BUSYBOX/x86_64_ash.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/x86_64_hexdump.config
Normal file
1166
BUSYBOX/x86_64_hexdump.config
Normal file
File diff suppressed because it is too large
Load Diff
1166
BUSYBOX/x86_64_xzcat.config
Normal file
1166
BUSYBOX/x86_64_xzcat.config
Normal file
File diff suppressed because it is too large
Load Diff
7
DMPATCH/Makefile
Normal file
7
DMPATCH/Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
obj-m += dm_patch.o
|
||||||
|
|
||||||
|
EXTRA_CFLAGS := -Wall
|
||||||
|
|
||||||
|
dm_patch-objs := dmpatch.o
|
||||||
|
|
||||||
187
DMPATCH/dmpatch.c
Normal file
187
DMPATCH/dmpatch.c
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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 padding[3];
|
||||||
|
}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_POS 3
|
||||||
|
#define CODE_MATCH(code, i) \
|
||||||
|
(code[i] == 0x40 && code[i + 1] == 0x80 && code[i + 2] == 0xce && code[i + 3] == 0x80)
|
||||||
|
#elif defined(CONFIG_X86_32)
|
||||||
|
#define PATCH_OP_POS 2
|
||||||
|
#define CODE_MATCH(code, i) \
|
||||||
|
(code[i] == 0x80 && code[i + 1] == 0xca && code[i + 2] == 0x80 && code[i + 3] == 0xe8)
|
||||||
|
#else
|
||||||
|
#error "unsupported arch"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
|
||||||
|
|
||||||
|
static int notrace dmpatch_replace_code(unsigned long addr, unsigned long size, int expect, const char *desc)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
unsigned long align;
|
||||||
|
unsigned char *patch[MAX_PATCH];
|
||||||
|
unsigned char *opCode = (unsigned char *)addr;
|
||||||
|
|
||||||
|
vdebug("patch for %s 0x%lx %d\n", desc, addr, (int)size);
|
||||||
|
|
||||||
|
for (i = 0; i < (int)size - 4; i++)
|
||||||
|
{
|
||||||
|
if (CODE_MATCH(opCode, i) && cnt < MAX_PATCH)
|
||||||
|
{
|
||||||
|
patch[cnt] = opCode + i + PATCH_OP_POS;
|
||||||
|
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 int notrace dmpatch_init(void)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
kprintf = (printk_pf)(g_ko_param.printk_addr);
|
||||||
|
|
||||||
|
vdebug("dmpatch_init start pagesize=%lu ...\n", g_ko_param.pgsize);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
r = dmpatch_replace_code(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device");
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
vdebug("patch dm_get_table_device success\n");
|
||||||
|
|
||||||
|
r = dmpatch_replace_code(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device");
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
vdebug("patch dm_put_table_device success\n");
|
||||||
|
|
||||||
|
vdebug("#####################################\n");
|
||||||
|
vdebug("######## dm patch success ###########\n");
|
||||||
|
vdebug("#####################################\n");
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notrace dmpatch_exit(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(dmpatch_init);
|
||||||
|
module_exit(dmpatch_exit);
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("dmpatch driver");
|
||||||
|
MODULE_AUTHOR("longpanda <admin@ventoy.net>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
36
DMPATCH/readme.txt
Normal file
36
DMPATCH/readme.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
1. install ubuntu 21.10
|
||||||
|
2. apt-get install build-essential flex libncurses-dev linux-headers-generic linux-source libssl-dev ...... and so on
|
||||||
|
3. cp /lib/modules/5.13.0-23-generic/build/Module.symvers ./
|
||||||
|
4. /boot/config-5.13.0-23-generic as .config make oldconfig
|
||||||
|
5. make menuconfig
|
||||||
|
1. close CONFIG_STACKPROTECTOR
|
||||||
|
2. close CONFIG_RETPOLINE
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
@@ -28,4 +28,43 @@ build for 32bit, static linked with dietlibc
|
|||||||
|
|
||||||
4. make
|
4. make
|
||||||
5. strip dmsetup/dmsetup
|
5. strip dmsetup/dmsetup
|
||||||
5. get dmsetup/dmsetup as the binary file
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
DMSETUP/dmsetup64
Normal file
BIN
DMSETUP/dmsetup64
Normal file
Binary file not shown.
BIN
DMSETUP/dmsetupaa64
Normal file
BIN
DMSETUP/dmsetupaa64
Normal file
Binary file not shown.
BIN
DMSETUP/dmsetupm64e
Normal file
BIN
DMSETUP/dmsetupm64e
Normal file
Binary file not shown.
@@ -3,7 +3,7 @@
|
|||||||
1. Compile Enviroment
|
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.
|
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.
|
Because Ventoy is based on many open source projects, so the environment is important. I suggest you test it on a virtual machine firstly.
|
||||||
|
|
||||||
1.1 Install CentOS 7.8
|
1.1 Install CentOS 7.8
|
||||||
I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install
|
I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \
|
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-* \
|
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 \
|
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
|
iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -22,35 +22,62 @@
|
|||||||
2. Download Source Code
|
2. Download Source Code
|
||||||
==========================================
|
==========================================
|
||||||
2.1 Download Ventoy source code from github and decompress it.
|
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).
|
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-part source code
|
2.2 Download third-part source code and tool
|
||||||
|
|
||||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz
|
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://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/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/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://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
|
||||||
|
http://ftp.loongnix.org/toolchain/gcc/release/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-part 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 envrioment
|
||||||
|
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
|
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.
|
I have made a 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.
|
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
|
cd /home/Ventoy-master/INSTALL
|
||||||
sh all_in_one.sh
|
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)
|
It should be noted that:
|
||||||
|
1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other part contains the binaries and are few modified, so will no be recompiled everytime.
|
||||||
|
You can rebuild these parts separately if you want.
|
||||||
|
|
||||||
|
2. 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.
|
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.
|
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.
|
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. Build every part of Ventoy
|
||||||
==========================================
|
==========================================
|
||||||
@@ -81,10 +108,10 @@
|
|||||||
cd /home/Ventoy-master/VtoyTool
|
cd /home/Ventoy-master/VtoyTool
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
4.8 == Build vtoyfat ==
|
4.8 == Build vtoycli ==
|
||||||
cd /home/Ventoy-master/vtoyfat/fat_io_lib
|
cd /home/Ventoy-master/vtoycli/fat_io_lib
|
||||||
sh buildlib.sh
|
sh buildlib.sh
|
||||||
cd /home/Ventoy-master/vtoyfat
|
cd /home/Ventoy-master/vtoycli
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
4.9 == Build exfat-util ==
|
4.9 == Build exfat-util ==
|
||||||
@@ -127,15 +154,37 @@
|
|||||||
cd /home/Ventoy-master/GenUUID
|
cd /home/Ventoy-master/GenUUID
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
4.15 == Build xzminidec ==
|
4.15 == Build xzminidec32 ==
|
||||||
cd /home/Ventoy-master/xz-embedded-20130513/userspace
|
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||||
make -f ventoy_makefile
|
make -f ventoy_makefile
|
||||||
strip --strip-all xzminidec
|
strip --strip-all xzminidec
|
||||||
|
|
||||||
4.16 == Build iso9660_x64.efi ==
|
4.16 == Build xzminidec64 ==
|
||||||
|
cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace
|
||||||
|
make -f ventoy_makefile64
|
||||||
|
strip --strip-all xzminidec
|
||||||
|
|
||||||
|
4.17 == Build iso9660_x64.efi ==
|
||||||
This efi driver is from https://github.com/pbatard/efifs
|
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)
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==========================================
|
==========================================
|
||||||
@@ -156,7 +205,7 @@
|
|||||||
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD
|
https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD
|
||||||
SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f
|
SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f
|
||||||
|
|
||||||
5.4 IMG/cpio/ventoy/busybox/tmpsh
|
5.4 IMG/cpio/ventoy/busybox/ash
|
||||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH
|
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH
|
||||||
SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97
|
SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97
|
||||||
|
|
||||||
@@ -164,11 +213,11 @@
|
|||||||
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ
|
https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ
|
||||||
SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291
|
SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291
|
||||||
|
|
||||||
5.6 INSTALL/tool/xzcat
|
5.6 INSTALL/tool/i386/xzcat
|
||||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT
|
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT
|
||||||
SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44
|
SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44
|
||||||
|
|
||||||
5.7 INSTALL/tool/hexdump
|
5.7 INSTALL/tool/i386/hexdump
|
||||||
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP
|
https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP
|
||||||
SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af
|
SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af
|
||||||
|
|
||||||
@@ -202,3 +251,10 @@
|
|||||||
https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH
|
https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH
|
||||||
SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
DOC/LoopExBuild.txt
Normal file
29
DOC/LoopExBuild.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9
DOC/prepare_env.sh
Normal file
9
DOC/prepare_env.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/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,17 +1,10 @@
|
|||||||
FROM centos:7
|
FROM centos:7
|
||||||
|
|
||||||
RUN yum -y install \
|
RUN yum -y -q install \
|
||||||
libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \
|
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 \
|
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-* \
|
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 \
|
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
|
iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso lz4 squashfs-tools
|
||||||
|
|
||||||
CMD cd /ventoy \
|
|
||||||
&& wget -P DOC/ https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz \
|
|
||||||
&& wget -P GRUB2/ https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz \
|
|
||||||
&& wget -O EDK2/edk2-edk2-stable201911.zip https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 \
|
|
||||||
&& wget -O ExFAT/exfat-1.3.0.zip https://codeload.github.com/relan/exfat/zip/v1.3.0 \
|
|
||||||
&& wget -O ExFAT/libfuse-fuse-2.9.9.zip https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 \
|
|
||||||
&& cd INSTALL && ls -la && sh all_in_one.sh
|
|
||||||
|
|
||||||
|
CMD cd /ventoy/INSTALL && ls -la && sh docker_ci_build.sh
|
||||||
|
|||||||
59
EDK2/build.sh
Normal file
59
EDK2/build.sh
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#!/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,32 +2,20 @@
|
|||||||
|
|
||||||
rm -rf edk2-edk2-stable201911
|
rm -rf edk2-edk2-stable201911
|
||||||
|
|
||||||
unzip edk2-edk2-stable201911.zip
|
unzip edk2-edk2-stable201911.zip > /dev/null
|
||||||
|
|
||||||
/bin/cp -a ./edk2_mod/edk2-edk2-stable201911 ./
|
/bin/cp -a ./edk2_mod/edk2-edk2-stable201911 ./
|
||||||
|
|
||||||
cd 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/
|
make -j 4 -C BaseTools/
|
||||||
|
|
||||||
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 ..
|
cd ..
|
||||||
else
|
|
||||||
echo -e '\n\n====================== FAILED ========================\n\n'
|
|
||||||
cd ..
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
echo '======== build EDK2 for i386-efi ==============='
|
||||||
|
sh ./build.sh ia32 || exit 1
|
||||||
|
|
||||||
|
echo '======== build EDK2 for arm64-efi ==============='
|
||||||
|
sh ./build.sh aa64 || exit 1
|
||||||
|
|
||||||
|
echo '======== build EDK2 for x86_64-efi ==============='
|
||||||
|
sh ./build.sh || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,472 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#************************************************************************************
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#include <Uefi.h>
|
||||||
|
int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size) { *buf = NULL; *size = 0; return 0; }
|
||||||
@@ -34,11 +34,17 @@
|
|||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
#include <Protocol/RamDisk.h>
|
#include <Protocol/RamDisk.h>
|
||||||
#include <Protocol/SimpleFileSystem.h>
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/DriverBinding.h>
|
||||||
#include <Ventoy.h>
|
#include <Ventoy.h>
|
||||||
|
|
||||||
BOOLEAN gDebugPrint = FALSE;
|
BOOLEAN gDebugPrint = FALSE;
|
||||||
|
BOOLEAN gBootFallBack = FALSE;
|
||||||
|
BOOLEAN gDotEfiBoot = FALSE;
|
||||||
|
BOOLEAN gLoadIsoEfi = FALSE;
|
||||||
|
BOOLEAN gIsoUdf = FALSE;
|
||||||
ventoy_ram_disk g_ramdisk_param;
|
ventoy_ram_disk g_ramdisk_param;
|
||||||
ventoy_chain_head *g_chain;
|
ventoy_chain_head *g_chain;
|
||||||
|
void *g_vtoy_img_location_buf;
|
||||||
ventoy_img_chunk *g_chunk;
|
ventoy_img_chunk *g_chunk;
|
||||||
UINT8 *g_os_param_reserved;
|
UINT8 *g_os_param_reserved;
|
||||||
UINT32 g_img_chunk_num;
|
UINT32 g_img_chunk_num;
|
||||||
@@ -48,26 +54,54 @@ ventoy_virt_chunk *g_virt_chunk;
|
|||||||
UINT32 g_virt_chunk_num;
|
UINT32 g_virt_chunk_num;
|
||||||
vtoy_block_data gBlockData;
|
vtoy_block_data gBlockData;
|
||||||
static grub_env_get_pf grub_env_get = NULL;
|
static grub_env_get_pf grub_env_get = NULL;
|
||||||
|
static grub_env_set_pf grub_env_set = NULL;
|
||||||
|
|
||||||
ventoy_grub_param_file_replace *g_file_replace_list = NULL;
|
ventoy_grub_param_file_replace *g_file_replace_list = NULL;
|
||||||
ventoy_efi_file_replace g_efi_file_replace;
|
ventoy_efi_file_replace g_efi_file_replace;
|
||||||
|
|
||||||
|
ventoy_grub_param_file_replace *g_img_replace_list = NULL;
|
||||||
|
ventoy_efi_file_replace g_img_file_replace;
|
||||||
|
|
||||||
|
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
|
||||||
|
CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH;
|
||||||
|
|
||||||
BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE;
|
BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE;
|
||||||
|
|
||||||
STATIC BOOLEAN g_hook_keyboard = FALSE;
|
STATIC BOOLEAN g_hook_keyboard = FALSE;
|
||||||
|
|
||||||
CHAR16 gFirstTryBootFile[256] = {0};
|
CHAR16 gFirstTryBootFile[256] = {0};
|
||||||
|
|
||||||
|
STATIC EFI_GET_VARIABLE g_org_get_variable = NULL;
|
||||||
|
STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL;
|
||||||
|
|
||||||
/* Boot filename */
|
/* Boot filename */
|
||||||
UINTN gBootFileStartIndex = 1;
|
UINTN gBootFileStartIndex = 1;
|
||||||
CONST CHAR16 *gEfiBootFileName[] =
|
CONST CHAR16 *gEfiBootFileName[] =
|
||||||
{
|
{
|
||||||
L"@",
|
L"@",
|
||||||
EFI_REMOVABLE_MEDIA_FILE_NAME,
|
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\\GRUBX64.EFI",
|
||||||
L"\\EFI\\BOOT\\BOOTx64.EFI",
|
L"\\EFI\\BOOT\\BOOTx64.EFI",
|
||||||
L"\\EFI\\BOOT\\bootx64.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
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...)
|
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...)
|
||||||
@@ -195,12 +229,14 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain)
|
|||||||
debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size);
|
debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size);
|
||||||
debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr);
|
debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr);
|
||||||
debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len);
|
debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len);
|
||||||
debug("os_param->vtoy_reserved=<%u %u %u %u %u>",
|
debug("os_param->vtoy_reserved=<%u %u %u %u %u %u %u>",
|
||||||
g_os_param_reserved[0],
|
g_os_param_reserved[0],
|
||||||
g_os_param_reserved[1],
|
g_os_param_reserved[1],
|
||||||
g_os_param_reserved[2],
|
g_os_param_reserved[2],
|
||||||
g_os_param_reserved[3],
|
g_os_param_reserved[3],
|
||||||
g_os_param_reserved[4]
|
g_os_param_reserved[4],
|
||||||
|
g_os_param_reserved[5],
|
||||||
|
g_os_param_reserved[6]
|
||||||
);
|
);
|
||||||
|
|
||||||
ventoy_debug_pause();
|
ventoy_debug_pause();
|
||||||
@@ -244,6 +280,7 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
address = (UINTN)buffer;
|
address = (UINTN)buffer;
|
||||||
|
g_vtoy_img_location_buf = buffer;
|
||||||
|
|
||||||
if (address % 4096)
|
if (address % 4096)
|
||||||
{
|
{
|
||||||
@@ -268,12 +305,25 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
||||||
location->image_sector_size = 2048;
|
location->image_sector_size = gSector512Mode ? 512 : 2048;
|
||||||
location->disk_sector_size = g_chain->disk_sector_size;
|
location->disk_sector_size = g_chain->disk_sector_size;
|
||||||
location->region_count = g_img_chunk_num;
|
location->region_count = g_img_chunk_num;
|
||||||
|
|
||||||
region = location->regions;
|
region = location->regions;
|
||||||
|
|
||||||
|
if (gSector512Mode)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
|
||||||
|
region->image_start_sector = chunk->img_start_sector * 4;
|
||||||
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i = 0; i < g_img_chunk_num; i++)
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
{
|
{
|
||||||
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
||||||
@@ -282,6 +332,7 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||||||
region++;
|
region++;
|
||||||
chunk++;
|
chunk++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -320,15 +371,27 @@ EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath
|
|||||||
return Handle;
|
return Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC ventoy_ram_disk g_backup_ramdisk_param;
|
||||||
|
STATIC ventoy_os_param g_backup_os_param_var;
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
|
EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
|
||||||
{
|
{
|
||||||
|
UINTN DataSize;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
EFI_GUID VarGuid = VENTOY_GUID;
|
EFI_GUID VarGuid = VENTOY_GUID;
|
||||||
|
|
||||||
|
DataSize = sizeof(g_backup_ramdisk_param);
|
||||||
|
Status = gRT->GetVariable(L"VentoyRamDisk", &VarGuid, NULL, &DataSize, &g_backup_ramdisk_param);
|
||||||
|
if (!EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("find previous ramdisk variable <%llu>", g_backup_ramdisk_param.DiskSize);
|
||||||
|
}
|
||||||
|
|
||||||
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
sizeof(g_ramdisk_param), &(g_ramdisk_param));
|
sizeof(g_ramdisk_param), &(g_ramdisk_param));
|
||||||
debug("set efi variable %r", Status);
|
debug("set ramdisk variable %r", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
@@ -338,20 +401,37 @@ EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID)
|
|||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
EFI_GUID VarGuid = VENTOY_GUID;
|
EFI_GUID VarGuid = VENTOY_GUID;
|
||||||
|
|
||||||
|
if (g_backup_ramdisk_param.DiskSize > 0 && g_backup_ramdisk_param.PhyAddr > 0)
|
||||||
|
{
|
||||||
|
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
sizeof(g_backup_ramdisk_param), &g_backup_ramdisk_param);
|
||||||
|
debug("resotre ramdisk variable %r", Status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
debug("delete efi variable %r", Status);
|
debug("delete ramdisk variable %r", Status);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_save_variable(VOID)
|
EFI_STATUS EFIAPI ventoy_save_variable(VOID)
|
||||||
{
|
{
|
||||||
|
UINTN DataSize;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
EFI_GUID VarGuid = VENTOY_GUID;
|
EFI_GUID VarGuid = VENTOY_GUID;
|
||||||
|
|
||||||
|
DataSize = sizeof(g_backup_os_param_var);
|
||||||
|
Status = gRT->GetVariable(L"VentoyOsParam", &VarGuid, NULL, &DataSize, &g_backup_os_param_var);
|
||||||
|
if (!EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("find previous efi variable <%a>", g_backup_os_param_var.vtoy_img_path);
|
||||||
|
}
|
||||||
|
|
||||||
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
sizeof(g_chain->os_param), &(g_chain->os_param));
|
sizeof(g_chain->os_param), &(g_chain->os_param));
|
||||||
@@ -365,14 +445,54 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID)
|
|||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
EFI_GUID VarGuid = VENTOY_GUID;
|
EFI_GUID VarGuid = VENTOY_GUID;
|
||||||
|
|
||||||
|
if (0 == CompareMem(&(g_backup_os_param_var.guid), &VarGuid, sizeof(EFI_GUID)))
|
||||||
|
{
|
||||||
|
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
sizeof(g_backup_os_param_var), &(g_backup_os_param_var));
|
||||||
|
debug("restore efi variable %r", Status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
debug("delete efi variable %r", Status);
|
debug("delete efi variable %r", Status);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (VENTOY_DEVICE_WARN != 0)
|
||||||
|
STATIC VOID ventoy_warn_invalid_device(VOID)
|
||||||
|
{
|
||||||
|
STATIC BOOLEAN flag = FALSE;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = TRUE;
|
||||||
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n");
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n");
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n\r\n\r\n");
|
||||||
|
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, L"This is NOT a standard Ventoy device and is NOT supported.\r\n\r\n");
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, L"You should follow the official instructions in https://www.ventoy.net\r\n");
|
||||||
|
|
||||||
|
gST->ConOut->OutputString(gST->ConOut, L"\r\n\r\nWill exit after 10 seconds ...... ");
|
||||||
|
|
||||||
|
sleep(10);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
STATIC VOID ventoy_warn_invalid_device(VOID)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI ventoy_load_image
|
STATIC EFI_STATUS EFIAPI ventoy_load_image
|
||||||
(
|
(
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
@@ -415,6 +535,7 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
|
|||||||
UINTN i = 0;
|
UINTN i = 0;
|
||||||
UINTN Count = 0;
|
UINTN Count = 0;
|
||||||
UINT64 DiskSize = 0;
|
UINT64 DiskSize = 0;
|
||||||
|
MBR_HEAD *pMBR = NULL;
|
||||||
UINT8 *pBuffer = NULL;
|
UINT8 *pBuffer = NULL;
|
||||||
EFI_HANDLE *Handles;
|
EFI_HANDLE *Handles;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
@@ -458,6 +579,18 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
|
|||||||
|
|
||||||
if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0)
|
if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0)
|
||||||
{
|
{
|
||||||
|
pMBR = (MBR_HEAD *)pBuffer;
|
||||||
|
if (g_os_param_reserved[6] == 0 && pMBR->PartTbl[0].FsFlag != 0xEE)
|
||||||
|
{
|
||||||
|
if (pMBR->PartTbl[0].StartSectorId != 2048 ||
|
||||||
|
pMBR->PartTbl[1].SectorCount != 65536 ||
|
||||||
|
pMBR->PartTbl[1].StartSectorId != pMBR->PartTbl[0].StartSectorId + pMBR->PartTbl[0].SectorCount)
|
||||||
|
{
|
||||||
|
debug("Failed to check disk part table");
|
||||||
|
ventoy_warn_invalid_device();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gBlockData.RawBlockIoHandle = Handles[i];
|
gBlockData.RawBlockIoHandle = Handles[i];
|
||||||
gBlockData.pRawBlockIo = pBlockIo;
|
gBlockData.pRawBlockIo = pBlockIo;
|
||||||
gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
|
gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
|
||||||
@@ -484,12 +617,211 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle)
|
||||||
|
{
|
||||||
|
UINTN i = 0;
|
||||||
|
UINTN Count = 0;
|
||||||
|
EFI_HANDLE Parent = NULL;
|
||||||
|
EFI_HANDLE *Handles = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
|
||||||
|
|
||||||
|
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
|
||||||
|
NULL, &Count, &Handles);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("ventoy_find_iso_disk_fs fs count:%u", Count);
|
||||||
|
|
||||||
|
for (i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
Parent = ventoy_get_parent_handle(pDevPath);
|
||||||
|
|
||||||
|
if (Parent == gBlockData.RawBlockIoHandle)
|
||||||
|
{
|
||||||
|
debug("Find ventoy disk fs");
|
||||||
|
gBlockData.DiskFsHandle = Handles[i];
|
||||||
|
gBlockData.pDiskFs = pFile;
|
||||||
|
gBlockData.pDiskFsDevPath = pDevPath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool(Handles);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle)
|
||||||
|
{
|
||||||
|
EFI_HANDLE Image = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
CHAR16 LogVar[4] = L"5";
|
||||||
|
|
||||||
|
if (gIsoUdf)
|
||||||
|
{
|
||||||
|
Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
|
||||||
|
gUdfEfiDriverPath,
|
||||||
|
sizeof(gUdfEfiDriverPath),
|
||||||
|
&Image);
|
||||||
|
debug("load iso UDF efi driver status:%r", Status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
|
||||||
|
gIso9660EfiDriverPath,
|
||||||
|
sizeof(gIso9660EfiDriverPath),
|
||||||
|
&Image);
|
||||||
|
debug("load iso 9660 efi driver status:%r", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gDebugPrint)
|
||||||
|
{
|
||||||
|
gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid,
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
sizeof(LogVar), LogVar);
|
||||||
|
}
|
||||||
|
|
||||||
|
gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid,
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
sizeof(LogVar), LogVar);
|
||||||
|
|
||||||
|
gBlockData.IsoDriverImage = Image;
|
||||||
|
Status = gBS->StartImage(Image, NULL, NULL);
|
||||||
|
debug("Start iso efi driver status:%r", Status);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS ventoy_proc_img_replace_name(ventoy_grub_param_file_replace *replace)
|
||||||
|
{
|
||||||
|
UINT32 i;
|
||||||
|
char tmp[256];
|
||||||
|
|
||||||
|
if (replace->magic != GRUB_IMG_REPLACE_MAGIC)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replace->old_file_name[0][0] == 0)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsciiStrCpyS(tmp, sizeof(tmp), replace->old_file_name[0]);
|
||||||
|
|
||||||
|
for (i = 0; i < 256 && tmp[i]; i++)
|
||||||
|
{
|
||||||
|
if (tmp[i] == '/')
|
||||||
|
{
|
||||||
|
tmp[i] = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AsciiStrCpyS(replace->old_file_name[0], 256, tmp);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_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 ventoy_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 ventoy_disable_secure_boot(IN EFI_HANDLE ImageHandle)
|
||||||
|
{
|
||||||
|
UINT8 Value = 0;
|
||||||
|
UINTN DataSize = 1;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
Status = gRT->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &DataSize, &Value);
|
||||||
|
if (!EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
if (DataSize == 1 && Value == 0)
|
||||||
|
{
|
||||||
|
debug("Current secure boot is off, no need to disable");
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("ventoy_disable_secure_boot");
|
||||||
|
|
||||||
|
/* 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 = ventoy_exit_boot_service_wrapper;
|
||||||
|
|
||||||
|
g_org_get_variable = gRT->GetVariable;
|
||||||
|
gRT->GetVariable = ventoy_get_variable_wrapper;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
||||||
{
|
{
|
||||||
UINT32 i = 0;
|
UINT32 i = 0;
|
||||||
UINT32 old_cnt = 0;
|
UINT32 old_cnt = 0;
|
||||||
UINTN size = 0;
|
UINTN size = 0;
|
||||||
UINT8 chksum = 0;
|
UINT8 chksum = 0;
|
||||||
|
const char *pEnv = NULL;
|
||||||
CHAR16 *pPos = NULL;
|
CHAR16 *pPos = NULL;
|
||||||
CHAR16 *pCmdLine = NULL;
|
CHAR16 *pCmdLine = NULL;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
@@ -513,6 +845,26 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
gDebugPrint = TRUE;
|
gDebugPrint = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StrStr(pCmdLine, L"fallback"))
|
||||||
|
{
|
||||||
|
gBootFallBack = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrStr(pCmdLine, L"dotefi"))
|
||||||
|
{
|
||||||
|
gDotEfiBoot = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrStr(pCmdLine, L"isoefi=on"))
|
||||||
|
{
|
||||||
|
gLoadIsoEfi = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrStr(pCmdLine, L"iso_udf"))
|
||||||
|
{
|
||||||
|
gIsoUdf = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
pPos = StrStr(pCmdLine, L"FirstTry=@");
|
pPos = StrStr(pCmdLine, L"FirstTry=@");
|
||||||
if (pPos)
|
if (pPos)
|
||||||
{
|
{
|
||||||
@@ -547,7 +899,19 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
|
pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
|
||||||
|
grub_env_set = pGrubParam->grub_env_set;
|
||||||
grub_env_get = pGrubParam->grub_env_get;
|
grub_env_get = pGrubParam->grub_env_get;
|
||||||
|
pEnv = grub_env_get("VTOY_CHKDEV_RESULT_STRING");
|
||||||
|
if (!pEnv)
|
||||||
|
{
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEnv[0] != '0' || pEnv[1] != 0)
|
||||||
|
{
|
||||||
|
ventoy_warn_invalid_device();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
g_file_replace_list = &pGrubParam->file_replace;
|
g_file_replace_list = &pGrubParam->file_replace;
|
||||||
old_cnt = g_file_replace_list->old_file_cnt;
|
old_cnt = g_file_replace_list->old_file_cnt;
|
||||||
@@ -561,6 +925,19 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
old_cnt > 3 ? g_file_replace_list->old_file_name[3] : ""
|
old_cnt > 3 ? g_file_replace_list->old_file_name[3] : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
g_img_replace_list = &pGrubParam->img_replace;
|
||||||
|
ventoy_proc_img_replace_name(g_img_replace_list);
|
||||||
|
old_cnt = g_img_replace_list->old_file_cnt;
|
||||||
|
debug("img replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
|
||||||
|
g_img_replace_list->magic,
|
||||||
|
g_img_replace_list->new_file_virtual_id,
|
||||||
|
old_cnt,
|
||||||
|
old_cnt > 0 ? g_img_replace_list->old_file_name[0] : "",
|
||||||
|
old_cnt > 1 ? g_img_replace_list->old_file_name[1] : "",
|
||||||
|
old_cnt > 2 ? g_img_replace_list->old_file_name[2] : "",
|
||||||
|
old_cnt > 3 ? g_img_replace_list->old_file_name[3] : ""
|
||||||
|
);
|
||||||
|
|
||||||
pPos = StrStr(pCmdLine, L"mem:");
|
pPos = StrStr(pCmdLine, L"mem:");
|
||||||
chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
|
chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
|
||||||
|
|
||||||
@@ -569,16 +946,27 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
|
|
||||||
debug("memory addr:%p size:%lu", chain, size);
|
debug("memory addr:%p size:%lu", chain, size);
|
||||||
|
|
||||||
g_chain = AllocatePool(size);
|
if (StrStr(pCmdLine, L"sector512"))
|
||||||
CopyMem(g_chain, chain, size);
|
{
|
||||||
|
gSector512Mode = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (StrStr(pCmdLine, L"memdisk"))
|
if (StrStr(pCmdLine, L"memdisk"))
|
||||||
{
|
{
|
||||||
g_iso_buf_size = size;
|
g_iso_data_buf = (UINT8 *)chain + sizeof(ventoy_chain_head);
|
||||||
|
g_iso_buf_size = size - sizeof(ventoy_chain_head);
|
||||||
|
debug("memdisk mode iso_buf_size:%u", g_iso_buf_size);
|
||||||
|
|
||||||
|
g_chain = chain;
|
||||||
|
g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved);
|
||||||
gMemdiskMode = TRUE;
|
gMemdiskMode = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
debug("This is normal mode");
|
||||||
|
g_chain = AllocatePool(size);
|
||||||
|
CopyMem(g_chain, chain, size);
|
||||||
|
|
||||||
g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
|
g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
|
||||||
g_img_chunk_num = g_chain->img_chunk_num;
|
g_img_chunk_num = g_chain->img_chunk_num;
|
||||||
g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
|
g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
|
||||||
@@ -599,6 +987,11 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
g_hook_keyboard = TRUE;
|
g_hook_keyboard = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_os_param_reserved[5] == 1 && g_os_param_reserved[2] == ventoy_chain_linux)
|
||||||
|
{
|
||||||
|
ventoy_disable_secure_boot(ImageHandle);
|
||||||
|
}
|
||||||
|
|
||||||
debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard);
|
debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(ventoy_os_param); i++)
|
for (i = 0; i < sizeof(ventoy_os_param); i++)
|
||||||
@@ -630,6 +1023,8 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ventoy_debug_pause();
|
||||||
|
|
||||||
FreePool(pCmdLine);
|
FreePool(pCmdLine);
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -639,6 +1034,11 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID)
|
|||||||
FreePool(g_sector_flag);
|
FreePool(g_sector_flag);
|
||||||
g_sector_flag_num = 0;
|
g_sector_flag_num = 0;
|
||||||
|
|
||||||
|
if (gLoadIsoEfi && gBlockData.IsoDriverImage)
|
||||||
|
{
|
||||||
|
gBS->UnloadImage(gBlockData.IsoDriverImage);
|
||||||
|
}
|
||||||
|
|
||||||
gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
|
gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
|
||||||
|
|
||||||
gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
|
gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
|
||||||
@@ -648,12 +1048,15 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID)
|
|||||||
|
|
||||||
ventoy_delete_variable();
|
ventoy_delete_variable();
|
||||||
|
|
||||||
if (g_chain->os_param.vtoy_img_location_addr)
|
if (g_vtoy_img_location_buf)
|
||||||
{
|
{
|
||||||
FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr);
|
FreePool(g_vtoy_img_location_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gMemdiskMode)
|
||||||
|
{
|
||||||
FreePool(g_chain);
|
FreePool(g_chain);
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -774,7 +1177,8 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
|
|||||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC)
|
if ((g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) ||
|
||||||
|
(g_img_replace_list && g_img_replace_list->magic == GRUB_IMG_REPLACE_MAGIC))
|
||||||
{
|
{
|
||||||
ventoy_wrapper_push_openvolume(pFile->OpenVolume);
|
ventoy_wrapper_push_openvolume(pFile->OpenVolume);
|
||||||
pFile->OpenVolume = ventoy_wrapper_open_volume;
|
pFile->OpenVolume = ventoy_wrapper_open_volume;
|
||||||
@@ -799,8 +1203,13 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
|
|||||||
|
|
||||||
if (Find == 0)
|
if (Find == 0)
|
||||||
{
|
{
|
||||||
|
if (gDotEfiBoot)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
debug("Fs not found, now wait and retry...");
|
debug("Fs not found, now wait and retry...");
|
||||||
sleep(2);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,24 +1247,57 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||||||
gST->ConOut->ClearScreen(gST->ConOut);
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
ventoy_clear_input();
|
ventoy_clear_input();
|
||||||
|
|
||||||
ventoy_parse_cmdline(ImageHandle);
|
Status = ventoy_parse_cmdline(ImageHandle);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_disable_ex_filesystem();
|
||||||
|
|
||||||
if (gMemdiskMode)
|
if (gMemdiskMode)
|
||||||
{
|
{
|
||||||
g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_chain;
|
g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_iso_data_buf;
|
||||||
g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size;
|
g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size;
|
||||||
|
|
||||||
ventoy_save_ramdisk_param();
|
ventoy_save_ramdisk_param();
|
||||||
|
|
||||||
|
if (gLoadIsoEfi)
|
||||||
|
{
|
||||||
|
ventoy_find_iso_disk(ImageHandle);
|
||||||
|
ventoy_find_iso_disk_fs(ImageHandle);
|
||||||
|
ventoy_load_isoefi_driver(ImageHandle);
|
||||||
|
}
|
||||||
|
|
||||||
ventoy_install_blockio(ImageHandle, g_iso_buf_size);
|
ventoy_install_blockio(ImageHandle, g_iso_buf_size);
|
||||||
|
ventoy_debug_pause();
|
||||||
|
|
||||||
Status = ventoy_boot(ImageHandle);
|
Status = ventoy_boot(ImageHandle);
|
||||||
|
|
||||||
ventoy_delete_ramdisk_param();
|
ventoy_delete_ramdisk_param();
|
||||||
|
|
||||||
|
if (gLoadIsoEfi && gBlockData.IsoDriverImage)
|
||||||
|
{
|
||||||
|
gBS->UnloadImage(gBlockData.IsoDriverImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
|
||||||
|
gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
|
||||||
|
&gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
|
||||||
|
&gEfiDevicePathProtocolGuid, gBlockData.Path,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ventoy_save_variable();
|
ventoy_save_variable();
|
||||||
ventoy_find_iso_disk(ImageHandle);
|
Status = ventoy_find_iso_disk(ImageHandle);
|
||||||
|
if (!EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
if (gLoadIsoEfi)
|
||||||
|
{
|
||||||
|
ventoy_find_iso_disk_fs(ImageHandle);
|
||||||
|
ventoy_load_isoefi_driver(ImageHandle);
|
||||||
|
}
|
||||||
|
|
||||||
ventoy_debug_pause();
|
ventoy_debug_pause();
|
||||||
|
|
||||||
@@ -864,20 +1306,31 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||||||
ventoy_debug_pause();
|
ventoy_debug_pause();
|
||||||
|
|
||||||
Status = ventoy_boot(ImageHandle);
|
Status = ventoy_boot(ImageHandle);
|
||||||
|
}
|
||||||
|
|
||||||
ventoy_clean_env();
|
ventoy_clean_env();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FALSE == gDotEfiBoot && FALSE == gBootFallBack)
|
||||||
|
{
|
||||||
if (EFI_NOT_FOUND == Status)
|
if (EFI_NOT_FOUND == Status)
|
||||||
{
|
{
|
||||||
gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
|
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");
|
gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
|
||||||
sleep(30);
|
sleep(30);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ventoy_clear_input();
|
ventoy_clear_input();
|
||||||
gST->ConOut->ClearScreen(gST->ConOut);
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
|
|
||||||
|
if (gDotEfiBoot && (EFI_NOT_FOUND == Status))
|
||||||
|
{
|
||||||
|
grub_env_set("vtoy_dotefi_retry", "YES");
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_enable_ex_filesystem();
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,21 +168,32 @@ typedef struct ventoy_virt_chunk
|
|||||||
#define VTOY_BLOCK_DEVICE_PATH_GUID \
|
#define VTOY_BLOCK_DEVICE_PATH_GUID \
|
||||||
{ 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }}
|
{ 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }}
|
||||||
|
|
||||||
#define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy"
|
|
||||||
|
|
||||||
#if defined (MDE_CPU_IA32)
|
#if defined (MDE_CPU_IA32)
|
||||||
#define VENTOY_UEFI_DESC L"IA32 UEFI"
|
#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)
|
#elif defined (MDE_CPU_X64)
|
||||||
#define VENTOY_UEFI_DESC L"X64 UEFI"
|
#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_EBC)
|
||||||
#elif defined (MDE_CPU_ARM)
|
#elif defined (MDE_CPU_ARM)
|
||||||
#define VENTOY_UEFI_DESC L"ARM UEFI"
|
#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)
|
#elif defined (MDE_CPU_AARCH64)
|
||||||
#define VENTOY_UEFI_DESC L"ARM64 UEFI"
|
#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
|
#else
|
||||||
#error Unknown Processor Type
|
#error Unknown Processor Type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VENTOY_DEVICE_WARN 1
|
||||||
|
#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
||||||
|
|
||||||
typedef struct ventoy_sector_flag
|
typedef struct ventoy_sector_flag
|
||||||
{
|
{
|
||||||
UINT8 flag; // 0:init 1:mem 2:remap
|
UINT8 flag; // 0:init 1:mem 2:remap
|
||||||
@@ -208,6 +219,7 @@ typedef struct vtoy_block_data
|
|||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
|
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
|
||||||
|
|
||||||
|
EFI_HANDLE IsoDriverImage;
|
||||||
}vtoy_block_data;
|
}vtoy_block_data;
|
||||||
|
|
||||||
|
|
||||||
@@ -224,12 +236,14 @@ if (gDebugPrint) \
|
|||||||
gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\
|
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 const char * (*grub_env_get_pf)(const char *name);
|
||||||
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
|
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
|
||||||
|
#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF
|
||||||
|
|
||||||
typedef struct ventoy_efi_file_replace
|
typedef struct ventoy_efi_file_replace
|
||||||
{
|
{
|
||||||
@@ -252,7 +266,9 @@ typedef struct ventoy_grub_param_file_replace
|
|||||||
typedef struct ventoy_grub_param
|
typedef struct ventoy_grub_param
|
||||||
{
|
{
|
||||||
grub_env_get_pf grub_env_get;
|
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 file_replace;
|
||||||
|
ventoy_grub_param_file_replace img_replace;
|
||||||
grub_env_printf_pf grub_env_printf;
|
grub_env_printf_pf grub_env_printf;
|
||||||
}ventoy_grub_param;
|
}ventoy_grub_param;
|
||||||
|
|
||||||
@@ -270,6 +286,32 @@ typedef struct ventoy_iso9660_override
|
|||||||
UINT32 size_be;
|
UINT32 size_be;
|
||||||
}ventoy_iso9660_override;
|
}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()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
@@ -303,6 +345,14 @@ typedef struct ventoy_system_wrapper
|
|||||||
EFI_LOCATE_DEVICE_PATH OriLocateDevicePath;
|
EFI_LOCATE_DEVICE_PATH OriLocateDevicePath;
|
||||||
} ventoy_system_wrapper;
|
} 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) \
|
#define ventoy_wrapper(bs, wrapper, func, newfunc) \
|
||||||
{\
|
{\
|
||||||
wrapper.Ori##func = bs->func;\
|
wrapper.Ori##func = bs->func;\
|
||||||
@@ -310,6 +360,22 @@ typedef struct ventoy_system_wrapper
|
|||||||
bs->func = wrapper.New##func;\
|
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 BOOLEAN gDebugPrint;
|
extern BOOLEAN gDebugPrint;
|
||||||
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
|
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
|
||||||
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
|
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
|
||||||
@@ -332,11 +398,15 @@ extern ventoy_virt_chunk *g_virt_chunk;
|
|||||||
extern UINT32 g_virt_chunk_num;
|
extern UINT32 g_virt_chunk_num;
|
||||||
extern vtoy_block_data gBlockData;
|
extern vtoy_block_data gBlockData;
|
||||||
extern ventoy_efi_file_replace g_efi_file_replace;
|
extern ventoy_efi_file_replace g_efi_file_replace;
|
||||||
|
extern ventoy_efi_file_replace g_img_file_replace;
|
||||||
extern ventoy_sector_flag *g_sector_flag;
|
extern ventoy_sector_flag *g_sector_flag;
|
||||||
extern UINT32 g_sector_flag_num;
|
extern UINT32 g_sector_flag_num;
|
||||||
extern BOOLEAN gMemdiskMode;
|
extern BOOLEAN gMemdiskMode;
|
||||||
|
extern BOOLEAN gSector512Mode;
|
||||||
extern UINTN g_iso_buf_size;
|
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_file_replace_list;
|
||||||
|
extern ventoy_grub_param_file_replace *g_img_replace_list;
|
||||||
extern BOOLEAN g_fixup_iso9660_secover_enable;
|
extern BOOLEAN g_fixup_iso9660_secover_enable;
|
||||||
extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex;
|
extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex;
|
||||||
extern BOOLEAN g_fix_windows_1st_cdrom_issue;
|
extern BOOLEAN g_fix_windows_1st_cdrom_issue;
|
||||||
@@ -353,6 +423,8 @@ EFI_STATUS ventoy_hook_keyboard_stop(VOID);
|
|||||||
BOOLEAN ventoy_is_cdrom_dp_exist(VOID);
|
BOOLEAN ventoy_is_cdrom_dp_exist(VOID);
|
||||||
EFI_STATUS ventoy_hook_1st_cdrom_start(VOID);
|
EFI_STATUS ventoy_hook_1st_cdrom_start(VOID);
|
||||||
EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID);
|
EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID);
|
||||||
|
EFI_STATUS ventoy_disable_ex_filesystem(VOID);
|
||||||
|
EFI_STATUS ventoy_enable_ex_filesystem(VOID);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
DebugLib
|
DebugLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
|
gEfiGlobalVariableGuid
|
||||||
gShellVariableGuid
|
gShellVariableGuid
|
||||||
gEfiVirtualCdGuid
|
gEfiVirtualCdGuid
|
||||||
gEfiFileInfoGuid
|
gEfiFileInfoGuid
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
#include <Protocol/RamDisk.h>
|
#include <Protocol/RamDisk.h>
|
||||||
#include <Protocol/SimpleFileSystem.h>
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/DriverBinding.h>
|
||||||
#include <Ventoy.h>
|
#include <Ventoy.h>
|
||||||
|
|
||||||
#define PROCOTOL_SLEEP_MSECONDS 0
|
#define PROCOTOL_SLEEP_MSECONDS 0
|
||||||
|
|||||||
@@ -34,10 +34,16 @@
|
|||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
#include <Protocol/RamDisk.h>
|
#include <Protocol/RamDisk.h>
|
||||||
#include <Protocol/SimpleFileSystem.h>
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/DriverBinding.h>
|
||||||
#include <Ventoy.h>
|
#include <Ventoy.h>
|
||||||
|
|
||||||
|
#define ASSIGN_REPLACE(This, replace) \
|
||||||
|
replace = (This->FlushEx == ventoy_wrapper_file_flush_ex) ? &g_efi_file_replace : &g_img_file_replace
|
||||||
|
|
||||||
|
UINT8 *g_iso_data_buf = NULL;
|
||||||
UINTN g_iso_buf_size = 0;
|
UINTN g_iso_buf_size = 0;
|
||||||
BOOLEAN gMemdiskMode = FALSE;
|
BOOLEAN gMemdiskMode = FALSE;
|
||||||
|
BOOLEAN gSector512Mode = FALSE;
|
||||||
|
|
||||||
ventoy_sector_flag *g_sector_flag = NULL;
|
ventoy_sector_flag *g_sector_flag = NULL;
|
||||||
UINT32 g_sector_flag_num = 0;
|
UINT32 g_sector_flag_num = 0;
|
||||||
@@ -67,6 +73,13 @@ STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL;
|
|||||||
|
|
||||||
STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL;
|
STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL;
|
||||||
|
|
||||||
|
STATIC UINT8 g_sector_buf[2048];
|
||||||
|
STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
|
||||||
|
STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL;
|
||||||
|
|
||||||
|
STATIC UINTN g_DriverBindWrapperCnt = 0;
|
||||||
|
STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList[MAX_DRIVER_BIND_WRAPPER];
|
||||||
|
|
||||||
BOOLEAN ventoy_is_cdrom_dp_exist(VOID)
|
BOOLEAN ventoy_is_cdrom_dp_exist(VOID)
|
||||||
{
|
{
|
||||||
UINTN i = 0;
|
UINTN i = 0;
|
||||||
@@ -142,7 +155,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
ventoy_override_chunk *pOverride = g_override_chunk;
|
ventoy_override_chunk *pOverride = g_override_chunk;
|
||||||
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
|
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
|
||||||
|
|
||||||
debug("read iso sector %lu count %u", Sector, Count);
|
debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign);
|
||||||
|
|
||||||
ReadStart = Sector * 2048;
|
ReadStart = Sector * 2048;
|
||||||
ReadEnd = (Sector + Count) * 2048;
|
ReadEnd = (Sector + Count) * 2048;
|
||||||
@@ -155,9 +168,17 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
{
|
{
|
||||||
MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
|
MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
|
||||||
}
|
}
|
||||||
else
|
else if (g_chain->disk_sector_size == 1024)
|
||||||
{
|
{
|
||||||
MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector;
|
MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else if (g_chain->disk_sector_size == 2048)
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else if (g_chain->disk_sector_size == 4096)
|
||||||
|
{
|
||||||
|
MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
secLeft = pchunk->img_end_sector + 1 - Sector;
|
secLeft = pchunk->img_end_sector + 1 - Sector;
|
||||||
@@ -167,7 +188,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
MapLba, secRead * 2048, pCurBuf);
|
MapLba, secRead * 2048, pCurBuf);
|
||||||
if (EFI_ERROR(Status))
|
if (EFI_ERROR(Status))
|
||||||
{
|
{
|
||||||
debug("Raw disk read block failed %r LBA:%lu Count:%u", Status, MapLba, secRead);
|
debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status, MapLba, secRead, pCurBuf);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +261,96 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector
|
||||||
|
(
|
||||||
|
IN UINT64 Sector,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
EFI_LBA MapLba = 0;
|
||||||
|
UINT32 i = 0;
|
||||||
|
UINTN secLeft = 0;
|
||||||
|
UINTN secRead = 0;
|
||||||
|
UINT64 ReadStart = 0;
|
||||||
|
UINT64 ReadEnd = 0;
|
||||||
|
UINT8 *pCurBuf = (UINT8 *)Buffer;
|
||||||
|
ventoy_img_chunk *pchunk = g_chunk;
|
||||||
|
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
|
||||||
|
|
||||||
|
debug("write iso sector %lu count %u", Sector, Count);
|
||||||
|
|
||||||
|
ReadStart = Sector * 2048;
|
||||||
|
ReadEnd = (Sector + Count) * 2048;
|
||||||
|
|
||||||
|
for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++)
|
||||||
|
{
|
||||||
|
if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector)
|
||||||
|
{
|
||||||
|
if (g_chain->disk_sector_size == 512)
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else if (g_chain->disk_sector_size == 1024)
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else if (g_chain->disk_sector_size == 2048)
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else if (g_chain->disk_sector_size == 4096)
|
||||||
|
{
|
||||||
|
MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
secLeft = pchunk->img_end_sector + 1 - Sector;
|
||||||
|
secRead = (Count < secLeft) ? Count : secLeft;
|
||||||
|
|
||||||
|
Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
|
||||||
|
MapLba, secRead * 2048, pCurBuf);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Count -= secRead;
|
||||||
|
Sector += secRead;
|
||||||
|
pCurBuf += secRead * 2048;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_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)Lba;
|
||||||
|
(VOID)BufferSize;
|
||||||
|
(VOID)Buffer;
|
||||||
|
|
||||||
|
if (!gSector512Mode)
|
||||||
|
{
|
||||||
|
return EFI_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
|
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
|
||||||
(
|
(
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
@@ -254,7 +365,7 @@ EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
|
|||||||
(VOID)This;
|
(VOID)This;
|
||||||
(VOID)MediaId;
|
(VOID)MediaId;
|
||||||
|
|
||||||
CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize);
|
CopyMem(Buffer, g_iso_data_buf + (Lba * 2048), BufferSize);
|
||||||
|
|
||||||
if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done)
|
if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done)
|
||||||
{
|
{
|
||||||
@@ -320,7 +431,7 @@ end:
|
|||||||
return Lba;
|
return Lba;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_read
|
EFI_STATUS EFIAPI ventoy_block_io_read_real
|
||||||
(
|
(
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
IN UINT32 MediaId,
|
IN UINT32 MediaId,
|
||||||
@@ -333,6 +444,8 @@ EFI_STATUS EFIAPI ventoy_block_io_read
|
|||||||
UINT32 j = 0;
|
UINT32 j = 0;
|
||||||
UINT32 lbacount = 0;
|
UINT32 lbacount = 0;
|
||||||
UINT32 secNum = 0;
|
UINT32 secNum = 0;
|
||||||
|
UINT32 TmpNum = 0;
|
||||||
|
UINT64 VirtSec = 0;
|
||||||
UINT64 offset = 0;
|
UINT64 offset = 0;
|
||||||
EFI_LBA curlba = 0;
|
EFI_LBA curlba = 0;
|
||||||
EFI_LBA lastlba = 0;
|
EFI_LBA lastlba = 0;
|
||||||
@@ -340,7 +453,7 @@ EFI_STATUS EFIAPI ventoy_block_io_read
|
|||||||
ventoy_sector_flag *cur_flag;
|
ventoy_sector_flag *cur_flag;
|
||||||
ventoy_virt_chunk *node;
|
ventoy_virt_chunk *node;
|
||||||
|
|
||||||
//debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
|
debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer);
|
||||||
|
|
||||||
secNum = BufferSize / 2048;
|
secNum = BufferSize / 2048;
|
||||||
|
|
||||||
@@ -356,6 +469,28 @@ EFI_STATUS EFIAPI ventoy_block_io_read
|
|||||||
{
|
{
|
||||||
return ventoy_read_iso_sector(Lba, secNum, Buffer);
|
return ventoy_read_iso_sector(Lba, secNum, Buffer);
|
||||||
}
|
}
|
||||||
|
else if (offset < g_chain->real_img_size_in_bytes)
|
||||||
|
{
|
||||||
|
TmpNum = (g_chain->real_img_size_in_bytes - offset) / 2048;
|
||||||
|
ventoy_read_iso_sector(Lba, TmpNum, Buffer);
|
||||||
|
|
||||||
|
Lba += TmpNum;
|
||||||
|
secNum -= TmpNum;
|
||||||
|
Buffer = (UINT8 *)Buffer + (g_chain->real_img_size_in_bytes - offset);
|
||||||
|
offset = Lba * 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtSec = g_chain->virt_img_size_in_bytes / 2048;
|
||||||
|
if (Lba >= VirtSec)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (Lba + secNum > VirtSec)
|
||||||
|
{
|
||||||
|
secNum = VirtSec - Lba;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer);
|
||||||
|
|
||||||
if (secNum > g_sector_flag_num)
|
if (secNum > g_sector_flag_num)
|
||||||
{
|
{
|
||||||
@@ -424,6 +559,42 @@ EFI_STATUS EFIAPI ventoy_block_io_read
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_read
|
||||||
|
(
|
||||||
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 IoAlign = 0;
|
||||||
|
VOID *NewBuf = NULL;
|
||||||
|
EFI_STATUS Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
|
if (gBlockData.pRawBlockIo && gBlockData.pRawBlockIo->Media)
|
||||||
|
{
|
||||||
|
IoAlign = gBlockData.pRawBlockIo->Media->IoAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((IoAlign == 0) || (((UINTN) Buffer & (IoAlign - 1)) == 0))
|
||||||
|
{
|
||||||
|
Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, Buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewBuf = AllocatePages(EFI_SIZE_TO_PAGES(BufferSize + IoAlign));
|
||||||
|
if (NewBuf)
|
||||||
|
{
|
||||||
|
Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, NewBuf);
|
||||||
|
CopyMem(Buffer, NewBuf, BufferSize);
|
||||||
|
FreePages(NewBuf, EFI_SIZE_TO_PAGES(BufferSize + IoAlign));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_write
|
EFI_STATUS EFIAPI ventoy_block_io_write
|
||||||
(
|
(
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
@@ -433,40 +604,97 @@ EFI_STATUS EFIAPI ventoy_block_io_write
|
|||||||
IN VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT32 secNum = 0;
|
||||||
|
UINT64 offset = 0;
|
||||||
|
|
||||||
(VOID)This;
|
(VOID)This;
|
||||||
(VOID)MediaId;
|
(VOID)MediaId;
|
||||||
(VOID)Lba;
|
|
||||||
(VOID)BufferSize;
|
if (!gSector512Mode)
|
||||||
(VOID)Buffer;
|
{
|
||||||
return EFI_WRITE_PROTECTED;
|
return EFI_WRITE_PROTECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secNum = BufferSize / 2048;
|
||||||
|
offset = Lba * 2048;
|
||||||
|
|
||||||
|
return ventoy_write_iso_sector(Lba, secNum, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
||||||
{
|
{
|
||||||
(VOID)This;
|
(VOID)This;
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC UINTN ventoy_get_current_device_path_id(VOID)
|
||||||
|
{
|
||||||
|
UINTN i = 0;
|
||||||
|
UINTN Count = 0;
|
||||||
|
UINTN MaxId = 0;
|
||||||
|
UINTN CurId = 0;
|
||||||
|
BOOLEAN Find = FALSE;
|
||||||
|
EFI_HANDLE *Handles = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
|
||||||
|
VENDOR_DEVICE_PATH *venPath = NULL;
|
||||||
|
|
||||||
|
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid,
|
||||||
|
NULL, &Count, &Handles);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DevicePath->Type == HARDWARE_DEVICE_PATH && DevicePath->SubType == HW_VENDOR_DP)
|
||||||
|
{
|
||||||
|
venPath = (VENDOR_DEVICE_PATH *)DevicePath;
|
||||||
|
if (CompareGuid(&venPath->Guid, &gVtoyBlockDevicePathGuid))
|
||||||
|
{
|
||||||
|
CurId = StrDecimalToUintn((CHAR16 *)(venPath + 1) + StrLen(L"ventoy_"));
|
||||||
|
MaxId = MAX(MaxId, CurId);
|
||||||
|
Find = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool(Handles);
|
||||||
|
|
||||||
|
return Find ? (MaxId + 1) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
|
EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
|
||||||
{
|
{
|
||||||
|
UINTN CurVtoyDpId = 0;
|
||||||
UINTN NameLen = 0;
|
UINTN NameLen = 0;
|
||||||
UINT8 TmpBuf[128] = {0};
|
UINT8 TmpBuf[128] = {0};
|
||||||
VENDOR_DEVICE_PATH *venPath = NULL;
|
VENDOR_DEVICE_PATH *venPath = NULL;
|
||||||
|
CHAR16 VtoyDpName[32];
|
||||||
|
|
||||||
|
CurVtoyDpId = ventoy_get_current_device_path_id();
|
||||||
|
UnicodeSPrintAsciiFormat(VtoyDpName, sizeof(VtoyDpName), "ventoy_%03lu", CurVtoyDpId);
|
||||||
|
|
||||||
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
|
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
|
||||||
NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
|
NameLen = StrSize(VtoyDpName);
|
||||||
venPath->Header.Type = HARDWARE_DEVICE_PATH;
|
venPath->Header.Type = HARDWARE_DEVICE_PATH;
|
||||||
venPath->Header.SubType = HW_VENDOR_DP;
|
venPath->Header.SubType = HW_VENDOR_DP;
|
||||||
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||||
venPath->Header.Length[1] = 0;
|
venPath->Header.Length[1] = 0;
|
||||||
CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
|
CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
|
||||||
CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
|
CopyMem(venPath + 1, VtoyDpName, NameLen);
|
||||||
|
|
||||||
gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
|
gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
|
||||||
gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||||
|
|
||||||
debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
|
debug("gBlockData.Path=<%lu><%s>\n", CurVtoyDpId, ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -499,11 +727,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName);
|
VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName);
|
||||||
if (EFI_ERROR(Status) || NULL == DriverName)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrStr(DriverName, DrvName))
|
if (StrStr(DriverName, DrvName))
|
||||||
{
|
{
|
||||||
@@ -541,11 +765,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName);
|
VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName);
|
||||||
if (EFI_ERROR(Status))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrStr(DriverName, DrvName))
|
if (StrStr(DriverName, DrvName))
|
||||||
{
|
{
|
||||||
@@ -570,6 +790,343 @@ end:
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
CHAR16 UpperDrvName[256];
|
||||||
|
|
||||||
|
StrCpyS(UpperDrvName, 256, DrvName);
|
||||||
|
|
||||||
|
for (i = 0; i < 256 && UpperDrvName[i]; i++)
|
||||||
|
{
|
||||||
|
if (UpperDrvName[i] >= 'a' && UpperDrvName[i] <= 'z')
|
||||||
|
{
|
||||||
|
UpperDrvName[i] = 'A' + (UpperDrvName[i] - 'a');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* suppress some file system drivers
|
||||||
|
* 1. rEFInd File System Driver
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM"))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID ventoy_add_filesystem_wrapper
|
||||||
|
(
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol,
|
||||||
|
IN CONST CHAR16 *DriverName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN j;
|
||||||
|
|
||||||
|
if (g_DriverBindWrapperCnt >= MAX_DRIVER_BIND_WRAPPER)
|
||||||
|
{
|
||||||
|
debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ventoy_filesystem_need_wrapper(DriverName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < g_DriverBindWrapperCnt; j++)
|
||||||
|
{
|
||||||
|
if (g_DriverBindWrapperList[j].DriverBinding == DriverBindProtocol)
|
||||||
|
{
|
||||||
|
debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName, DriverBindProtocol, j, g_DriverBindWrapperCnt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j >= g_DriverBindWrapperCnt)
|
||||||
|
{
|
||||||
|
g_DriverBindWrapperList[g_DriverBindWrapperCnt].DriverBinding = DriverBindProtocol;
|
||||||
|
g_DriverBindWrapperList[g_DriverBindWrapperCnt].pfOldSupport = DriverBindProtocol->Supported;
|
||||||
|
g_DriverBindWrapperCnt++;
|
||||||
|
debug("Add driverbinding <%s> %p %lu", DriverName, DriverBindProtocol, g_DriverBindWrapperCnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol = NULL;
|
||||||
|
|
||||||
|
debug("ventoy_find_filesystem_driverbind...");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName);
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("### 2 No DriverBind <%s> <%r>", DriverName, Status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_add_filesystem_wrapper(DriverBindProtocol, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName);
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("### 1 No DriverBind <%s> <%r>", DriverName, Status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool(Handles);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support
|
||||||
|
(
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
|
||||||
|
EFI_DRIVER_BINDING_SUPPORTED pfOldSupport = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < g_DriverBindWrapperCnt; i++)
|
||||||
|
{
|
||||||
|
if (g_DriverBindWrapperList[i].DriverBinding == This)
|
||||||
|
{
|
||||||
|
pfOldSupport = g_DriverBindWrapperList[i].pfOldSupport;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("ventoy_wrapper_driver_bind_support %lu %p", i, pfOldSupport);
|
||||||
|
|
||||||
|
if (!pfOldSupport)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == CompareMem(gBlockData.Path, DevicePath, gBlockData.DevicePathCompareLen))
|
||||||
|
{
|
||||||
|
debug("return EFI_UNSUPPORTED for ventoy");
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return pfOldSupport(This, ControllerHandle, RemainingDevicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS ventoy_disable_ex_filesystem(VOID)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
|
||||||
|
ventoy_find_filesystem_driverbind();
|
||||||
|
|
||||||
|
for (i = 0; i < g_DriverBindWrapperCnt; i++)
|
||||||
|
{
|
||||||
|
g_DriverBindWrapperList[i].DriverBinding->Supported = ventoy_wrapper_driver_bind_support;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt);
|
||||||
|
ventoy_debug_pause();
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS ventoy_enable_ex_filesystem(VOID)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
|
||||||
|
for (i = 0; i < g_DriverBindWrapperCnt; i++)
|
||||||
|
{
|
||||||
|
g_DriverBindWrapperList[i].DriverBinding->Supported = g_DriverBindWrapperList[i].pfOldSupport;
|
||||||
|
}
|
||||||
|
g_DriverBindWrapperCnt = 0;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_read_512
|
||||||
|
(
|
||||||
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_LBA Mod;
|
||||||
|
UINTN ReadSize;
|
||||||
|
UINT8 *CurBuf = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer);
|
||||||
|
|
||||||
|
CurBuf = (UINT8 *)Buffer;
|
||||||
|
|
||||||
|
Mod = Lba % 4;
|
||||||
|
if (Mod > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
if (BufferSize <= (4 - Mod) * 512)
|
||||||
|
{
|
||||||
|
CopyMem(CurBuf, g_sector_buf + Mod * 512, BufferSize);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadSize = (4 - Mod) * 512;
|
||||||
|
CopyMem(CurBuf, g_sector_buf + Mod * 512, ReadSize);
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
Lba += (4 - Mod);
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize >= 2048)
|
||||||
|
{
|
||||||
|
ReadSize = BufferSize / 2048 * 2048;
|
||||||
|
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, ReadSize, CurBuf);
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
|
||||||
|
Lba += ReadSize / 512;
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
CopyMem(CurBuf, g_sector_buf, BufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_write_512
|
||||||
|
(
|
||||||
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_LBA Mod;
|
||||||
|
UINTN ReadSize;
|
||||||
|
UINT8 *CurBuf = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512);
|
||||||
|
|
||||||
|
CurBuf = (UINT8 *)Buffer;
|
||||||
|
|
||||||
|
Mod = Lba % 4;
|
||||||
|
if (Mod > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
if (BufferSize <= (4 - Mod) * 512)
|
||||||
|
{
|
||||||
|
CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize);
|
||||||
|
return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadSize = (4 - Mod) * 512;
|
||||||
|
CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize);
|
||||||
|
g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
Lba += (4 - Mod);
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize >= 2048)
|
||||||
|
{
|
||||||
|
ReadSize = BufferSize / 2048 * 2048;
|
||||||
|
|
||||||
|
Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf);
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
|
||||||
|
Lba += ReadSize / 512;
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
CopyMem(g_sector_buf, CurBuf, BufferSize);
|
||||||
|
g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
|
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
@@ -580,17 +1137,39 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im
|
|||||||
debug("install block io protocol %p", ImageHandle);
|
debug("install block io protocol %p", ImageHandle);
|
||||||
ventoy_debug_pause();
|
ventoy_debug_pause();
|
||||||
|
|
||||||
|
if (gSector512Mode)
|
||||||
|
{
|
||||||
|
gBlockData.Media.BlockSize = 512;
|
||||||
|
gBlockData.Media.LastBlock = ImgSize / 512 - 1;
|
||||||
|
gBlockData.Media.ReadOnly = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gBlockData.Media.BlockSize = 2048;
|
gBlockData.Media.BlockSize = 2048;
|
||||||
gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
|
gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
|
||||||
gBlockData.Media.ReadOnly = TRUE;
|
gBlockData.Media.ReadOnly = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gBlockData.Media.MediaPresent = 1;
|
gBlockData.Media.MediaPresent = 1;
|
||||||
gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
|
gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
|
||||||
|
|
||||||
pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
|
pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
|
||||||
pBlockIo->Media = &(gBlockData.Media);
|
pBlockIo->Media = &(gBlockData.Media);
|
||||||
pBlockIo->Reset = ventoy_block_io_reset;
|
pBlockIo->Reset = ventoy_block_io_reset;
|
||||||
|
|
||||||
|
if (gSector512Mode)
|
||||||
|
{
|
||||||
|
g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
||||||
|
g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write;
|
||||||
|
pBlockIo->ReadBlocks = ventoy_block_io_read_512;
|
||||||
|
pBlockIo->WriteBlocks = ventoy_block_io_write_512;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
||||||
pBlockIo->WriteBlocks = ventoy_block_io_write;
|
pBlockIo->WriteBlocks = ventoy_block_io_write;
|
||||||
|
}
|
||||||
|
|
||||||
pBlockIo->FlushBlocks = ventoy_block_io_flush;
|
pBlockIo->FlushBlocks = ventoy_block_io_flush;
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
|
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
|
||||||
@@ -669,6 +1248,15 @@ ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ex version */
|
||||||
|
STATIC EFI_STATUS EFIAPI
|
||||||
|
ventoy_wrapper_file_flush_ex_img(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
||||||
|
{
|
||||||
|
(VOID)This;
|
||||||
|
(VOID)Token;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI
|
STATIC EFI_STATUS EFIAPI
|
||||||
ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
|
ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
|
||||||
@@ -694,22 +1282,33 @@ ventoy_wrapper_file_close(EFI_FILE_HANDLE This)
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI
|
STATIC EFI_STATUS EFIAPI
|
||||||
ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
|
ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
|
||||||
{
|
{
|
||||||
(VOID)This;
|
ventoy_efi_file_replace *replace = NULL;
|
||||||
|
|
||||||
|
ASSIGN_REPLACE(This, replace);
|
||||||
|
|
||||||
|
if (Position <= replace->FileSizeBytes)
|
||||||
|
{
|
||||||
|
replace->CurPos = Position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
replace->CurPos = replace->FileSizeBytes;
|
||||||
|
}
|
||||||
|
|
||||||
g_efi_file_replace.CurPos = Position;
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI
|
STATIC EFI_STATUS EFIAPI
|
||||||
ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
|
ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
|
||||||
{
|
{
|
||||||
(VOID)This;
|
ventoy_efi_file_replace *replace = NULL;
|
||||||
|
|
||||||
*Position = g_efi_file_replace.CurPos;
|
ASSIGN_REPLACE(This, replace);
|
||||||
|
|
||||||
|
*Position = replace->CurPos;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -719,6 +1318,9 @@ STATIC EFI_STATUS EFIAPI
|
|||||||
ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
|
ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
|
||||||
{
|
{
|
||||||
EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
|
EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
|
||||||
|
ventoy_efi_file_replace *replace = NULL;
|
||||||
|
|
||||||
|
ASSIGN_REPLACE(This, replace);
|
||||||
|
|
||||||
debug("ventoy_wrapper_file_get_info ... %u", *Len);
|
debug("ventoy_wrapper_file_get_info ... %u", *Len);
|
||||||
|
|
||||||
@@ -736,8 +1338,8 @@ ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, V
|
|||||||
ZeroMem(Data, sizeof(EFI_FILE_INFO));
|
ZeroMem(Data, sizeof(EFI_FILE_INFO));
|
||||||
|
|
||||||
Info->Size = sizeof(EFI_FILE_INFO);
|
Info->Size = sizeof(EFI_FILE_INFO);
|
||||||
Info->FileSize = g_efi_file_replace.FileSizeBytes;
|
Info->FileSize = replace->FileSizeBytes;
|
||||||
Info->PhysicalSize = g_efi_file_replace.FileSizeBytes;
|
Info->PhysicalSize = replace->FileSizeBytes;
|
||||||
Info->Attribute = EFI_FILE_READ_ONLY;
|
Info->Attribute = EFI_FILE_READ_ONLY;
|
||||||
//Info->FileName = EFI_FILE_READ_ONLY;
|
//Info->FileName = EFI_FILE_READ_ONLY;
|
||||||
|
|
||||||
@@ -751,23 +1353,24 @@ ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
|
|||||||
{
|
{
|
||||||
EFI_LBA Lba;
|
EFI_LBA Lba;
|
||||||
UINTN ReadLen = *Len;
|
UINTN ReadLen = *Len;
|
||||||
|
ventoy_efi_file_replace *replace = NULL;
|
||||||
|
|
||||||
(VOID)This;
|
ASSIGN_REPLACE(This, replace);
|
||||||
|
|
||||||
debug("ventoy_wrapper_file_read ... %u", *Len);
|
debug("ventoy_wrapper_file_read ... %u", *Len);
|
||||||
|
|
||||||
if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes)
|
if (replace->CurPos + ReadLen > replace->FileSizeBytes)
|
||||||
{
|
{
|
||||||
ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos;
|
ReadLen = replace->FileSizeBytes - replace->CurPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart;
|
Lba = replace->CurPos / 2048 + replace->BlockIoSectorStart;
|
||||||
|
|
||||||
ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data);
|
ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data);
|
||||||
|
|
||||||
*Len = ReadLen;
|
*Len = ReadLen;
|
||||||
|
|
||||||
g_efi_file_replace.CurPos += ReadLen;
|
replace->CurPos += ReadLen;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -778,7 +1381,7 @@ ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN
|
|||||||
return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
|
return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File)
|
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, BOOLEAN Img)
|
||||||
{
|
{
|
||||||
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
|
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
|
||||||
File->Open = ventoy_wrapper_fs_open;
|
File->Open = ventoy_wrapper_fs_open;
|
||||||
@@ -794,7 +1397,7 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File)
|
|||||||
File->OpenEx = ventoy_wrapper_file_open_ex;
|
File->OpenEx = ventoy_wrapper_file_open_ex;
|
||||||
File->ReadEx = ventoy_wrapper_file_read_ex;
|
File->ReadEx = ventoy_wrapper_file_read_ex;
|
||||||
File->WriteEx = ventoy_wrapper_file_write_ex;
|
File->WriteEx = ventoy_wrapper_file_write_ex;
|
||||||
File->FlushEx = ventoy_wrapper_file_flush_ex;
|
File->FlushEx = Img ? ventoy_wrapper_file_flush_ex_img : ventoy_wrapper_file_flush_ex;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -813,14 +1416,28 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
|||||||
UINT64 Sectors = 0;
|
UINT64 Sectors = 0;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
CHAR8 TmpName[256];
|
CHAR8 TmpName[256];
|
||||||
|
CHAR8 OldName[256];
|
||||||
ventoy_virt_chunk *virt = NULL;
|
ventoy_virt_chunk *virt = NULL;
|
||||||
|
|
||||||
|
debug("## ventoy_wrapper_file_open <%s> ", Name);
|
||||||
|
|
||||||
|
if ((Mode & EFI_FILE_MODE_WRITE) > 0 && StrCmp(Name, L"\\loader\\random-seed") == 0)
|
||||||
|
{
|
||||||
|
if (gDebugPrint)
|
||||||
|
{
|
||||||
|
debug("## ventoy_wrapper_file_open return NOT_FOUND for random-seed %lx", Mode);
|
||||||
|
sleep(3);
|
||||||
|
}
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
Status = g_original_fopen(This, New, Name, Mode, Attributes);
|
Status = g_original_fopen(This, New, Name, Mode, Attributes);
|
||||||
if (EFI_ERROR(Status))
|
if (EFI_ERROR(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC &&
|
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC &&
|
||||||
g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
|
g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
|
||||||
{
|
{
|
||||||
@@ -831,7 +1448,7 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
|||||||
{
|
{
|
||||||
g_original_fclose(*New);
|
g_original_fclose(*New);
|
||||||
*New = &g_efi_file_replace.WrapperHandle;
|
*New = &g_efi_file_replace.WrapperHandle;
|
||||||
ventoy_wrapper_file_procotol(*New);
|
ventoy_wrapper_file_procotol(*New, FALSE);
|
||||||
|
|
||||||
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
|
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
|
||||||
|
|
||||||
@@ -850,6 +1467,54 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StrCmp(Name, L"\\EFI\\BOOT") == 0)
|
||||||
|
{
|
||||||
|
(*New)->Open = ventoy_wrapper_file_open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (g_img_replace_list && g_img_replace_list->magic == GRUB_IMG_REPLACE_MAGIC &&
|
||||||
|
g_img_replace_list->new_file_virtual_id < g_virt_chunk_num)
|
||||||
|
{
|
||||||
|
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
|
||||||
|
for (j = 0; j < g_img_replace_list->old_file_cnt; j++)
|
||||||
|
{
|
||||||
|
AsciiStrCpyS(OldName, sizeof(OldName), g_img_replace_list[i].old_file_name[j]);
|
||||||
|
if ((0 == AsciiStrCmp(OldName, TmpName)) ||
|
||||||
|
(AsciiStrnCmp(OldName, "\\loader\\entries\\", 16) == 0 &&
|
||||||
|
AsciiStrCmp(OldName + 16, TmpName) == 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_original_fclose(*New);
|
||||||
|
*New = &g_img_file_replace.WrapperHandle;
|
||||||
|
ventoy_wrapper_file_procotol(*New, TRUE);
|
||||||
|
|
||||||
|
virt = g_virt_chunk + g_img_replace_list->new_file_virtual_id;
|
||||||
|
|
||||||
|
Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
|
||||||
|
|
||||||
|
g_img_file_replace.BlockIoSectorStart = virt->mem_sector_start;
|
||||||
|
g_img_file_replace.FileSizeBytes = Sectors * 2048;
|
||||||
|
|
||||||
|
if (gDebugPrint)
|
||||||
|
{
|
||||||
|
debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
|
||||||
|
g_img_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048);
|
||||||
|
sleep(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrCmp(Name, L"\\loader\\entries") == 0)
|
||||||
|
{
|
||||||
|
(*New)->Open = ventoy_wrapper_file_open;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -44,8 +44,39 @@ STATIC grub_env_printf_pf g_env_printf = NULL;
|
|||||||
STATIC VtoyUtilFeature gFeatureList[] =
|
STATIC VtoyUtilFeature gFeatureList[] =
|
||||||
{
|
{
|
||||||
{ L"fix_windows_mmap", FixWindowsMemhole },
|
{ 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, ...)
|
VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...)
|
||||||
{
|
{
|
||||||
VA_LIST Marker;
|
VA_LIST Marker;
|
||||||
@@ -79,6 +110,14 @@ STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0);
|
SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0);
|
||||||
CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize);
|
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"))
|
if (StrStr(pCmdLine, L"debug"))
|
||||||
{
|
{
|
||||||
gVtoyDebugPrint = TRUE;
|
gVtoyDebugPrint = TRUE;
|
||||||
@@ -102,6 +141,7 @@ STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
gCurFeature = pPos + StrLen(L"feature=");
|
gCurFeature = pPos + StrLen(L"feature=");
|
||||||
|
|
||||||
gCmdLine = pCmdLine;
|
gCmdLine = pCmdLine;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +156,7 @@ EFI_STATUS EFIAPI VtoyUtilEfiMain
|
|||||||
|
|
||||||
ParseCmdline(ImageHandle);
|
ParseCmdline(ImageHandle);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(gFeatureList); i++)
|
for (i = 0; gCurFeature && i < ARRAY_SIZE(gFeatureList); i++)
|
||||||
{
|
{
|
||||||
Len = StrLen(gFeatureList[i].Cmd);
|
Len = StrLen(gFeatureList[i].Cmd);
|
||||||
if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0)
|
if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0)
|
||||||
@@ -127,8 +167,11 @@ EFI_STATUS EFIAPI VtoyUtilEfiMain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gCmdLine)
|
||||||
|
{
|
||||||
FreePool(gCmdLine);
|
FreePool(gCmdLine);
|
||||||
gCmdLine = NULL;
|
gCmdLine = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
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 const char * (*grub_env_get_pf)(const char *name);
|
||||||
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
||||||
|
|
||||||
@@ -38,7 +39,9 @@ typedef struct ventoy_grub_param_file_replace
|
|||||||
typedef struct ventoy_grub_param
|
typedef struct ventoy_grub_param
|
||||||
{
|
{
|
||||||
grub_env_get_pf grub_env_get;
|
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 file_replace;
|
||||||
|
ventoy_grub_param_file_replace img_replace;
|
||||||
grub_env_printf_pf grub_env_printf;
|
grub_env_printf_pf grub_env_printf;
|
||||||
}ventoy_grub_param;
|
}ventoy_grub_param;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
@@ -55,7 +58,9 @@ VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...);
|
|||||||
#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__)
|
#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__)
|
||||||
#define Printf VtoyUtilDebug
|
#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 FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
||||||
|
EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
[Sources]
|
[Sources]
|
||||||
VtoyUtil.h
|
VtoyUtil.h
|
||||||
VtoyUtil.c
|
VtoyUtil.c
|
||||||
|
VtoyDrv.c
|
||||||
Memhole.c
|
Memhole.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
|
|||||||
@@ -205,6 +205,7 @@
|
|||||||
[Components]
|
[Components]
|
||||||
MdeModulePkg/Application/Ventoy/Ventoy.inf
|
MdeModulePkg/Application/Ventoy/Ventoy.inf
|
||||||
MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
|
MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
|
||||||
|
MdeModulePkg/Application/VDiskChain/VDiskChain.inf
|
||||||
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
||||||
MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
|
MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
|
||||||
MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
|
MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
|
||||||
|
|||||||
1
EfiISO/ISO/EFI/BOOT/BOOTX64.EFI
Normal file
1
EfiISO/ISO/EFI/BOOT/BOOTX64.EFI
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
13
EfiISO/mkefiiso.sh
Normal file
13
EfiISO/mkefiiso.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/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/
|
||||||
|
|
||||||
32
ExFAT/buidexfat_aarch64.sh
Normal file
32
ExFAT/buidexfat_aarch64.sh
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
29
ExFAT/buidlibfuse_aarch64.sh
Normal file
29
ExFAT/buidlibfuse_aarch64.sh
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/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,10 +11,16 @@ else
|
|||||||
opt=-lrt
|
opt=-lrt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# use musl-c to build for x86_64
|
||||||
|
#
|
||||||
|
|
||||||
export C_INCLUDE_PATH=$LIBFUSE_DIR/include
|
export C_INCLUDE_PATH=$LIBFUSE_DIR/include
|
||||||
|
|
||||||
rm -f $name
|
rm -f $name
|
||||||
gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a -lpthread -ldl $opt
|
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
|
||||||
|
|
||||||
if [ -e $name ]; then
|
if [ -e $name ]; then
|
||||||
echo -e "\n############### SUCCESS $name ##################\n"
|
echo -e "\n############### SUCCESS $name ##################\n"
|
||||||
|
|||||||
21
FUSEISO/build_aarch64.sh
Normal file
21
FUSEISO/build_aarch64.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/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,6 +7,8 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# use mini-native-x86_64 UCLIBC to build for x86_64
|
||||||
|
|
||||||
|
|
||||||
CUR="$PWD"
|
CUR="$PWD"
|
||||||
LIBFUSE_DIR=$CUR/LIBFUSE
|
LIBFUSE_DIR=$CUR/LIBFUSE
|
||||||
@@ -31,7 +33,7 @@ fi
|
|||||||
|
|
||||||
./makeconf.sh
|
./makeconf.sh
|
||||||
|
|
||||||
./configure --prefix="$LIBFUSE_DIR"
|
./configure --prefix="$LIBFUSE_DIR" CFLAGS='-specs /usr/local/musl/lib/musl-gcc.specs'
|
||||||
make -j 16
|
make -j 16
|
||||||
make install
|
make install
|
||||||
cd ..
|
cd ..
|
||||||
|
|||||||
46
FUSEISO/build_libfuse_aarch64.sh
Normal file
46
FUSEISO/build_libfuse_aarch64.sh
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/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,11 +114,12 @@ static int ventoy_iso_open(const char *path, struct fuse_file_info *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, void *buf)
|
static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, char *buf)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t leftSec = 0;
|
uint32_t leftSec = 0;
|
||||||
uint32_t readSec = 0;
|
uint32_t readSec = 0;
|
||||||
|
off_t offset = 0;
|
||||||
dmtable_entry *entry = NULL;
|
dmtable_entry *entry = NULL;
|
||||||
|
|
||||||
for (i = 0; i < g_disk_entry_num && num > 0; i++)
|
for (i = 0; i < g_disk_entry_num && num > 0; i++)
|
||||||
@@ -127,14 +128,15 @@ static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, void *buf)
|
|||||||
|
|
||||||
if (sector >= entry->isoSector && sector < entry->isoSector + entry->sectorNum)
|
if (sector >= entry->isoSector && sector < entry->isoSector + entry->sectorNum)
|
||||||
{
|
{
|
||||||
lseek(g_disk_fd, (entry->diskSector + (sector - entry->isoSector)) * 512, SEEK_SET);
|
offset = (entry->diskSector + (sector - entry->isoSector)) * 512;
|
||||||
|
|
||||||
leftSec = entry->sectorNum - (sector - entry->isoSector);
|
leftSec = entry->sectorNum - (sector - entry->isoSector);
|
||||||
readSec = (leftSec > num) ? num : leftSec;
|
readSec = (leftSec > num) ? num : leftSec;
|
||||||
|
|
||||||
read(g_disk_fd, buf, readSec * 512);
|
pread(g_disk_fd, buf, readSec * 512, offset);
|
||||||
|
|
||||||
sector += readSec;
|
sector += readSec;
|
||||||
|
buf += readSec * 512;
|
||||||
num -= readSec;
|
num -= readSec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
FUSEISO/vtoy_fuse_iso_aa64
Normal file
BIN
FUSEISO/vtoy_fuse_iso_aa64
Normal file
Binary file not shown.
2123
GRUB2/MOD_SRC/grub-2.04/configure.ac
Normal file
2123
GRUB2/MOD_SRC/grub-2.04/configure.ac
Normal file
File diff suppressed because it is too large
Load Diff
909
GRUB2/MOD_SRC/grub-2.04/gentpl.py
Normal file
909
GRUB2/MOD_SRC/grub-2.04/gentpl.py
Normal file
@@ -0,0 +1,909 @@
|
|||||||
|
#! /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()
|
||||||
507
GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am
Normal file
507
GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am
Normal file
@@ -0,0 +1,507 @@
|
|||||||
|
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,6 +100,10 @@ kernel = {
|
|||||||
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
||||||
arm_uboot_ldflags = '-Wl,-r,-d';
|
arm_uboot_ldflags = '-Wl,-r,-d';
|
||||||
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
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_ldflags = '-Wl,-r,-d';
|
||||||
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
||||||
|
|
||||||
@@ -114,6 +118,7 @@ kernel = {
|
|||||||
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
||||||
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
||||||
mips_startup = kern/mips/startup.S;
|
mips_startup = kern/mips/startup.S;
|
||||||
|
mips64_efi_startup = kern/mips64/efi/startup.S;
|
||||||
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
|
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
|
||||||
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
|
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
|
||||||
arm_uboot_startup = kern/arm/startup.S;
|
arm_uboot_startup = kern/arm/startup.S;
|
||||||
@@ -310,6 +315,15 @@ kernel = {
|
|||||||
extra_dist = video/sis315_init.c;
|
extra_dist = video/sis315_init.c;
|
||||||
mips_loongson = commands/keylayouts.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/cache.S;
|
||||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||||
@@ -809,6 +823,16 @@ module = {
|
|||||||
common = commands/blocklist.c;
|
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 = {
|
module = {
|
||||||
name = boot;
|
name = boot;
|
||||||
common = commands/boot.c;
|
common = commands/boot.c;
|
||||||
@@ -818,6 +842,7 @@ module = {
|
|||||||
enable = sparc64_ieee1275;
|
enable = sparc64_ieee1275;
|
||||||
enable = powerpc_ieee1275;
|
enable = powerpc_ieee1275;
|
||||||
enable = mips_arc;
|
enable = mips_arc;
|
||||||
|
enable = mips64_efi;
|
||||||
enable = ia64_efi;
|
enable = ia64_efi;
|
||||||
enable = arm_efi;
|
enable = arm_efi;
|
||||||
enable = arm64_efi;
|
enable = arm64_efi;
|
||||||
@@ -986,6 +1011,7 @@ module = {
|
|||||||
module = {
|
module = {
|
||||||
name = loadenv;
|
name = loadenv;
|
||||||
common = commands/loadenv.c;
|
common = commands/loadenv.c;
|
||||||
|
common = commands/loadenv.h;
|
||||||
common = lib/envblk.c;
|
common = lib/envblk.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1577,12 +1603,23 @@ module = {
|
|||||||
module = {
|
module = {
|
||||||
name = ventoy;
|
name = ventoy;
|
||||||
common = ventoy/ventoy.c;
|
common = ventoy/ventoy.c;
|
||||||
|
common = ventoy/ventoy_cmd.c;
|
||||||
common = ventoy/ventoy_linux.c;
|
common = ventoy/ventoy_linux.c;
|
||||||
|
common = ventoy/ventoy_unix.c;
|
||||||
common = ventoy/ventoy_windows.c;
|
common = ventoy/ventoy_windows.c;
|
||||||
|
common = ventoy/ventoy_vhd.c;
|
||||||
common = ventoy/ventoy_plugin.c;
|
common = ventoy/ventoy_plugin.c;
|
||||||
common = ventoy/ventoy_json.c;
|
common = ventoy/ventoy_json.c;
|
||||||
|
common = ventoy/ventoy_browser.c;
|
||||||
common = ventoy/lzx.c;
|
common = ventoy/lzx.c;
|
||||||
|
common = ventoy/xpress.c;
|
||||||
common = ventoy/huffman.c;
|
common = ventoy/huffman.c;
|
||||||
|
common = ventoy/miniz.c;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = setkey;
|
||||||
|
common = term/setkey.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
@@ -1647,6 +1684,8 @@ module = {
|
|||||||
efi = lib/efi/relocator.c;
|
efi = lib/efi/relocator.c;
|
||||||
mips = lib/mips/relocator_asm.S;
|
mips = lib/mips/relocator_asm.S;
|
||||||
mips = lib/mips/relocator.c;
|
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_asm.S;
|
||||||
powerpc = lib/powerpc/relocator.c;
|
powerpc = lib/powerpc/relocator.c;
|
||||||
xen = lib/xen/relocator.c;
|
xen = lib/xen/relocator.c;
|
||||||
@@ -1659,6 +1698,7 @@ module = {
|
|||||||
extra_dist = kern/powerpc/cache_flush.S;
|
extra_dist = kern/powerpc/cache_flush.S;
|
||||||
|
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
enable = mips64;
|
||||||
enable = powerpc;
|
enable = powerpc;
|
||||||
enable = x86;
|
enable = x86;
|
||||||
enable = i386_xen_pvh;
|
enable = i386_xen_pvh;
|
||||||
@@ -1789,6 +1829,7 @@ module = {
|
|||||||
i386_pc = lib/i386/pc/vesa_modes_table.c;
|
i386_pc = lib/i386/pc/vesa_modes_table.c;
|
||||||
i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
|
i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
|
||||||
mips = loader/mips/linux.c;
|
mips = loader/mips/linux.c;
|
||||||
|
mips64 = loader/mips64/linux.c;
|
||||||
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
||||||
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
||||||
ia64_efi = loader/ia64/efi/linux.c;
|
ia64_efi = loader/ia64/efi/linux.c;
|
||||||
@@ -1895,6 +1936,7 @@ module = {
|
|||||||
enable = riscv32_efi;
|
enable = riscv32_efi;
|
||||||
enable = riscv64_efi;
|
enable = riscv64_efi;
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
enable = mips64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ LOCAL(stop):
|
|||||||
jmp LOCAL(stop)
|
jmp LOCAL(stop)
|
||||||
|
|
||||||
ventoy_uuid: .ascii "XXXXXXXXXXXXXXXX"
|
ventoy_uuid: .ascii "XXXXXXXXXXXXXXXX"
|
||||||
notification_string: .asciz "GR"
|
notification_string: .asciz "VT"
|
||||||
geometry_error_string: .asciz "Ge"
|
geometry_error_string: .asciz "Ge"
|
||||||
hd_probe_error_string: .asciz "HD"
|
hd_probe_error_string: .asciz "HD"
|
||||||
read_error_string: .asciz "Rd"
|
read_error_string: .asciz "Rd"
|
||||||
|
|||||||
1111
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c
Normal file
1111
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c
Normal file
File diff suppressed because it is too large
Load Diff
349
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c
Normal file
349
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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", 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);
|
||||||
|
}
|
||||||
894
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c
Normal file
894
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c
Normal file
@@ -0,0 +1,894 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
397
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c
Normal file
397
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
93
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h
Normal file
93
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
349
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c
Normal file
349
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
353
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c
Normal file
353
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
/* 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 1;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
257
GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c
Normal file
257
GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
1603
GRUB2/MOD_SRC/grub-2.04/grub-core/font/font.c
Normal file
1603
GRUB2/MOD_SRC/grub-2.04/grub-core/font/font.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@
|
|||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static int g_ventoy_no_joliet = 0;
|
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_pos = 0;
|
||||||
static grub_uint64_t g_ventoy_last_read_offset = 0;
|
static grub_uint64_t g_ventoy_last_read_offset = 0;
|
||||||
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
|
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
|
||||||
@@ -451,6 +452,7 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||||||
|
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
|
|
||||||
|
g_ventoy_cur_joliet = 0;
|
||||||
block = 16;
|
block = 16;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -484,6 +486,7 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||||||
if (0 == g_ventoy_no_joliet) {
|
if (0 == g_ventoy_no_joliet) {
|
||||||
copy_voldesc = 1;
|
copy_voldesc = 1;
|
||||||
data->joliet = 1;
|
data->joliet = 1;
|
||||||
|
g_ventoy_cur_joliet = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -735,6 +738,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
|||||||
{
|
{
|
||||||
if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
|
if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
|
||||||
ctx.type = GRUB_FSHELP_DIR;
|
ctx.type = GRUB_FSHELP_DIR;
|
||||||
|
else if ((dirent.flags & FLAG_TYPE) == 3)
|
||||||
|
ctx.type = GRUB_FSHELP_DIR;
|
||||||
else
|
else
|
||||||
ctx.type = GRUB_FSHELP_REG;
|
ctx.type = GRUB_FSHELP_REG;
|
||||||
}
|
}
|
||||||
@@ -1116,6 +1121,11 @@ void grub_iso9660_set_nojoliet(int nojoliet)
|
|||||||
g_ventoy_no_joliet = 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)
|
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file)
|
||||||
{
|
{
|
||||||
(void)file;
|
(void)file;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
extern int g_ventoy_memdisk_mode;
|
extern int g_ventoy_memdisk_mode;
|
||||||
extern int g_ventoy_iso_raw;
|
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 int g_ventoy_iso_uefi_drv;
|
||||||
|
|
||||||
static const char *align_options[] =
|
static const char *align_options[] =
|
||||||
@@ -57,11 +59,15 @@ struct grub_gui_label
|
|||||||
grub_font_t font;
|
grub_font_t font;
|
||||||
grub_video_rgba_color_t color;
|
grub_video_rgba_color_t color;
|
||||||
int value;
|
int value;
|
||||||
|
int vtoytip;
|
||||||
enum align_mode align;
|
enum align_mode align;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct grub_gui_label *grub_gui_label_t;
|
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
|
static void
|
||||||
label_destroy (void *vself)
|
label_destroy (void *vself)
|
||||||
{
|
{
|
||||||
@@ -88,6 +94,7 @@ label_is_instance (void *vself __attribute__((unused)), const char *type)
|
|||||||
static void
|
static void
|
||||||
label_paint (void *vself, const grub_video_rect_t *region)
|
label_paint (void *vself, const grub_video_rect_t *region)
|
||||||
{
|
{
|
||||||
|
const char *text;
|
||||||
grub_gui_label_t self = vself;
|
grub_gui_label_t self = vself;
|
||||||
|
|
||||||
if (! self->visible)
|
if (! self->visible)
|
||||||
@@ -96,16 +103,24 @@ label_paint (void *vself, const grub_video_rect_t *region)
|
|||||||
if (!grub_video_have_common_points (region, &self->bounds))
|
if (!grub_video_have_common_points (region, &self->bounds))
|
||||||
return;
|
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. */
|
/* Calculate the starting x coordinate. */
|
||||||
int left_x;
|
int left_x;
|
||||||
if (self->align == align_left)
|
if (self->align == align_left)
|
||||||
left_x = 0;
|
left_x = 0;
|
||||||
else if (self->align == align_center)
|
else if (self->align == align_center)
|
||||||
left_x = (self->bounds.width
|
left_x = (self->bounds.width
|
||||||
- grub_font_get_string_width (self->font, self->text)) / 2;
|
- grub_font_get_string_width (self->font, text)) / 2;
|
||||||
else if (self->align == align_right)
|
else if (self->align == align_right)
|
||||||
left_x = (self->bounds.width
|
left_x = (self->bounds.width
|
||||||
- grub_font_get_string_width (self->font, self->text));
|
- grub_font_get_string_width (self->font, text));
|
||||||
else
|
else
|
||||||
return; /* Invalid alignment. */
|
return; /* Invalid alignment. */
|
||||||
|
|
||||||
@@ -114,7 +129,7 @@ label_paint (void *vself, const grub_video_rect_t *region)
|
|||||||
|
|
||||||
grub_video_rect_t vpsave;
|
grub_video_rect_t vpsave;
|
||||||
grub_gui_set_viewport (&self->bounds, &vpsave);
|
grub_gui_set_viewport (&self->bounds, &vpsave);
|
||||||
grub_font_draw_string (self->text,
|
grub_font_draw_string (text,
|
||||||
self->font,
|
self->font,
|
||||||
grub_video_map_rgba_color (self->color),
|
grub_video_map_rgba_color (self->color),
|
||||||
left_x,
|
left_x,
|
||||||
@@ -205,6 +220,12 @@ label_set_property (void *vself, const char *name, const char *value)
|
|||||||
else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
|
else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
|
||||||
value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " ";
|
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) {
|
else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) {
|
||||||
value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
|
value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
|
||||||
}
|
}
|
||||||
@@ -247,8 +268,14 @@ label_set_property (void *vself, const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self->id);
|
grub_free (self->id);
|
||||||
if (value)
|
if (value) {
|
||||||
self->id = grub_strdup (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
|
else
|
||||||
self->id = 0;
|
self->id = 0;
|
||||||
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||||
|
|||||||
868
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
Normal file
868
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
Normal file
@@ -0,0 +1,868 @@
|
|||||||
|
/* theme_loader.c - Theme file loader for gfxmenu. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2008 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/file.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/video.h>
|
||||||
|
#include <grub/gui_string_util.h>
|
||||||
|
#include <grub/bitmap.h>
|
||||||
|
#include <grub/bitmap_scale.h>
|
||||||
|
#include <grub/gfxwidgets.h>
|
||||||
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/gui.h>
|
||||||
|
#include <grub/color.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop);
|
||||||
|
|
||||||
|
/* Construct a new box widget using ABSPATTERN to find the pixmap files for
|
||||||
|
it, storing the new box instance at *BOXPTR.
|
||||||
|
PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
|
||||||
|
The '*' then gets substituted with the various pixmap names that the
|
||||||
|
box uses. */
|
||||||
|
static grub_err_t
|
||||||
|
recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern)
|
||||||
|
{
|
||||||
|
char *prefix;
|
||||||
|
char *suffix;
|
||||||
|
char *star;
|
||||||
|
grub_gfxmenu_box_t box;
|
||||||
|
|
||||||
|
star = grub_strchr (abspattern, '*');
|
||||||
|
if (! star)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"missing `*' in box pixmap pattern `%s'", abspattern);
|
||||||
|
|
||||||
|
/* Prefix: Get the part before the '*'. */
|
||||||
|
prefix = grub_malloc (star - abspattern + 1);
|
||||||
|
if (! prefix)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
grub_memcpy (prefix, abspattern, star - abspattern);
|
||||||
|
prefix[star - abspattern] = '\0';
|
||||||
|
|
||||||
|
/* Suffix: Everything after the '*' is the suffix. */
|
||||||
|
suffix = star + 1;
|
||||||
|
|
||||||
|
box = grub_gfxmenu_create_box (prefix, suffix);
|
||||||
|
grub_free (prefix);
|
||||||
|
if (! box)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (*boxptr)
|
||||||
|
(*boxptr)->destroy (*boxptr);
|
||||||
|
*boxptr = box;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Construct a new box widget using PATTERN to find the pixmap files for it,
|
||||||
|
storing the new widget at *BOXPTR. PATTERN should be of the form:
|
||||||
|
"somewhere/style*.png". The '*' then gets substituted with the various
|
||||||
|
pixmap names that the widget uses.
|
||||||
|
|
||||||
|
Important! The value of *BOXPTR must be initialized! It must either
|
||||||
|
(1) Be 0 (a NULL pointer), or
|
||||||
|
(2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance.
|
||||||
|
In this case, the previous instance is destroyed. */
|
||||||
|
grub_err_t
|
||||||
|
grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
|
||||||
|
const char *pattern, const char *theme_dir)
|
||||||
|
{
|
||||||
|
char *abspattern;
|
||||||
|
|
||||||
|
/* Check arguments. */
|
||||||
|
if (! pattern)
|
||||||
|
{
|
||||||
|
/* If no pixmap pattern is given, then just create an empty box. */
|
||||||
|
if (*boxptr)
|
||||||
|
(*boxptr)->destroy (*boxptr);
|
||||||
|
*boxptr = grub_gfxmenu_create_box (0, 0);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! theme_dir)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"styled box missing theme directory");
|
||||||
|
|
||||||
|
/* Resolve to an absolute path. */
|
||||||
|
abspattern = grub_resolve_relative_path (theme_dir, pattern);
|
||||||
|
if (! abspattern)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
/* Create the box. */
|
||||||
|
recreate_box_absolute (boxptr, abspattern);
|
||||||
|
grub_free (abspattern);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
theme_get_unsigned_int_from_proportional (const char *value,
|
||||||
|
unsigned absolute_value,
|
||||||
|
unsigned int *parsed_value)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_fixed_signed_t frac;
|
||||||
|
signed pixels;
|
||||||
|
err = parse_proportional_spec (value, &pixels, &frac);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels;
|
||||||
|
if (result < 0)
|
||||||
|
result = 0;
|
||||||
|
*parsed_value = result;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the specified property NAME on the view to the given string VALUE.
|
||||||
|
The caller is responsible for the lifetimes of NAME and VALUE. */
|
||||||
|
static grub_err_t
|
||||||
|
theme_set_string (grub_gfxmenu_view_t view,
|
||||||
|
const char *name,
|
||||||
|
const char *value,
|
||||||
|
const char *theme_dir,
|
||||||
|
const char *filename,
|
||||||
|
int line_num,
|
||||||
|
int col_num)
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("title-font", name))
|
||||||
|
view->title_font = grub_font_get (value);
|
||||||
|
else if (! grub_strcmp ("message-font", name))
|
||||||
|
view->message_font = grub_font_get (value);
|
||||||
|
else if (! grub_strcmp ("terminal-font", name))
|
||||||
|
{
|
||||||
|
grub_free (view->terminal_font_name);
|
||||||
|
view->terminal_font_name = grub_strdup (value);
|
||||||
|
if (! view->terminal_font_name)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("title-color", name))
|
||||||
|
grub_video_parse_color (value, &view->title_color);
|
||||||
|
else if (! grub_strcmp ("message-color", name))
|
||||||
|
grub_video_parse_color (value, &view->message_color);
|
||||||
|
else if (! grub_strcmp ("message-bg-color", name))
|
||||||
|
grub_video_parse_color (value, &view->message_bg_color);
|
||||||
|
else if (! grub_strcmp ("desktop-image", name))
|
||||||
|
{
|
||||||
|
struct grub_video_bitmap *raw_bitmap;
|
||||||
|
char *path;
|
||||||
|
path = grub_resolve_relative_path (theme_dir, value);
|
||||||
|
if (! path)
|
||||||
|
return grub_errno;
|
||||||
|
if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_free (path);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_free(path);
|
||||||
|
grub_video_bitmap_destroy (view->raw_desktop_image);
|
||||||
|
view->raw_desktop_image = raw_bitmap;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-scale-method", name))
|
||||||
|
{
|
||||||
|
if (! value || ! grub_strcmp ("stretch", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH;
|
||||||
|
else if (! grub_strcmp ("crop", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP;
|
||||||
|
else if (! grub_strcmp ("padding", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING;
|
||||||
|
else if (! grub_strcmp ("fitwidth", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH;
|
||||||
|
else if (! grub_strcmp ("fitheight", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported scale method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-h-align", name))
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("left", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT;
|
||||||
|
else if (! grub_strcmp ("center", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER;
|
||||||
|
else if (! grub_strcmp ("right", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported horizontal align method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-v-align", name))
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("top", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP;
|
||||||
|
else if (! grub_strcmp ("center", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER;
|
||||||
|
else if (! grub_strcmp ("bottom", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported vertical align method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-color", name))
|
||||||
|
grub_video_parse_color (value, &view->desktop_color);
|
||||||
|
else if (! grub_strcmp ("terminal-box", name))
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-border", name))
|
||||||
|
{
|
||||||
|
view->terminal_border = grub_strtoul (value, 0, 10);
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-left", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.width,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.x = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-top", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.height,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.y = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-width", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.width,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.width = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-height", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.height,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.height = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("title-text", name))
|
||||||
|
{
|
||||||
|
grub_free (view->title_text);
|
||||||
|
view->title_text = grub_strdup (value);
|
||||||
|
if (! view->title_text)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"%s:%d:%d unknown property `%s'",
|
||||||
|
filename, line_num, col_num, name);
|
||||||
|
}
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct parsebuf
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int pos;
|
||||||
|
int len;
|
||||||
|
int line_num;
|
||||||
|
int col_num;
|
||||||
|
const char *filename;
|
||||||
|
char *theme_dir;
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
has_more (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
return p->pos < p->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_char (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
if (has_more (p))
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
c = p->buf[p->pos++];
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
p->line_num++;
|
||||||
|
p->col_num = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->col_num++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
peek_char (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
if (has_more (p))
|
||||||
|
return p->buf[p->pos];
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_whitespace (char c)
|
||||||
|
{
|
||||||
|
return (c == ' '
|
||||||
|
|| c == '\t'
|
||||||
|
|| c == '\r'
|
||||||
|
|| c == '\n'
|
||||||
|
|| c == '\f');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
skip_whitespace (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
while (has_more (p) && is_whitespace(peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
advance_to_next_line (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* Eat characters up to the newline. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = read_char (p);
|
||||||
|
}
|
||||||
|
while (c != -1 && c != '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_identifier_char (int c)
|
||||||
|
{
|
||||||
|
return (c != -1
|
||||||
|
&& (grub_isalpha(c)
|
||||||
|
|| grub_isdigit(c)
|
||||||
|
|| c == '_'
|
||||||
|
|| c == '-'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_identifier (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
/* Index of the first character of the identifier in p->buf. */
|
||||||
|
int start;
|
||||||
|
/* Next index after the last character of the identifer in p->buf. */
|
||||||
|
int end;
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Capture the start of the identifier. */
|
||||||
|
start = p->pos;
|
||||||
|
|
||||||
|
/* Scan for the end. */
|
||||||
|
while (is_identifier_char (peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
|
||||||
|
if (end - start < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return grub_new_substring (p->buf, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_expression (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (peek_char (p) == '"')
|
||||||
|
{
|
||||||
|
/* Read as a quoted string.
|
||||||
|
The quotation marks are not included in the expression value. */
|
||||||
|
/* Skip opening quotation mark. */
|
||||||
|
read_char (p);
|
||||||
|
start = p->pos;
|
||||||
|
while (has_more (p) && peek_char (p) != '"')
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
/* Skip the terminating quotation mark. */
|
||||||
|
read_char (p);
|
||||||
|
}
|
||||||
|
else if (peek_char (p) == '(')
|
||||||
|
{
|
||||||
|
/* Read as a parenthesized string -- for tuples/coordinates. */
|
||||||
|
/* The parentheses are included in the expression value. */
|
||||||
|
int c;
|
||||||
|
|
||||||
|
start = p->pos;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = read_char (p);
|
||||||
|
}
|
||||||
|
while (c != -1 && c != ')');
|
||||||
|
end = p->pos;
|
||||||
|
}
|
||||||
|
else if (has_more (p))
|
||||||
|
{
|
||||||
|
/* Read as a single word -- for numeric values or words without
|
||||||
|
whitespace. */
|
||||||
|
start = p->pos;
|
||||||
|
while (has_more (p) && ! is_whitespace (peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The end of the theme file has been reached. */
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return grub_new_substring (p->buf, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop)
|
||||||
|
{
|
||||||
|
signed num;
|
||||||
|
const char *ptr;
|
||||||
|
int sig = 0;
|
||||||
|
*abs = 0;
|
||||||
|
*prop = 0;
|
||||||
|
ptr = value;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
sig = 0;
|
||||||
|
|
||||||
|
while (*ptr == '-' || *ptr == '+')
|
||||||
|
{
|
||||||
|
if (*ptr == '-')
|
||||||
|
sig = !sig;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = grub_strtoul (ptr, (char **) &ptr, 0);
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
if (sig)
|
||||||
|
num = -num;
|
||||||
|
if (*ptr == '%')
|
||||||
|
{
|
||||||
|
*prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*abs += num;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read a GUI object specification from the theme file.
|
||||||
|
Any components created will be added to the GUI container PARENT. */
|
||||||
|
static grub_err_t
|
||||||
|
read_object (struct parsebuf *p, grub_gui_container_t parent)
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
name = read_identifier (p);
|
||||||
|
if (! name)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
grub_gui_component_t component = 0;
|
||||||
|
if (grub_strcmp (name, "label") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_label_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "image") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_image_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "vbox") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_vbox_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "hbox") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_hbox_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "canvas") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_canvas_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "progress_bar") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_progress_bar_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "circular_progress") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_circular_progress_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "boot_menu") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_list_new ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown type. */
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! component)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Inform the component about the theme so it can find its resources. */
|
||||||
|
component->ops->set_property (component, "theme_dir", p->theme_dir);
|
||||||
|
component->ops->set_property (component, "theme_path", p->filename);
|
||||||
|
|
||||||
|
/* Add the component as a child of PARENT. */
|
||||||
|
bounds.x = 0;
|
||||||
|
bounds.y = 0;
|
||||||
|
bounds.width = -1;
|
||||||
|
bounds.height = -1;
|
||||||
|
component->ops->set_bounds (component, &bounds);
|
||||||
|
parent->ops->add (parent, component);
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (read_char (p) != '{')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d expected `{' after object type name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (has_more (p))
|
||||||
|
{
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Check whether the end has been encountered. */
|
||||||
|
if (peek_char (p) == '}')
|
||||||
|
{
|
||||||
|
/* Skip the closing brace. */
|
||||||
|
read_char (p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peek_char (p) == '#')
|
||||||
|
{
|
||||||
|
/* Skip comments. */
|
||||||
|
advance_to_next_line (p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peek_char (p) == '+')
|
||||||
|
{
|
||||||
|
/* Skip the '+'. */
|
||||||
|
read_char (p);
|
||||||
|
|
||||||
|
/* Check whether this component is a container. */
|
||||||
|
if (component->ops->is_instance (component, "container"))
|
||||||
|
{
|
||||||
|
/* Read the sub-object recursively and add it as a child. */
|
||||||
|
if (read_object (p, (grub_gui_container_t) component) != 0)
|
||||||
|
goto cleanup;
|
||||||
|
/* After reading the sub-object, resume parsing, expecting
|
||||||
|
another property assignment or sub-object definition. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d attempted to add object to non-container",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *property;
|
||||||
|
property = read_identifier (p);
|
||||||
|
if (! property)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (read_char (p) != '=')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d expected `=' after property name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, property);
|
||||||
|
grub_free (property);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
char *value;
|
||||||
|
value = read_expression (p);
|
||||||
|
if (! value)
|
||||||
|
{
|
||||||
|
grub_free (property);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the property value. */
|
||||||
|
if (grub_strcmp (property, "left") == 0)
|
||||||
|
parse_proportional_spec (value, &component->x, &component->xfrac);
|
||||||
|
else if (grub_strcmp (property, "top") == 0)
|
||||||
|
parse_proportional_spec (value, &component->y, &component->yfrac);
|
||||||
|
else if (grub_strcmp (property, "width") == 0)
|
||||||
|
parse_proportional_spec (value, &component->w, &component->wfrac);
|
||||||
|
else if (grub_strcmp (property, "height") == 0)
|
||||||
|
parse_proportional_spec (value, &component->h, &component->hfrac);
|
||||||
|
else
|
||||||
|
/* General property handling. */
|
||||||
|
component->ops->set_property (component, property, value);
|
||||||
|
|
||||||
|
grub_free (value);
|
||||||
|
grub_free (property);
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
grub_free (name);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
read_property (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* Read the property name. */
|
||||||
|
name = read_identifier (p);
|
||||||
|
if (! name)
|
||||||
|
{
|
||||||
|
advance_to_next_line (p);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip whitespace before separator. */
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Read separator. */
|
||||||
|
if (read_char (p) != ':')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d missing separator after property name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip whitespace after separator. */
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Get the value based on its type. */
|
||||||
|
if (peek_char (p) == '"')
|
||||||
|
{
|
||||||
|
/* String value (e.g., '"My string"'). */
|
||||||
|
char *value = read_expression (p);
|
||||||
|
if (! value)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* If theme_set_string results in an error, grub_errno will be returned
|
||||||
|
below. */
|
||||||
|
theme_set_string (p->view, name, value, p->theme_dir,
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
grub_free (value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d property value invalid; "
|
||||||
|
"enclose literal values in quotes (\")",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
grub_free (name);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int g_menu_update_mode;
|
||||||
|
|
||||||
|
/* Set properties on the view based on settings from the specified
|
||||||
|
theme file. */
|
||||||
|
grub_err_t
|
||||||
|
grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
||||||
|
{
|
||||||
|
grub_file_t file;
|
||||||
|
struct parsebuf p;
|
||||||
|
|
||||||
|
p.view = view;
|
||||||
|
p.theme_dir = grub_get_dirname (theme_path);
|
||||||
|
|
||||||
|
file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME);
|
||||||
|
if (! file)
|
||||||
|
{
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.len = grub_file_size (file);
|
||||||
|
p.buf = grub_malloc (p.len + 8192);
|
||||||
|
p.pos = 0;
|
||||||
|
p.line_num = 1;
|
||||||
|
p.col_num = 1;
|
||||||
|
p.filename = theme_path;
|
||||||
|
if (! p.buf)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
if (grub_file_read (file, p.buf, p.len) != p.len)
|
||||||
|
{
|
||||||
|
grub_free (p.buf);
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING");
|
||||||
|
if (checkret == NULL || checkret[0] != '0')
|
||||||
|
{
|
||||||
|
p.len += grub_snprintf(p.buf + p.len, 4096, "\n+ hbox{\n left = 1%%\n top = 90%%\n"
|
||||||
|
" + label {text = \"[Unofficial Ventoy]\" color = \"red\" align = \"left\"}\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *tip = grub_env_get("VTOY_MENU_TIP_ENABLE");
|
||||||
|
if (tip && tip[0] == '1')
|
||||||
|
{
|
||||||
|
char tmpmsg[512];
|
||||||
|
|
||||||
|
grub_memset(tmpmsg, 'w', 500);
|
||||||
|
tmpmsg[500] = 0;
|
||||||
|
|
||||||
|
g_menu_update_mode = 1;
|
||||||
|
p.len += grub_snprintf(p.buf + p.len, 4096,
|
||||||
|
"\n+ vbox{\n left = %s\n top = %s\n"
|
||||||
|
"+ label { id=\"VTOY_MENU_TIP_1\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
|
||||||
|
"+ label { id=\"VTOY_MENU_TIP_2\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
|
||||||
|
"}\n",
|
||||||
|
grub_env_get("VTOY_TIP_LEFT"),
|
||||||
|
grub_env_get("VTOY_TIP_TOP"),
|
||||||
|
tmpmsg,
|
||||||
|
grub_env_get("VTOY_TIP_COLOR"),
|
||||||
|
grub_env_get("VTOY_TIP_ALIGN"),
|
||||||
|
tmpmsg,
|
||||||
|
grub_env_get("VTOY_TIP_COLOR"),
|
||||||
|
grub_env_get("VTOY_TIP_ALIGN")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
|
||||||
|
view->canvas = grub_gui_canvas_new ();
|
||||||
|
if (!view->canvas)
|
||||||
|
goto fail;
|
||||||
|
((grub_gui_component_t) view->canvas)
|
||||||
|
->ops->set_bounds ((grub_gui_component_t) view->canvas,
|
||||||
|
&view->screen);
|
||||||
|
|
||||||
|
while (has_more (&p))
|
||||||
|
{
|
||||||
|
/* Skip comments (lines beginning with #). */
|
||||||
|
if (peek_char (&p) == '#')
|
||||||
|
{
|
||||||
|
advance_to_next_line (&p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the first non-whitespace character. */
|
||||||
|
skip_whitespace (&p);
|
||||||
|
|
||||||
|
/* Handle the content. */
|
||||||
|
if (peek_char (&p) == '+')
|
||||||
|
{
|
||||||
|
/* Skip the '+'. */
|
||||||
|
read_char (&p);
|
||||||
|
read_object (&p, view->canvas);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_property (&p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new theme path. */
|
||||||
|
grub_free (view->theme_path);
|
||||||
|
view->theme_path = grub_strdup (theme_path);
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (view->canvas)
|
||||||
|
{
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
view->canvas = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
grub_free (p.buf);
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
665
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c
Normal file
665
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c
Normal file
@@ -0,0 +1,665 @@
|
|||||||
|
/* view.c - Graphical menu interface MVC view. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2008 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/file.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/normal.h>
|
||||||
|
#include <grub/video.h>
|
||||||
|
#include <grub/gfxterm.h>
|
||||||
|
#include <grub/bitmap.h>
|
||||||
|
#include <grub/bitmap_scale.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
#include <grub/gfxwidgets.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/menu.h>
|
||||||
|
#include <grub/menu_viewer.h>
|
||||||
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/gui_string_util.h>
|
||||||
|
#include <grub/icon_manager.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_terminal (grub_gfxmenu_view_t view);
|
||||||
|
static void
|
||||||
|
init_background (grub_gfxmenu_view_t view);
|
||||||
|
static grub_gfxmenu_view_t term_view;
|
||||||
|
|
||||||
|
/* Create a new view object, loading the theme specified by THEME_PATH and
|
||||||
|
associating MODEL with the view. */
|
||||||
|
grub_gfxmenu_view_t
|
||||||
|
grub_gfxmenu_view_new (const char *theme_path,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
grub_font_t default_font;
|
||||||
|
grub_video_rgba_color_t default_fg_color;
|
||||||
|
grub_video_rgba_color_t default_bg_color;
|
||||||
|
|
||||||
|
view = grub_malloc (sizeof (*view));
|
||||||
|
if (! view)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (grub_gfxmenu_timeout_notifications)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *p;
|
||||||
|
p = grub_gfxmenu_timeout_notifications;
|
||||||
|
grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next;
|
||||||
|
grub_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
view->screen.x = 0;
|
||||||
|
view->screen.y = 0;
|
||||||
|
view->screen.width = width;
|
||||||
|
view->screen.height = height;
|
||||||
|
|
||||||
|
view->need_to_check_sanity = 1;
|
||||||
|
view->terminal_border = 3;
|
||||||
|
view->terminal_rect.width = view->screen.width * 7 / 10;
|
||||||
|
view->terminal_rect.height = view->screen.height * 7 / 10;
|
||||||
|
view->terminal_rect.x = view->screen.x + (view->screen.width
|
||||||
|
- view->terminal_rect.width) / 2;
|
||||||
|
view->terminal_rect.y = view->screen.y + (view->screen.height
|
||||||
|
- view->terminal_rect.height) / 2;
|
||||||
|
|
||||||
|
default_font = grub_font_get ("Unknown Regular 16");
|
||||||
|
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
||||||
|
default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
|
||||||
|
|
||||||
|
view->canvas = 0;
|
||||||
|
|
||||||
|
view->title_font = default_font;
|
||||||
|
view->message_font = default_font;
|
||||||
|
view->terminal_font_name = grub_strdup ("Fixed 10");
|
||||||
|
view->title_color = default_fg_color;
|
||||||
|
view->message_color = default_bg_color;
|
||||||
|
view->message_bg_color = default_fg_color;
|
||||||
|
view->raw_desktop_image = 0;
|
||||||
|
view->scaled_desktop_image = 0;
|
||||||
|
view->desktop_image_scale_method = GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH;
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER;
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER;
|
||||||
|
view->desktop_color = default_bg_color;
|
||||||
|
view->terminal_box = grub_gfxmenu_create_box (0, 0);
|
||||||
|
view->title_text = grub_strdup (_("GRUB Boot Menu"));
|
||||||
|
view->progress_message_text = 0;
|
||||||
|
view->theme_path = 0;
|
||||||
|
|
||||||
|
/* Set the timeout bar's frame. */
|
||||||
|
view->progress_message_frame.width = view->screen.width * 4 / 5;
|
||||||
|
view->progress_message_frame.height = 50;
|
||||||
|
view->progress_message_frame.x = view->screen.x
|
||||||
|
+ (view->screen.width - view->progress_message_frame.width) / 2;
|
||||||
|
view->progress_message_frame.y = view->screen.y
|
||||||
|
+ view->screen.height - 90 - 20 - view->progress_message_frame.height;
|
||||||
|
|
||||||
|
if (grub_gfxmenu_view_load_theme (view, theme_path) != 0)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_destroy (view);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the view object. All used memory is freed. */
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (!view)
|
||||||
|
return;
|
||||||
|
while (grub_gfxmenu_timeout_notifications)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *p;
|
||||||
|
p = grub_gfxmenu_timeout_notifications;
|
||||||
|
grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next;
|
||||||
|
grub_free (p);
|
||||||
|
}
|
||||||
|
grub_video_bitmap_destroy (view->raw_desktop_image);
|
||||||
|
grub_video_bitmap_destroy (view->scaled_desktop_image);
|
||||||
|
if (view->terminal_box)
|
||||||
|
view->terminal_box->destroy (view->terminal_box);
|
||||||
|
grub_free (view->terminal_font_name);
|
||||||
|
grub_free (view->title_text);
|
||||||
|
grub_free (view->progress_message_text);
|
||||||
|
grub_free (view->theme_path);
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
grub_free (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_background (grub_gfxmenu_view_t view,
|
||||||
|
const grub_video_rect_t *bounds)
|
||||||
|
{
|
||||||
|
if (view->scaled_desktop_image)
|
||||||
|
{
|
||||||
|
struct grub_video_bitmap *img = view->scaled_desktop_image;
|
||||||
|
grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE,
|
||||||
|
bounds->x, bounds->y,
|
||||||
|
bounds->x - view->screen.x,
|
||||||
|
bounds->y - view->screen.y,
|
||||||
|
bounds->width, bounds->height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color),
|
||||||
|
bounds->x, bounds->y,
|
||||||
|
bounds->width, bounds->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_title (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (! view->title_text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Center the title. */
|
||||||
|
int title_width = grub_font_get_string_width (view->title_font,
|
||||||
|
view->title_text);
|
||||||
|
int x = (view->screen.width - title_width) / 2;
|
||||||
|
int y = 40 + grub_font_get_ascent (view->title_font);
|
||||||
|
grub_font_draw_string (view->title_text,
|
||||||
|
view->title_font,
|
||||||
|
grub_video_map_rgba_color (view->title_color),
|
||||||
|
x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct progress_value_data
|
||||||
|
{
|
||||||
|
int visible;
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_timeouts (int visible, int start, int value, int end)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *cur;
|
||||||
|
|
||||||
|
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||||
|
cur->set_state (cur->self, visible, start, value, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_timeouts (struct grub_gfxmenu_view *view)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *cur;
|
||||||
|
|
||||||
|
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
cur->self->ops->get_bounds (cur->self, &bounds);
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_print_timeout (int timeout, void *data)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_view *view = data;
|
||||||
|
|
||||||
|
if (view->first_timeout == -1)
|
||||||
|
view->first_timeout = timeout;
|
||||||
|
|
||||||
|
update_timeouts (1, -view->first_timeout, -timeout, 0);
|
||||||
|
redraw_timeouts (view);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
redraw_timeouts (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_clear_timeout (void *data)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_view *view = data;
|
||||||
|
|
||||||
|
update_timeouts (0, 1, 0, 0);
|
||||||
|
redraw_timeouts (view);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
redraw_timeouts (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_gui_list_t list = (grub_gui_list_t) component;
|
||||||
|
list->ops->set_view_info (list, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update any boot menu components with the current menu model and
|
||||||
|
theme path. */
|
||||||
|
static void
|
||||||
|
update_menu_components (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
update_menu_visit, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
refresh_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_gui_list_t list = (grub_gui_list_t) component;
|
||||||
|
list->ops->refresh_list (list, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Refresh list information (useful for submenus) */
|
||||||
|
static void
|
||||||
|
refresh_menu_components (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
refresh_menu_visit, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_message (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
char *text = view->progress_message_text;
|
||||||
|
grub_video_rect_t f = view->progress_message_frame;
|
||||||
|
if (! text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_font_t font = view->message_font;
|
||||||
|
grub_video_color_t color = grub_video_map_rgba_color (view->message_color);
|
||||||
|
|
||||||
|
/* Border. */
|
||||||
|
grub_video_fill_rect (color,
|
||||||
|
f.x-1, f.y-1, f.width+2, f.height+2);
|
||||||
|
/* Fill. */
|
||||||
|
grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color),
|
||||||
|
f.x, f.y, f.width, f.height);
|
||||||
|
|
||||||
|
/* Center the text. */
|
||||||
|
int text_width = grub_font_get_string_width (font, text);
|
||||||
|
int x = f.x + (f.width - text_width) / 2;
|
||||||
|
int y = (f.y + (f.height - grub_font_get_descent (font)) / 2
|
||||||
|
+ grub_font_get_ascent (font) / 2);
|
||||||
|
grub_font_draw_string (text, font, color, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
|
||||||
|
const grub_video_rect_t *region)
|
||||||
|
{
|
||||||
|
if (grub_video_have_common_points (&view->terminal_rect, region))
|
||||||
|
grub_gfxterm_schedule_repaint ();
|
||||||
|
|
||||||
|
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
|
||||||
|
grub_video_area_status_t area_status;
|
||||||
|
grub_video_get_area_status (&area_status);
|
||||||
|
if (area_status == GRUB_VIDEO_AREA_ENABLED)
|
||||||
|
grub_video_set_region (region->x, region->y,
|
||||||
|
region->width, region->height);
|
||||||
|
|
||||||
|
redraw_background (view, region);
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->paint (view->canvas, region);
|
||||||
|
draw_title (view);
|
||||||
|
if (grub_video_have_common_points (&view->progress_message_frame, region))
|
||||||
|
draw_message (view);
|
||||||
|
|
||||||
|
if (area_status == GRUB_VIDEO_AREA_ENABLED)
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
init_terminal (view);
|
||||||
|
|
||||||
|
init_background (view);
|
||||||
|
|
||||||
|
/* Clear the screen; there may be garbage left over in video memory. */
|
||||||
|
grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
|
||||||
|
view->screen.x, view->screen.y,
|
||||||
|
view->screen.width, view->screen.height);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
|
||||||
|
view->screen.x, view->screen.y,
|
||||||
|
view->screen.width, view->screen.height);
|
||||||
|
|
||||||
|
refresh_menu_components (view);
|
||||||
|
update_menu_components (view);
|
||||||
|
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->screen);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
{
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
|
||||||
|
component->ops->get_bounds (component, &bounds);
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int g_menu_update_mode;
|
||||||
|
|
||||||
|
static void grub_gfxmenu_update_all(grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_video_set_area_status(GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
grub_gfxmenu_view_redraw(view, &view->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
update_menu_components (view);
|
||||||
|
|
||||||
|
if (g_menu_update_mode)
|
||||||
|
grub_gfxmenu_update_all(view);
|
||||||
|
else
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
redraw_menu_visit, view);
|
||||||
|
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
{
|
||||||
|
if (g_menu_update_mode)
|
||||||
|
grub_gfxmenu_update_all(view);
|
||||||
|
else
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
redraw_menu_visit, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_set_chosen_entry (int entry, void *data)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = data;
|
||||||
|
|
||||||
|
view->selected = entry;
|
||||||
|
grub_gfxmenu_redraw_menu (view);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_gfxmenu_draw_terminal_box (void)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_box_t term_box;
|
||||||
|
|
||||||
|
term_box = term_view->terminal_box;
|
||||||
|
if (!term_box)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
|
||||||
|
term_box->set_content_size (term_box, term_view->terminal_rect.width,
|
||||||
|
term_view->terminal_rect.height);
|
||||||
|
|
||||||
|
term_box->draw (term_box,
|
||||||
|
term_view->terminal_rect.x - term_box->get_left_pad (term_box),
|
||||||
|
term_view->terminal_rect.y - term_box->get_top_pad (term_box));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_min_terminal (grub_font_t terminal_font,
|
||||||
|
unsigned int border_width,
|
||||||
|
unsigned int *min_terminal_width,
|
||||||
|
unsigned int *min_terminal_height)
|
||||||
|
{
|
||||||
|
struct grub_font_glyph *glyph;
|
||||||
|
glyph = grub_font_get_glyph (terminal_font, 'M');
|
||||||
|
*min_terminal_width = (glyph? glyph->device_width : 8) * 80
|
||||||
|
+ 2 * border_width;
|
||||||
|
*min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24
|
||||||
|
+ 2 * border_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
terminal_sanity_check (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (!view->need_to_check_sanity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* terminal_font was checked before in the init_terminal function. */
|
||||||
|
grub_font_t terminal_font = grub_font_get (view->terminal_font_name);
|
||||||
|
|
||||||
|
/* Non-negative numbers below. */
|
||||||
|
int scr_x = view->screen.x;
|
||||||
|
int scr_y = view->screen.y;
|
||||||
|
int scr_width = view->screen.width;
|
||||||
|
int scr_height = view->screen.height;
|
||||||
|
int term_x = view->terminal_rect.x;
|
||||||
|
int term_y = view->terminal_rect.y;
|
||||||
|
int term_width = view->terminal_rect.width;
|
||||||
|
int term_height = view->terminal_rect.height;
|
||||||
|
|
||||||
|
/* Check that border_width isn't too big. */
|
||||||
|
unsigned int border_width = view->terminal_border;
|
||||||
|
unsigned int min_terminal_width;
|
||||||
|
unsigned int min_terminal_height;
|
||||||
|
get_min_terminal (terminal_font, border_width,
|
||||||
|
&min_terminal_width, &min_terminal_height);
|
||||||
|
if (border_width > 3 && ((int) min_terminal_width >= scr_width
|
||||||
|
|| (int) min_terminal_height >= scr_height))
|
||||||
|
{
|
||||||
|
border_width = 3;
|
||||||
|
get_min_terminal (terminal_font, border_width,
|
||||||
|
&min_terminal_width, &min_terminal_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity checks. */
|
||||||
|
if (term_width > scr_width)
|
||||||
|
term_width = scr_width;
|
||||||
|
if (term_height > scr_height)
|
||||||
|
term_height = scr_height;
|
||||||
|
|
||||||
|
if (scr_width <= (int) min_terminal_width
|
||||||
|
|| scr_height <= (int) min_terminal_height)
|
||||||
|
{
|
||||||
|
/* The screen resulution is too low. Use all space, except a small border
|
||||||
|
to show the user, that it is a window. Then center the window. */
|
||||||
|
term_width = scr_width - 6 * border_width;
|
||||||
|
term_height = scr_height - 6 * border_width;
|
||||||
|
term_x = scr_x + (scr_width - term_width) / 2;
|
||||||
|
term_y = scr_y + (scr_height - term_height) / 2;
|
||||||
|
}
|
||||||
|
else if (term_width < (int) min_terminal_width
|
||||||
|
|| term_height < (int) min_terminal_height)
|
||||||
|
{
|
||||||
|
/* The screen resolution is big enough. Make sure, that terminal screen
|
||||||
|
dimensions aren't less than minimal values. Then center the window. */
|
||||||
|
term_width = (int) min_terminal_width;
|
||||||
|
term_height = (int) min_terminal_height;
|
||||||
|
term_x = scr_x + (scr_width - term_width) / 2;
|
||||||
|
term_y = scr_y + (scr_height - term_height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point w and h are satisfying. */
|
||||||
|
if (term_x + term_width > scr_width)
|
||||||
|
term_x = scr_width - term_width;
|
||||||
|
if (term_y + term_height > scr_height)
|
||||||
|
term_y = scr_height - term_height;
|
||||||
|
|
||||||
|
/* Write down corrected data. */
|
||||||
|
view->terminal_rect.x = (unsigned int) term_x;
|
||||||
|
view->terminal_rect.y = (unsigned int) term_y;
|
||||||
|
view->terminal_rect.width = (unsigned int) term_width;
|
||||||
|
view->terminal_rect.height = (unsigned int) term_height;
|
||||||
|
view->terminal_border = border_width;
|
||||||
|
|
||||||
|
view->need_to_check_sanity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_terminal (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_font_t terminal_font;
|
||||||
|
|
||||||
|
terminal_font = grub_font_get (view->terminal_font_name);
|
||||||
|
if (!terminal_font)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that terminal window size and position are sane. */
|
||||||
|
terminal_sanity_check (view);
|
||||||
|
|
||||||
|
term_view = view;
|
||||||
|
|
||||||
|
/* Note: currently there is no API for changing the gfxterm font
|
||||||
|
on the fly, so whatever font the initially loaded theme specifies
|
||||||
|
will be permanent. */
|
||||||
|
grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
|
||||||
|
view->terminal_rect.x,
|
||||||
|
view->terminal_rect.y,
|
||||||
|
view->terminal_rect.width,
|
||||||
|
view->terminal_rect.height,
|
||||||
|
view->double_repaint,
|
||||||
|
terminal_font,
|
||||||
|
view->terminal_border);
|
||||||
|
grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_background (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (view->scaled_desktop_image || (!view->raw_desktop_image))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct grub_video_bitmap *scaled_bitmap;
|
||||||
|
if (view->desktop_image_scale_method ==
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH)
|
||||||
|
grub_video_bitmap_create_scaled (&scaled_bitmap,
|
||||||
|
view->screen.width,
|
||||||
|
view->screen.height,
|
||||||
|
view->raw_desktop_image,
|
||||||
|
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
|
||||||
|
else
|
||||||
|
grub_video_bitmap_scale_proportional (&scaled_bitmap,
|
||||||
|
view->screen.width,
|
||||||
|
view->screen.height,
|
||||||
|
view->raw_desktop_image,
|
||||||
|
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST,
|
||||||
|
view->desktop_image_scale_method,
|
||||||
|
view->desktop_image_v_align,
|
||||||
|
view->desktop_image_h_align);
|
||||||
|
if (! scaled_bitmap)
|
||||||
|
return;
|
||||||
|
view->scaled_desktop_image = scaled_bitmap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: previously notifications were displayed in special case.
|
||||||
|
Is it necessary?
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
/* Sets MESSAGE as the progress message for the view.
|
||||||
|
MESSAGE can be 0, in which case no message is displayed. */
|
||||||
|
static void
|
||||||
|
set_progress_message (grub_gfxmenu_view_t view, const char *message)
|
||||||
|
{
|
||||||
|
grub_free (view->progress_message_text);
|
||||||
|
if (message)
|
||||||
|
view->progress_message_text = grub_strdup (message);
|
||||||
|
else
|
||||||
|
view->progress_message_text = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_booting (grub_menu_entry_t entry, void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
|
||||||
|
|
||||||
|
char *s = grub_malloc (100 + grub_strlen (entry->title));
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_sprintf (s, "Booting '%s'", entry->title);
|
||||||
|
set_progress_message (view, s);
|
||||||
|
grub_free (s);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_fallback (grub_menu_entry_t entry, void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
|
||||||
|
|
||||||
|
char *s = grub_malloc (100 + grub_strlen (entry->title));
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_sprintf (s, "Falling back to '%s'", entry->title);
|
||||||
|
set_progress_message (view, s);
|
||||||
|
grub_free (s);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_execution_failure (void *userdata __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct grub_menu_execute_callback execute_callback =
|
||||||
|
{
|
||||||
|
.notify_booting = notify_booting,
|
||||||
|
.notify_fallback = notify_fallback,
|
||||||
|
.notify_failure = notify_execution_failure
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -964,3 +964,20 @@ void * grub_efi_allocate_iso_buf(grub_uint64_t size)
|
|||||||
|
|
||||||
return (void *)(unsigned long)address;
|
return (void *)(unsigned long)address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * grub_efi_allocate_chain_buf(grub_uint64_t size)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_physical_address_t address = 0;
|
||||||
|
grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size);
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_LOADER_DATA, pages, &address);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)(unsigned long)address;
|
||||||
|
}
|
||||||
|
|||||||
672
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c
Normal file
672
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c
Normal file
@@ -0,0 +1,672 @@
|
|||||||
|
/* mm.c - generic EFI memory management */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2006,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/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/cpu/efi/memory.h>
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
#include <grub/pci.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
|
||||||
|
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||||
|
|
||||||
|
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||||
|
#define BYTES_TO_PAGES_DOWN(bytes) ((bytes) >> 12)
|
||||||
|
#define PAGES_TO_BYTES(pages) ((pages) << 12)
|
||||||
|
|
||||||
|
/* The size of a memory map obtained from the firmware. This must be
|
||||||
|
a multiplier of 4KB. */
|
||||||
|
#define MEMORY_MAP_SIZE 0x3000
|
||||||
|
|
||||||
|
/* The minimum and maximum heap size for GRUB itself. */
|
||||||
|
#define MIN_HEAP_SIZE 0x100000
|
||||||
|
#define MAX_HEAP_SIZE (1600 * 0x100000)
|
||||||
|
|
||||||
|
static void *finish_mmap_buf = 0;
|
||||||
|
static grub_efi_uintn_t finish_mmap_size = 0;
|
||||||
|
static grub_efi_uintn_t finish_key = 0;
|
||||||
|
static grub_efi_uintn_t finish_desc_size;
|
||||||
|
static grub_efi_uint32_t finish_desc_version;
|
||||||
|
int grub_efi_is_finished = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to roll back EFI allocations on exit. Remember allocations that
|
||||||
|
* we'll free on exit.
|
||||||
|
*/
|
||||||
|
struct efi_allocation;
|
||||||
|
struct efi_allocation {
|
||||||
|
grub_efi_physical_address_t address;
|
||||||
|
grub_efi_uint64_t pages;
|
||||||
|
struct efi_allocation *next;
|
||||||
|
};
|
||||||
|
static struct efi_allocation *efi_allocated_memory;
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_store_alloc (grub_efi_physical_address_t address,
|
||||||
|
grub_efi_uintn_t pages)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
struct efi_allocation *alloc;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
|
||||||
|
sizeof(*alloc), (void**)&alloc);
|
||||||
|
|
||||||
|
if (status == GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
alloc->next = efi_allocated_memory;
|
||||||
|
alloc->address = address;
|
||||||
|
alloc->pages = pages;
|
||||||
|
efi_allocated_memory = alloc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
grub_printf ("Could not malloc memory to remember EFI allocation. "
|
||||||
|
"Exiting GRUB won't free all memory.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_drop_alloc (grub_efi_physical_address_t address,
|
||||||
|
grub_efi_uintn_t pages)
|
||||||
|
{
|
||||||
|
struct efi_allocation *ea, *eap;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
|
||||||
|
for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next)
|
||||||
|
{
|
||||||
|
if (ea->address != address || ea->pages != pages)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Remove the current entry from the list. */
|
||||||
|
if (eap)
|
||||||
|
eap->next = ea->next;
|
||||||
|
else
|
||||||
|
efi_allocated_memory = ea->next;
|
||||||
|
|
||||||
|
/* Then free the memory backing it. */
|
||||||
|
efi_call_1 (b->free_pool, ea);
|
||||||
|
|
||||||
|
/* And leave, we're done. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate pages. Return the pointer to the first of allocated pages. */
|
||||||
|
void *
|
||||||
|
grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
grub_efi_uintn_t pages,
|
||||||
|
grub_efi_allocate_type_t alloctype,
|
||||||
|
grub_efi_memory_type_t memtype)
|
||||||
|
{
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||||
|
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (address == 0)
|
||||||
|
{
|
||||||
|
/* Uggh, the address 0 was allocated... This is too annoying,
|
||||||
|
so reallocate another one. */
|
||||||
|
address = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||||
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
grub_efi_free_pages (0, pages);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_efi_store_alloc (address, pages);
|
||||||
|
|
||||||
|
return (void *) ((grub_addr_t) address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_efi_allocate_any_pages (grub_efi_uintn_t pages)
|
||||||
|
{
|
||||||
|
return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS,
|
||||||
|
pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||||
|
GRUB_EFI_LOADER_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_efi_allocate_fixed (grub_efi_physical_address_t address,
|
||||||
|
grub_efi_uintn_t pages)
|
||||||
|
{
|
||||||
|
return grub_efi_allocate_pages_real (address, pages,
|
||||||
|
GRUB_EFI_ALLOCATE_ADDRESS,
|
||||||
|
GRUB_EFI_LOADER_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free pages starting from ADDRESS. */
|
||||||
|
void
|
||||||
|
grub_efi_free_pages (grub_efi_physical_address_t address,
|
||||||
|
grub_efi_uintn_t pages)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
efi_call_2 (b->free_pages, address, pages);
|
||||||
|
|
||||||
|
grub_efi_drop_alloc (address, pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
|
||||||
|
/* Helper for stop_broadcom. */
|
||||||
|
static int
|
||||||
|
find_card (grub_pci_device_t dev, grub_pci_id_t pciid,
|
||||||
|
void *data __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
grub_pci_address_t addr;
|
||||||
|
grub_uint8_t cap;
|
||||||
|
grub_uint16_t pm_state;
|
||||||
|
|
||||||
|
if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
|
||||||
|
if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
|
||||||
|
return 0;
|
||||||
|
cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
|
||||||
|
if (!cap)
|
||||||
|
return 0;
|
||||||
|
addr = grub_pci_make_address (dev, cap + 4);
|
||||||
|
pm_state = grub_pci_read_word (addr);
|
||||||
|
pm_state = pm_state | 0x03;
|
||||||
|
grub_pci_write_word (addr, pm_state);
|
||||||
|
grub_pci_read_word (addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_broadcom (void)
|
||||||
|
{
|
||||||
|
grub_pci_iterate (find_card, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
|
||||||
|
grub_efi_uintn_t *map_key,
|
||||||
|
grub_efi_uintn_t *efi_desc_size,
|
||||||
|
grub_efi_uint32_t *efi_desc_version)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
|
||||||
|
int is_apple;
|
||||||
|
|
||||||
|
is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor,
|
||||||
|
apple, sizeof (apple)) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
|
||||||
|
&finish_desc_size, &finish_desc_version) < 0)
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||||
|
|
||||||
|
if (outbuf && *outbuf_size < finish_mmap_size)
|
||||||
|
return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
|
||||||
|
|
||||||
|
finish_mmap_buf = grub_malloc (finish_mmap_size);
|
||||||
|
if (!finish_mmap_buf)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
|
||||||
|
&finish_desc_size, &finish_desc_version) <= 0)
|
||||||
|
{
|
||||||
|
grub_free (finish_mmap_buf);
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||||
|
}
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
|
||||||
|
finish_key);
|
||||||
|
if (status == GRUB_EFI_SUCCESS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (status != GRUB_EFI_INVALID_PARAMETER)
|
||||||
|
{
|
||||||
|
grub_free (finish_mmap_buf);
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free (finish_mmap_buf);
|
||||||
|
grub_printf ("Trying to terminate EFI services again\n");
|
||||||
|
}
|
||||||
|
grub_efi_is_finished = 1;
|
||||||
|
if (outbuf_size)
|
||||||
|
*outbuf_size = finish_mmap_size;
|
||||||
|
if (outbuf)
|
||||||
|
grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
|
||||||
|
if (map_key)
|
||||||
|
*map_key = finish_key;
|
||||||
|
if (efi_desc_size)
|
||||||
|
*efi_desc_size = finish_desc_size;
|
||||||
|
if (efi_desc_version)
|
||||||
|
*efi_desc_version = finish_desc_version;
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
if (is_apple)
|
||||||
|
stop_broadcom ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To obtain the UEFI memory map, we must pass a buffer of sufficient size
|
||||||
|
* to hold the entire map. This function returns a sane start value for
|
||||||
|
* buffer size.
|
||||||
|
*/
|
||||||
|
grub_efi_uintn_t
|
||||||
|
grub_efi_find_mmap_size (void)
|
||||||
|
{
|
||||||
|
grub_efi_uintn_t mmap_size = 0;
|
||||||
|
grub_efi_uintn_t desc_size;
|
||||||
|
|
||||||
|
if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "cannot get EFI memory map size");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an extra page, since UEFI can alter the memory map itself on
|
||||||
|
* callbacks or explicit calls, including console output.
|
||||||
|
*/
|
||||||
|
return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
|
||||||
|
return 0 if partial, or return -1 if an error occurs. */
|
||||||
|
int
|
||||||
|
grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t *map_key,
|
||||||
|
grub_efi_uintn_t *descriptor_size,
|
||||||
|
grub_efi_uint32_t *descriptor_version)
|
||||||
|
{
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_uintn_t key;
|
||||||
|
grub_efi_uint32_t version;
|
||||||
|
grub_efi_uintn_t size;
|
||||||
|
|
||||||
|
if (grub_efi_is_finished)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
if (*memory_map_size < finish_mmap_size)
|
||||||
|
{
|
||||||
|
grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
*memory_map_size = finish_mmap_size;
|
||||||
|
if (map_key)
|
||||||
|
*map_key = finish_key;
|
||||||
|
if (descriptor_size)
|
||||||
|
*descriptor_size = finish_desc_size;
|
||||||
|
if (descriptor_version)
|
||||||
|
*descriptor_version = finish_desc_version;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow some parameters to be missing. */
|
||||||
|
if (! map_key)
|
||||||
|
map_key = &key;
|
||||||
|
if (! descriptor_version)
|
||||||
|
descriptor_version = &version;
|
||||||
|
if (! descriptor_size)
|
||||||
|
descriptor_size = &size;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
|
||||||
|
descriptor_size, descriptor_version);
|
||||||
|
if (*descriptor_size == 0)
|
||||||
|
*descriptor_size = sizeof (grub_efi_memory_descriptor_t);
|
||||||
|
if (status == GRUB_EFI_SUCCESS)
|
||||||
|
return 1;
|
||||||
|
else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the memory map in place. */
|
||||||
|
static void
|
||||||
|
sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t desc_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *d1;
|
||||||
|
grub_efi_memory_descriptor_t *d2;
|
||||||
|
|
||||||
|
for (d1 = memory_map;
|
||||||
|
d1 < memory_map_end;
|
||||||
|
d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *max_desc = d1;
|
||||||
|
|
||||||
|
for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
|
||||||
|
d2 < memory_map_end;
|
||||||
|
d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
|
||||||
|
{
|
||||||
|
if (max_desc->num_pages < d2->num_pages)
|
||||||
|
max_desc = d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_desc != d1)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t tmp;
|
||||||
|
|
||||||
|
tmp = *d1;
|
||||||
|
*d1 = *max_desc;
|
||||||
|
*max_desc = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter the descriptors. GRUB needs only available memory. */
|
||||||
|
static grub_efi_memory_descriptor_t *
|
||||||
|
filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_memory_descriptor_t *filtered_memory_map,
|
||||||
|
grub_efi_uintn_t desc_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
grub_efi_memory_descriptor_t *filtered_desc;
|
||||||
|
|
||||||
|
for (desc = memory_map, filtered_desc = filtered_memory_map;
|
||||||
|
desc < memory_map_end;
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
|
||||||
|
#if 1
|
||||||
|
&& desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
|
||||||
|
#endif
|
||||||
|
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
|
||||||
|
&& desc->num_pages != 0)
|
||||||
|
{
|
||||||
|
grub_memcpy (filtered_desc, desc, desc_size);
|
||||||
|
|
||||||
|
/* Avoid less than 1MB, because some loaders seem to be confused. */
|
||||||
|
if (desc->physical_start < 0x100000)
|
||||||
|
{
|
||||||
|
desc->num_pages -= BYTES_TO_PAGES (0x100000
|
||||||
|
- desc->physical_start);
|
||||||
|
desc->physical_start = 0x100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (BYTES_TO_PAGES (filtered_desc->physical_start)
|
||||||
|
+ filtered_desc->num_pages
|
||||||
|
> BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
|
||||||
|
filtered_desc->num_pages
|
||||||
|
= (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
- BYTES_TO_PAGES (filtered_desc->physical_start));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (filtered_desc->num_pages == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the total number of pages. */
|
||||||
|
static grub_efi_uint64_t
|
||||||
|
get_total_pages (grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t desc_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
grub_efi_uint64_t total = 0;
|
||||||
|
|
||||||
|
for (desc = memory_map;
|
||||||
|
desc < memory_map_end;
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
total += desc->num_pages;
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add memory regions. */
|
||||||
|
static void
|
||||||
|
add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t desc_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end,
|
||||||
|
grub_efi_uint64_t required_pages)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
|
||||||
|
for (desc = memory_map;
|
||||||
|
desc < memory_map_end;
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
grub_efi_uint64_t pages;
|
||||||
|
grub_efi_physical_address_t start;
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
start = desc->physical_start;
|
||||||
|
pages = desc->num_pages;
|
||||||
|
if (pages > required_pages)
|
||||||
|
{
|
||||||
|
start += PAGES_TO_BYTES (pages - required_pages);
|
||||||
|
pages = required_pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = grub_efi_allocate_pages_real (start, pages,
|
||||||
|
GRUB_EFI_ALLOCATE_ADDRESS,
|
||||||
|
GRUB_EFI_LOADER_CODE);
|
||||||
|
if (! addr)
|
||||||
|
grub_fatal ("cannot allocate conventional memory %p with %u pages",
|
||||||
|
(void *) ((grub_addr_t) start),
|
||||||
|
(unsigned) pages);
|
||||||
|
|
||||||
|
grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
|
||||||
|
|
||||||
|
required_pages -= pages;
|
||||||
|
if (required_pages == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (required_pages > 0)
|
||||||
|
grub_fatal ("too little memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_memory_fini (void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Free all stale allocations. grub_efi_free_pages() will remove
|
||||||
|
* the found entry from the list and it will always find the first
|
||||||
|
* list entry (efi_allocated_memory is the list start). Hence we
|
||||||
|
* remove all entries from the list until none is left altogether.
|
||||||
|
*/
|
||||||
|
while (efi_allocated_memory)
|
||||||
|
grub_efi_free_pages (efi_allocated_memory->address,
|
||||||
|
efi_allocated_memory->pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Print the memory map. */
|
||||||
|
static void
|
||||||
|
print_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t desc_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (desc = memory_map, i = 0;
|
||||||
|
desc < memory_map_end;
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
|
||||||
|
{
|
||||||
|
grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n",
|
||||||
|
desc->type, desc->physical_start, desc->virtual_start,
|
||||||
|
desc->num_pages, desc->attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_mm_init (void)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *memory_map;
|
||||||
|
grub_efi_memory_descriptor_t *memory_map_end;
|
||||||
|
grub_efi_memory_descriptor_t *filtered_memory_map;
|
||||||
|
grub_efi_memory_descriptor_t *filtered_memory_map_end;
|
||||||
|
grub_efi_uintn_t map_size;
|
||||||
|
grub_efi_uintn_t desc_size;
|
||||||
|
grub_efi_uint64_t total_pages;
|
||||||
|
grub_efi_uint64_t required_pages;
|
||||||
|
int mm_status;
|
||||||
|
|
||||||
|
/* Prepare a memory region to store two memory maps. */
|
||||||
|
memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||||
|
if (! memory_map)
|
||||||
|
grub_fatal ("cannot allocate memory");
|
||||||
|
|
||||||
|
/* Obtain descriptors for available memory. */
|
||||||
|
map_size = MEMORY_MAP_SIZE;
|
||||||
|
|
||||||
|
mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0);
|
||||||
|
|
||||||
|
if (mm_status == 0)
|
||||||
|
{
|
||||||
|
grub_efi_free_pages
|
||||||
|
((grub_efi_physical_address_t) ((grub_addr_t) memory_map),
|
||||||
|
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||||
|
|
||||||
|
/* Freeing/allocating operations may increase memory map size. */
|
||||||
|
map_size += desc_size * 32;
|
||||||
|
|
||||||
|
memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size));
|
||||||
|
if (! memory_map)
|
||||||
|
grub_fatal ("cannot allocate memory");
|
||||||
|
|
||||||
|
mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0,
|
||||||
|
&desc_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mm_status < 0)
|
||||||
|
grub_fatal ("cannot get memory map");
|
||||||
|
|
||||||
|
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
|
||||||
|
|
||||||
|
filtered_memory_map = memory_map_end;
|
||||||
|
|
||||||
|
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
|
||||||
|
desc_size, memory_map_end);
|
||||||
|
|
||||||
|
/* By default, request a quarter of the available memory. */
|
||||||
|
total_pages = get_total_pages (filtered_memory_map, desc_size,
|
||||||
|
filtered_memory_map_end);
|
||||||
|
|
||||||
|
#if defined (__mips__) && (_MIPS_SIM == _ABI64)
|
||||||
|
required_pages = (total_pages > 4096) ? (total_pages - 4096) : (total_pages >> 1);
|
||||||
|
#else
|
||||||
|
required_pages = (total_pages >> 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
|
||||||
|
required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
|
||||||
|
else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
|
||||||
|
required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
|
||||||
|
|
||||||
|
/* Sort the filtered descriptors, so that GRUB can allocate pages
|
||||||
|
from smaller regions. */
|
||||||
|
sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
|
||||||
|
|
||||||
|
/* Allocate memory regions for GRUB's memory management. */
|
||||||
|
add_memory_regions (filtered_memory_map, desc_size,
|
||||||
|
filtered_memory_map_end, required_pages);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* For debug. */
|
||||||
|
map_size = MEMORY_MAP_SIZE;
|
||||||
|
|
||||||
|
if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
|
||||||
|
grub_fatal ("cannot get memory map");
|
||||||
|
|
||||||
|
grub_printf ("printing memory map\n");
|
||||||
|
print_memory_map (memory_map, desc_size,
|
||||||
|
NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
|
||||||
|
grub_fatal ("Debug. ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Release the memory maps. */
|
||||||
|
grub_efi_free_pages ((grub_addr_t) memory_map,
|
||||||
|
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
|
||||||
|
grub_err_t
|
||||||
|
grub_efi_get_ram_base(grub_addr_t *base_addr)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *memory_map, *desc;
|
||||||
|
grub_efi_uintn_t memory_map_size, desc_size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memory_map_size = grub_efi_find_mmap_size();
|
||||||
|
|
||||||
|
memory_map = grub_malloc (memory_map_size);
|
||||||
|
if (! memory_map)
|
||||||
|
return GRUB_ERR_OUT_OF_MEMORY;
|
||||||
|
ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL,
|
||||||
|
&desc_size, NULL);
|
||||||
|
|
||||||
|
if (ret < 1)
|
||||||
|
return GRUB_ERR_BUG;
|
||||||
|
|
||||||
|
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||||
|
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
if (desc->attribute & GRUB_EFI_MEMORY_WB)
|
||||||
|
*base_addr = grub_min (*base_addr, desc->physical_start);
|
||||||
|
|
||||||
|
grub_free(memory_map);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -106,20 +106,135 @@ int ventoy_check_file_exist(const char * fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct grub_vlnk
|
||||||
|
{
|
||||||
|
int srclen;
|
||||||
|
char src[512];
|
||||||
|
char dst[512];
|
||||||
|
struct grub_vlnk *next;
|
||||||
|
}grub_vlnk;
|
||||||
|
|
||||||
|
static grub_vlnk g_vtoy_vlnk;
|
||||||
|
static grub_vlnk *g_vlnk_list;
|
||||||
|
|
||||||
|
int grub_file_is_vlnk_suffix(const char *name, int len)
|
||||||
|
{
|
||||||
|
grub_uint32_t suffix;
|
||||||
|
|
||||||
|
if (len > 9)
|
||||||
|
{
|
||||||
|
suffix = *(grub_uint32_t *)(name + len - 4);
|
||||||
|
if (grub_strncmp(name + len - 9, ".vlnk.", 6) == 0)
|
||||||
|
{
|
||||||
|
/* .iso .wim .img .vhd .efi .dat */
|
||||||
|
if (suffix == 0x6F73692E || suffix == 0x6D69772E ||
|
||||||
|
suffix == 0x676D692E || suffix == 0x6468762E ||
|
||||||
|
suffix == 0x6966652E || suffix == 0x7461642E)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len > 10 && grub_strncmp(name + len - 10, ".vlnk.", 6) == 0)
|
||||||
|
{
|
||||||
|
/* vhdx vtoy */
|
||||||
|
if (suffix == 0x78646876 || suffix == 0x796F7476)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int grub_file_vtoy_vlnk(const char *src, const char *dst)
|
||||||
|
{
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
g_vtoy_vlnk.srclen = (int)grub_strlen(src);
|
||||||
|
grub_strncpy(g_vtoy_vlnk.src, src, sizeof(g_vtoy_vlnk.src) - 1);
|
||||||
|
grub_strncpy(g_vtoy_vlnk.dst, dst, sizeof(g_vtoy_vlnk.dst) - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_vtoy_vlnk.srclen = 0;
|
||||||
|
g_vtoy_vlnk.src[0] = 0;
|
||||||
|
g_vtoy_vlnk.dst[0] = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int grub_file_add_vlnk(const char *src, const char *dst)
|
||||||
|
{
|
||||||
|
grub_vlnk *node = NULL;
|
||||||
|
|
||||||
|
if (src && dst)
|
||||||
|
{
|
||||||
|
node = grub_zalloc(sizeof(grub_vlnk));
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->srclen = (int)grub_strlen(src);
|
||||||
|
grub_strncpy(node->src, src, sizeof(node->src) - 1);
|
||||||
|
grub_strncpy(node->dst, dst, sizeof(node->dst) - 1);
|
||||||
|
|
||||||
|
node->next = g_vlnk_list;
|
||||||
|
g_vlnk_list = node;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *grub_file_get_vlnk(const char *name, int *vlnk)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
grub_vlnk *node = g_vlnk_list;
|
||||||
|
|
||||||
|
len = grub_strlen(name);
|
||||||
|
|
||||||
|
if (!grub_file_is_vlnk_suffix(name, len))
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == g_vtoy_vlnk.srclen && grub_strcmp(name, g_vtoy_vlnk.src) == 0)
|
||||||
|
{
|
||||||
|
*vlnk = 1;
|
||||||
|
return g_vtoy_vlnk.dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
if (node->srclen == len && grub_strcmp(name, node->src) == 0)
|
||||||
|
{
|
||||||
|
*vlnk = 1;
|
||||||
|
return node->dst;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
grub_file_t
|
grub_file_t
|
||||||
grub_file_open (const char *name, enum grub_file_type type)
|
grub_file_open (const char *name, enum grub_file_type type)
|
||||||
{
|
{
|
||||||
|
int vlnk = 0;
|
||||||
grub_device_t device = 0;
|
grub_device_t device = 0;
|
||||||
grub_file_t file = 0, last_file = 0;
|
grub_file_t file = 0, last_file = 0;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
const char *file_name;
|
const char *file_name;
|
||||||
grub_file_filter_id_t filter;
|
grub_file_filter_id_t filter;
|
||||||
|
|
||||||
/* <DESC> : mem:xxx:size:xxx format in chainloader */
|
/* <DESC> : mem:xxx:size:xxx format in chainloader grub_strlen(GRUB_MEMFILE_MEM) */
|
||||||
if (grub_strncmp(name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) {
|
if (grub_strncmp(name, GRUB_MEMFILE_MEM, 4) == 0) {
|
||||||
return grub_memfile_open(name);
|
return grub_memfile_open(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((g_vlnk_list || g_vtoy_vlnk.srclen) && (type & GRUB_FILE_TYPE_NO_VLNK) == 0)
|
||||||
|
name = grub_file_get_vlnk(name, &vlnk);
|
||||||
|
|
||||||
device_name = grub_file_get_device_name (name);
|
device_name = grub_file_get_device_name (name);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -141,6 +256,7 @@ grub_file_open (const char *name, enum grub_file_type type)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
file->device = device;
|
file->device = device;
|
||||||
|
file->vlnk = vlnk;
|
||||||
|
|
||||||
/* In case of relative pathnames and non-Unix systems (like Windows)
|
/* In case of relative pathnames and non-Unix systems (like Windows)
|
||||||
* name of host files may not start with `/'. Blocklists for host files
|
* name of host files may not start with `/'. Blocklists for host files
|
||||||
|
|||||||
@@ -42,6 +42,44 @@ probe_dummy_iter (const char *filename __attribute__ ((unused)),
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_fs_t grub_fs_list_probe(grub_device_t device, const char **list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
grub_fs_t p;
|
||||||
|
|
||||||
|
if (!device->disk)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (p = grub_fs_list; p; p = p->next)
|
||||||
|
{
|
||||||
|
for (i = 0; list[i]; i++)
|
||||||
|
{
|
||||||
|
if (grub_strcmp(p->name, list[i]) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
grub_dprintf("fs", "Detecting %s...\n", p->name);
|
||||||
|
|
||||||
|
(p->fs_dir) (device, "/", probe_dummy_iter, NULL);
|
||||||
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
return p;
|
||||||
|
|
||||||
|
grub_error_push ();
|
||||||
|
grub_dprintf ("fs", "%s detection failed.\n", p->name);
|
||||||
|
grub_error_pop ();
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_BAD_FS && grub_errno != GRUB_ERR_OUT_OF_RANGE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
grub_fs_t
|
grub_fs_t
|
||||||
grub_fs_probe (grub_device_t device)
|
grub_fs_probe (grub_device_t device)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,6 +109,52 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
|
|||||||
return grub_strdup (val);
|
return grub_strdup (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int g_ventoy_hook_root = 0;
|
||||||
|
void ventoy_env_hook_root(int hook)
|
||||||
|
{
|
||||||
|
g_ventoy_hook_root = hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ventoy_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
|
||||||
|
const char *val)
|
||||||
|
{
|
||||||
|
const char *pos = val;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (g_ventoy_hook_root == 0)
|
||||||
|
{
|
||||||
|
return grub_env_write_root(var, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos[0] == '(')
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(pos, "vtimghd", 7) == 0)
|
||||||
|
{
|
||||||
|
return grub_env_write_root(var, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = grub_strchr(val, ',');
|
||||||
|
if (!pos)
|
||||||
|
{
|
||||||
|
return grub_env_write_root(var, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val[0] == '(')
|
||||||
|
{
|
||||||
|
grub_snprintf(buf, sizeof(buf), "(vtimghd%s", pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_snprintf(buf, sizeof(buf), "vtimghd%s", pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return grub_env_write_root(var, buf);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_set_prefix_and_root (void)
|
grub_set_prefix_and_root (void)
|
||||||
{
|
{
|
||||||
@@ -123,7 +169,7 @@ grub_set_prefix_and_root (void)
|
|||||||
if (header->type == OBJ_TYPE_PREFIX)
|
if (header->type == OBJ_TYPE_PREFIX)
|
||||||
prefix = (char *) header + sizeof (struct grub_module_header);
|
prefix = (char *) header + sizeof (struct grub_module_header);
|
||||||
|
|
||||||
grub_register_variable_hook ("root", 0, grub_env_write_root);
|
grub_register_variable_hook ("root", 0, ventoy_env_write_root);
|
||||||
|
|
||||||
grub_machine_get_bootlocation (&fwdevice, &fwpath);
|
grub_machine_get_bootlocation (&fwdevice, &fwpath);
|
||||||
|
|
||||||
|
|||||||
23
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S
Normal file
23
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2017 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/symbol.h>
|
||||||
|
|
||||||
|
FUNCTION (grub_arch_sync_caches)
|
||||||
|
jr.hb $ra
|
||||||
|
|
||||||
150
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c
Normal file
150
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/* dl-mips64.c - arch-dependent part of loadable module support */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2002,2005,2007,2009,2017 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/elf.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/cpu/types.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
/* Check if EHDR is a valid ELF header. */
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_check_header (void *ehdr)
|
||||||
|
{
|
||||||
|
Elf_Ehdr *e = ehdr;
|
||||||
|
|
||||||
|
/* Check the magic numbers. */
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
if (e->e_ident[EI_CLASS] != ELFCLASS64
|
||||||
|
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|
||||||
|
|| e->e_machine != EM_MIPS)
|
||||||
|
#else
|
||||||
|
if (e->e_ident[EI_CLASS] != ELFCLASS64
|
||||||
|
|| e->e_ident[EI_DATA] != ELFDATA2LSB
|
||||||
|
|| e->e_machine != EM_MIPS)
|
||||||
|
#endif
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
|
||||||
|
grub_size_t *tramp, grub_size_t *got)
|
||||||
|
{
|
||||||
|
*tramp = 0;
|
||||||
|
*got = 0;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Relocate symbols. */
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||||
|
Elf_Shdr *s, grub_dl_segment_t seg)
|
||||||
|
{
|
||||||
|
Elf_Ehdr *e = ehdr;
|
||||||
|
Elf_Rel *rel, *max;
|
||||||
|
|
||||||
|
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
|
||||||
|
max = (Elf_Rel *) ((char *) rel + s->sh_size);
|
||||||
|
rel < max;
|
||||||
|
rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
|
||||||
|
{
|
||||||
|
grub_uint8_t *addr;
|
||||||
|
Elf_Sym *sym;
|
||||||
|
Elf_Addr r_info;
|
||||||
|
grub_uint64_t sym_value;
|
||||||
|
|
||||||
|
if (seg->size < rel->r_offset)
|
||||||
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
|
"reloc offset is out of the segment");
|
||||||
|
|
||||||
|
r_info = ((grub_uint64_t) rel->r_info << 32) |
|
||||||
|
(grub_uint32_t) grub_be_to_cpu64 (rel->r_info);
|
||||||
|
|
||||||
|
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
|
||||||
|
sym = (Elf_Sym *) ((char *) mod->symtab
|
||||||
|
+ mod->symsize * ELF_R_SYM (r_info));
|
||||||
|
sym_value = sym->st_value;
|
||||||
|
if (s->sh_type == SHT_RELA)
|
||||||
|
{
|
||||||
|
sym_value += ((Elf_Rela *) rel)->r_addend;
|
||||||
|
}
|
||||||
|
switch (ELF_R_TYPE (r_info))
|
||||||
|
{
|
||||||
|
case R_MIPS_64:
|
||||||
|
*(grub_uint64_t *) addr += sym_value;
|
||||||
|
break;
|
||||||
|
case R_MIPS_32:
|
||||||
|
*(grub_uint32_t *) addr += sym_value;
|
||||||
|
break;
|
||||||
|
case R_MIPS_26:
|
||||||
|
{
|
||||||
|
grub_uint32_t value;
|
||||||
|
grub_uint32_t raw;
|
||||||
|
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
|
||||||
|
value = raw << 2;
|
||||||
|
value += sym_value;
|
||||||
|
raw = (value >> 2) & 0x3ffffff;
|
||||||
|
|
||||||
|
*(grub_uint32_t *) addr =
|
||||||
|
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R_MIPS_LO16:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
*(grub_uint16_t *) addr = (grub_int16_t) sym_value;
|
||||||
|
break;
|
||||||
|
case R_MIPS_HI16:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
*(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x8000UL) >> 16);
|
||||||
|
break;
|
||||||
|
case R_MIPS_HIGHER:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
*(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x80008000UL) >> 32);
|
||||||
|
break;
|
||||||
|
case R_MIPS_HIGHEST:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
*(grub_uint16_t *) addr = (grub_uint16_t) ((sym_value + 0x800080008000UL) >> 48);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
N_("relocation 0x%x is not implemented yet"),
|
||||||
|
ELF_R_TYPE (r_info));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
85
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c
Normal file
85
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* init.c - initialize an arm-based EFI system */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/cpu/time.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/machine/loongson.h>
|
||||||
|
|
||||||
|
static grub_uint64_t tmr;
|
||||||
|
static grub_efi_event_t tmr_evt;
|
||||||
|
|
||||||
|
static grub_uint64_t
|
||||||
|
grub_efi_get_time_ms (void)
|
||||||
|
{
|
||||||
|
return tmr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)),
|
||||||
|
void *context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
tmr += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_init (void)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
grub_efi_init ();
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL,
|
||||||
|
GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt);
|
||||||
|
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000);
|
||||||
|
|
||||||
|
grub_install_get_time_ms (grub_efi_get_time_ms);
|
||||||
|
|
||||||
|
if (grub_efi_is_loongson ())
|
||||||
|
grub_efi_loongson_init ();
|
||||||
|
else
|
||||||
|
/* FIXME: Get cpuclock from EFI. */
|
||||||
|
grub_timer_init (1000000000U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_fini (int flags)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_NORETURN))
|
||||||
|
return;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
|
||||||
|
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0);
|
||||||
|
efi_call_1 (b->close_event, tmr_evt);
|
||||||
|
|
||||||
|
if (grub_efi_is_loongson ())
|
||||||
|
grub_efi_loongson_fini ();
|
||||||
|
grub_efi_fini ();
|
||||||
|
}
|
||||||
33
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c
Normal file
33
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2017 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/efi/efi.h>
|
||||||
|
#include <grub/cpu/time.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
#include <grub/machine/loongson.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_loongson_init (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_loongson_fini (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
47
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S
Normal file
47
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/symbol.h>
|
||||||
|
|
||||||
|
.file "startup.S"
|
||||||
|
.text
|
||||||
|
|
||||||
|
.set push
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
FUNCTION(_start)
|
||||||
|
/*
|
||||||
|
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0.
|
||||||
|
*/
|
||||||
|
daddiu $sp, -16
|
||||||
|
sd $ra, ($sp)
|
||||||
|
|
||||||
|
dla $a2, grub_efi_image_handle
|
||||||
|
sd $a0, ($a2)
|
||||||
|
dla $a2, grub_efi_system_table
|
||||||
|
sd $a1, ($a2)
|
||||||
|
|
||||||
|
jal grub_main
|
||||||
|
|
||||||
|
1:
|
||||||
|
ld $ra, ($sp)
|
||||||
|
daddiu $sp, 16
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.set pop
|
||||||
|
|
||||||
47
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c
Normal file
47
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2017 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/kernel.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/cpu/mips.h>
|
||||||
|
|
||||||
|
grub_uint32_t grub_arch_cpuclock;
|
||||||
|
|
||||||
|
/* FIXME: use interrupt to count high. */
|
||||||
|
grub_uint64_t
|
||||||
|
grub_get_rtc (void)
|
||||||
|
{
|
||||||
|
static grub_uint32_t high = 0;
|
||||||
|
static grub_uint32_t last = 0;
|
||||||
|
grub_uint32_t low;
|
||||||
|
|
||||||
|
asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low));
|
||||||
|
if (low < last)
|
||||||
|
high++;
|
||||||
|
last = low;
|
||||||
|
|
||||||
|
return (((grub_uint64_t) high) << 32) | low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_timer_init (grub_uint32_t cpuclock)
|
||||||
|
{
|
||||||
|
grub_arch_cpuclock = cpuclock;
|
||||||
|
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||||
|
}
|
||||||
133
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c
Normal file
133
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2002,2003,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/term.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
|
||||||
|
struct grub_term_output *grub_term_outputs_disabled;
|
||||||
|
struct grub_term_input *grub_term_inputs_disabled;
|
||||||
|
struct grub_term_output *grub_term_outputs;
|
||||||
|
struct grub_term_input *grub_term_inputs;
|
||||||
|
|
||||||
|
/* Current color state. */
|
||||||
|
grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR;
|
||||||
|
grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR;
|
||||||
|
|
||||||
|
void (*grub_term_poll_usb) (int wait_for_completion) = NULL;
|
||||||
|
void (*grub_net_poll_cards_idle) (void) = NULL;
|
||||||
|
|
||||||
|
/* Put a Unicode character. */
|
||||||
|
static void
|
||||||
|
grub_putcode_dumb (grub_uint32_t code,
|
||||||
|
struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c =
|
||||||
|
{
|
||||||
|
.base = code,
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.estimated_width = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (code == '\t' && term->getxy)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term).x)
|
||||||
|
% GRUB_TERM_TAB_WIDTH);
|
||||||
|
while (n--)
|
||||||
|
grub_putcode_dumb (' ', term);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(term->putchar) (term, &c);
|
||||||
|
if (code == '\n')
|
||||||
|
grub_putcode_dumb ('\r', term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_xputs_dumb (const char *str)
|
||||||
|
{
|
||||||
|
for (; *str; str++)
|
||||||
|
{
|
||||||
|
grub_term_output_t term;
|
||||||
|
grub_uint32_t code = *str;
|
||||||
|
if (code > 0x7f)
|
||||||
|
code = '?';
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
grub_putcode_dumb (code, term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*grub_xputs) (const char *str) = grub_xputs_dumb;
|
||||||
|
|
||||||
|
int (*grub_key_remap)(int key) = NULL;
|
||||||
|
int
|
||||||
|
grub_getkey_noblock (void)
|
||||||
|
{
|
||||||
|
grub_term_input_t term;
|
||||||
|
|
||||||
|
if (grub_term_poll_usb)
|
||||||
|
grub_term_poll_usb (0);
|
||||||
|
|
||||||
|
if (grub_net_poll_cards_idle)
|
||||||
|
grub_net_poll_cards_idle ();
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_INPUTS(term)
|
||||||
|
{
|
||||||
|
int key = term->getkey (term);
|
||||||
|
if (grub_key_remap)
|
||||||
|
key = grub_key_remap(key);
|
||||||
|
if (key != GRUB_TERM_NO_KEY)
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_TERM_NO_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_getkey (void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
grub_refresh ();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ret = grub_getkey_noblock ();
|
||||||
|
if (ret != GRUB_TERM_NO_KEY)
|
||||||
|
return ret;
|
||||||
|
grub_cpu_idle ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_refresh (void)
|
||||||
|
{
|
||||||
|
struct grub_term_output *term;
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
grub_term_refresh (term);
|
||||||
|
}
|
||||||
40
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c
Normal file
40
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/* efi.c - generic EFI support */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2006,2007,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/efi/api.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
#include <grub/acpi.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_halt (void)
|
||||||
|
{
|
||||||
|
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||||
|
#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) &&\
|
||||||
|
!defined(__riscv)
|
||||||
|
grub_acpi_halt ();
|
||||||
|
#endif
|
||||||
|
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||||
|
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
495
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c
Normal file
495
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2017 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/mm.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/cpu/efi/memory.h>
|
||||||
|
#include <grub/cpu/memory.h>
|
||||||
|
#include <grub/machine/loongson.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
|
||||||
|
#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp)
|
||||||
|
#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8)
|
||||||
|
#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start)
|
||||||
|
|
||||||
|
extern grub_uint8_t grub_efi_loongson_reset_start;
|
||||||
|
extern grub_uint8_t grub_efi_loongson_reset_end;
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
grub_efi_loongson_boot_params boot_params;
|
||||||
|
grub_efi_loongson_memory_map memory_map;
|
||||||
|
grub_efi_loongson_cpu_info cpu_info;
|
||||||
|
grub_efi_loongson_system_info system_info;
|
||||||
|
grub_efi_loongson_irq_src_routing_table irq_src_routing_table;
|
||||||
|
grub_efi_loongson_interface_info interface_info;
|
||||||
|
grub_efi_loongson_special_attribute special_attribute;
|
||||||
|
grub_efi_loongson_board_devices board_devices;
|
||||||
|
} GRUB_PACKED
|
||||||
|
* loongson_boot_params;
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_reset_system (void)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_boot_params *boot_params;
|
||||||
|
grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params +
|
||||||
|
loongson_boot_params_size;
|
||||||
|
|
||||||
|
boot_params = &loongson_boot_params->boot_params;
|
||||||
|
grub_efi_loongson_reset_system_addr =
|
||||||
|
(grub_uint64_t) grub_efi_system_table->runtime_services->reset_system;
|
||||||
|
grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size);
|
||||||
|
grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size);
|
||||||
|
|
||||||
|
boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr +
|
||||||
|
((grub_uint64_t) &grub_efi_loongson_reset_cold -
|
||||||
|
(grub_uint64_t) &grub_efi_loongson_reset_start);
|
||||||
|
boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr +
|
||||||
|
((grub_uint64_t) &grub_efi_loongson_reset_warm -
|
||||||
|
(grub_uint64_t) &grub_efi_loongson_reset_start);
|
||||||
|
boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr +
|
||||||
|
((grub_uint64_t) &grub_efi_loongson_reset_shutdown -
|
||||||
|
(grub_uint64_t) &grub_efi_loongson_reset_start);
|
||||||
|
boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr +
|
||||||
|
((grub_uint64_t) &grub_efi_loongson_reset_suspend -
|
||||||
|
(grub_uint64_t) &grub_efi_loongson_reset_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios;
|
||||||
|
|
||||||
|
dst->vers = smbios_table->vers;
|
||||||
|
dst->vga_bios = smbios_table->vga_bios;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset;
|
||||||
|
grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info));
|
||||||
|
loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset;
|
||||||
|
grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info));
|
||||||
|
loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset;
|
||||||
|
grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table));
|
||||||
|
loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset;
|
||||||
|
grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info));
|
||||||
|
loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset;
|
||||||
|
grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute));
|
||||||
|
loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset;
|
||||||
|
grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices));
|
||||||
|
loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADD_MEMORY_DESCRIPTOR(desc, size) \
|
||||||
|
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table,
|
||||||
|
grub_efi_memory_descriptor_t *mmap_buf,
|
||||||
|
grub_efi_uintn_t mmap_size,
|
||||||
|
grub_efi_uintn_t desc_size)
|
||||||
|
{
|
||||||
|
grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset;
|
||||||
|
grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map;
|
||||||
|
grub_efi_memory_descriptor_t *mmap_end;
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
grub_efi_memory_descriptor_t *desc_next;
|
||||||
|
grub_efi_uint32_t mem_types_reserved[] =
|
||||||
|
{
|
||||||
|
1, // GRUB_EFI_RESERVED_MEMORY_TYPE
|
||||||
|
0, // GRUB_EFI_LOADER_CODE
|
||||||
|
0, // GRUB_EFI_LOADER_DATA
|
||||||
|
0, // GRUB_EFI_BOOT_SERVICES_CODE
|
||||||
|
0, // GRUB_EFI_BOOT_SERVICES_DATA
|
||||||
|
1, // GRUB_EFI_RUNTIME_SERVICES_CODE
|
||||||
|
1, // GRUB_EFI_RUNTIME_SERVICES_DATA
|
||||||
|
0, // GRUB_EFI_CONVENTIONAL_MEMORY
|
||||||
|
1, // GRUB_EFI_UNUSABLE_MEMORY
|
||||||
|
0, // GRUB_EFI_ACPI_RECLAIM_MEMORY
|
||||||
|
0, // GRUB_EFI_ACPI_MEMORY_NVS
|
||||||
|
1, // GRUB_EFI_MEMORY_MAPPED_IO
|
||||||
|
1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE
|
||||||
|
1, // GRUB_EFI_PAL_CODE
|
||||||
|
1, // GRUB_EFI_PERSISTENT_MEMORY
|
||||||
|
};
|
||||||
|
grub_uint32_t need_sort = 1;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst->vers = src->vers;
|
||||||
|
dst->nr_map = 0;
|
||||||
|
dst->mem_freq = src->mem_freq;
|
||||||
|
loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
|
||||||
|
|
||||||
|
if (!mmap_buf || !mmap_size || !desc_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
|
||||||
|
|
||||||
|
/* drop reserved */
|
||||||
|
for (desc = mmap_buf,
|
||||||
|
desc_next = desc;
|
||||||
|
desc < mmap_end;
|
||||||
|
desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
desc->type = mem_types_reserved[desc->type];
|
||||||
|
if (desc->type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (desc != desc_next)
|
||||||
|
*desc_next = *desc;
|
||||||
|
desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size);
|
||||||
|
}
|
||||||
|
mmap_end = desc_next;
|
||||||
|
|
||||||
|
/* sort: low->high */
|
||||||
|
while (need_sort)
|
||||||
|
{
|
||||||
|
need_sort = 0;
|
||||||
|
|
||||||
|
for (desc = mmap_buf,
|
||||||
|
desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
|
||||||
|
(desc < mmap_end) && (desc_next < mmap_end);
|
||||||
|
desc = desc_next,
|
||||||
|
desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t tmp;
|
||||||
|
|
||||||
|
if (desc->physical_start <= desc_next->physical_start)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tmp = *desc;
|
||||||
|
*desc = *desc_next;
|
||||||
|
*desc_next = tmp;
|
||||||
|
need_sort = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* combine continuous memory map */
|
||||||
|
for (desc = mmap_buf,
|
||||||
|
desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
|
||||||
|
desc_next < mmap_end;
|
||||||
|
desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size))
|
||||||
|
{
|
||||||
|
grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12);
|
||||||
|
|
||||||
|
if (prev_end == desc_next->physical_start)
|
||||||
|
{
|
||||||
|
desc->num_pages += desc_next->num_pages;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
|
||||||
|
grub_memcpy (desc, desc_next, desc_size);
|
||||||
|
}
|
||||||
|
mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
|
||||||
|
|
||||||
|
/* write to loongson memory map */
|
||||||
|
for (desc = mmap_buf;
|
||||||
|
desc < mmap_end;
|
||||||
|
desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start);
|
||||||
|
grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12);
|
||||||
|
|
||||||
|
physical_start = ALIGN_UP (physical_start, 0x100000);
|
||||||
|
physical_end = ALIGN_DOWN (physical_end, 0x100000);
|
||||||
|
|
||||||
|
if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf;
|
||||||
|
dst->map[dst->nr_map].mem_type = (physical_end <= 0x10000000) ?
|
||||||
|
GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW :
|
||||||
|
GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH;
|
||||||
|
dst->map[dst->nr_map].mem_start = physical_start;
|
||||||
|
dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20;
|
||||||
|
|
||||||
|
grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n",
|
||||||
|
dst->nr_map, physical_start, physical_end - physical_start,
|
||||||
|
dst->map[dst->nr_map].node_id);
|
||||||
|
|
||||||
|
dst->nr_map ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||||
|
#define SUB_MEMORY_DESCRIPTOR(desc, size) \
|
||||||
|
((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size)))
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_loongson_alloc_boot_params (void)
|
||||||
|
{
|
||||||
|
grub_efi_memory_descriptor_t *mmap_buf;
|
||||||
|
grub_efi_memory_descriptor_t *mmap_end;
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
grub_efi_uintn_t mmap_size;
|
||||||
|
grub_efi_uintn_t desc_size;
|
||||||
|
grub_efi_physical_address_t address;
|
||||||
|
grub_efi_allocate_type_t type;
|
||||||
|
grub_efi_uintn_t pages;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
int mm_status;
|
||||||
|
|
||||||
|
type = GRUB_EFI_ALLOCATE_ADDRESS;
|
||||||
|
pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size);
|
||||||
|
|
||||||
|
mmap_size = (1 << 12);
|
||||||
|
mmap_buf = grub_malloc (mmap_size);
|
||||||
|
if (!mmap_buf)
|
||||||
|
grub_fatal ("out of memory!");
|
||||||
|
|
||||||
|
mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0);
|
||||||
|
if (mm_status == 0)
|
||||||
|
{
|
||||||
|
grub_free (mmap_buf);
|
||||||
|
mmap_size += desc_size * 32;
|
||||||
|
|
||||||
|
mmap_buf = grub_malloc (mmap_size);
|
||||||
|
if (!mmap_buf)
|
||||||
|
grub_fatal ("out of memory!");
|
||||||
|
|
||||||
|
mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mm_status < 0)
|
||||||
|
grub_fatal ("cannot get memory map!");
|
||||||
|
|
||||||
|
mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
|
||||||
|
|
||||||
|
for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size);
|
||||||
|
desc >= mmap_buf;
|
||||||
|
desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
|
||||||
|
continue;
|
||||||
|
if (desc->physical_start >= GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
continue;
|
||||||
|
if (desc->num_pages < pages)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
address = desc->physical_start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free (mmap_buf);
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
grub_fatal ("cannot allocate Loongson boot parameters!");
|
||||||
|
|
||||||
|
loongson_boot_params = (void *) ((grub_addr_t) address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_efi_loongson_free_boot_params (void)
|
||||||
|
{
|
||||||
|
grub_efi_free_pages ((grub_addr_t) loongson_boot_params,
|
||||||
|
BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_efi_loongson_get_smbios_table (void)
|
||||||
|
{
|
||||||
|
static grub_efi_loongson_smbios_table *smbios_table;
|
||||||
|
grub_efi_loongson_boot_params *old_boot_params;
|
||||||
|
struct bootparamsinterface* boot_params;
|
||||||
|
void * tmp_boot_params = NULL;
|
||||||
|
char * p = NULL;
|
||||||
|
if(smbios_table)
|
||||||
|
return smbios_table;
|
||||||
|
|
||||||
|
tmp_boot_params = grub_efi_loongson_get_boot_params();
|
||||||
|
if(tmp_boot_params == NULL)
|
||||||
|
{
|
||||||
|
grub_dprintf("loongson", "tmp_boot_params is NULL\n");
|
||||||
|
return tmp_boot_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_params = (struct bootparamsinterface *)tmp_boot_params;
|
||||||
|
p = (char *)&(boot_params->signature);
|
||||||
|
if(grub_strncmp(p, "BPI", 3) == 0)
|
||||||
|
{
|
||||||
|
grub_dprintf("loongson", "find new bpi\n");
|
||||||
|
return boot_params ? boot_params : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params;
|
||||||
|
return old_boot_params ? &old_boot_params->efi.smbios : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_efi_is_loongson (void)
|
||||||
|
{
|
||||||
|
return grub_efi_loongson_get_smbios_table () ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_efi_loongson_get_boot_params (void)
|
||||||
|
{
|
||||||
|
static void * boot_params = NULL;
|
||||||
|
grub_efi_configuration_table_t *tables;
|
||||||
|
grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (boot_params)
|
||||||
|
return boot_params;
|
||||||
|
|
||||||
|
/* Look for Loongson SMBIOS in UEFI config tables. */
|
||||||
|
tables = grub_efi_system_table->configuration_table;
|
||||||
|
|
||||||
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
|
if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0)
|
||||||
|
{
|
||||||
|
boot_params= tables[i].vendor_table;
|
||||||
|
grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return boot_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_uint8_t
|
||||||
|
grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length)
|
||||||
|
{
|
||||||
|
grub_uint8_t sum;
|
||||||
|
grub_efi_uintn_t count;
|
||||||
|
|
||||||
|
for (sum = 0, count = 0; count < length; count++)
|
||||||
|
{
|
||||||
|
sum = (grub_uint8_t) (sum + *(buffer + count));
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_uint8_t
|
||||||
|
grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length)
|
||||||
|
{
|
||||||
|
grub_uint8_t checksum;
|
||||||
|
|
||||||
|
checksum = grub_efi_loongson_calculatesum8(buffer, length);
|
||||||
|
|
||||||
|
return (grub_uint8_t) (0x100 - checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
grub_uint32_t
|
||||||
|
grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype)
|
||||||
|
{
|
||||||
|
grub_uint64_t tempmemsize = 0;
|
||||||
|
grub_uint32_t j = 0;
|
||||||
|
grub_uint32_t t = 0;
|
||||||
|
|
||||||
|
for(j = 0; j < length;)
|
||||||
|
{
|
||||||
|
tempmemsize = array[j].memsize;
|
||||||
|
for(t = j + 1; t < length; t++)
|
||||||
|
{
|
||||||
|
if(array[j].memstart + tempmemsize == array[t].memstart)
|
||||||
|
{
|
||||||
|
tempmemsize += array[t].memsize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bpmem->map[index].memtype = memtype;
|
||||||
|
bpmem->map[index].memstart = array[j].memstart;
|
||||||
|
bpmem->map[index].memsize = tempmemsize;
|
||||||
|
grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n",
|
||||||
|
index,
|
||||||
|
bpmem->map[index].memtype,
|
||||||
|
(unsigned long long)bpmem->map[index].memstart,
|
||||||
|
(unsigned long long)bpmem->map[index].memstart+ bpmem->map[index].memsize
|
||||||
|
);
|
||||||
|
j = t;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2017 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/symbol.h>
|
||||||
|
|
||||||
|
.file "loongson.S"
|
||||||
|
.text
|
||||||
|
|
||||||
|
.set push
|
||||||
|
.set noreorder
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
VARIABLE (grub_efi_loongson_reset_start)
|
||||||
|
|
||||||
|
VARIABLE (grub_efi_loongson_reset_system_addr)
|
||||||
|
.dword 0
|
||||||
|
|
||||||
|
reset_system:
|
||||||
|
bal 1f
|
||||||
|
move $a1, $zero
|
||||||
|
1:
|
||||||
|
ld $t9, -16($ra)
|
||||||
|
move $a2, $zero
|
||||||
|
jalr $t9
|
||||||
|
move $a3, $zero
|
||||||
|
|
||||||
|
FUNCTION(grub_efi_loongson_reset_cold)
|
||||||
|
b reset_system
|
||||||
|
li $a0, 0
|
||||||
|
|
||||||
|
FUNCTION(grub_efi_loongson_reset_warm)
|
||||||
|
b reset_system
|
||||||
|
li $a0, 1
|
||||||
|
|
||||||
|
FUNCTION(grub_efi_loongson_reset_shutdown)
|
||||||
|
b reset_system
|
||||||
|
li $a0, 2
|
||||||
|
|
||||||
|
FUNCTION(grub_efi_loongson_reset_suspend)
|
||||||
|
b reset_system
|
||||||
|
li $a0, 3
|
||||||
|
|
||||||
|
VARIABLE (grub_efi_loongson_reset_end)
|
||||||
|
|
||||||
|
.set pop
|
||||||
|
|
||||||
169
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c
Normal file
169
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2017 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/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
|
||||||
|
#include <grub/mips64/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
|
||||||
|
extern grub_uint8_t grub_relocator_forward_start;
|
||||||
|
extern grub_uint8_t grub_relocator_forward_end;
|
||||||
|
extern grub_uint8_t grub_relocator_backward_start;
|
||||||
|
extern grub_uint8_t grub_relocator_backward_end;
|
||||||
|
|
||||||
|
#define REGW_SIZEOF (6 * sizeof (grub_uint32_t))
|
||||||
|
#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
|
||||||
|
|
||||||
|
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \
|
||||||
|
- &grub_relocator_##x##_start)
|
||||||
|
#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
|
||||||
|
+ REGW_SIZEOF * 3)
|
||||||
|
grub_size_t grub_relocator_align = sizeof (grub_uint64_t);
|
||||||
|
grub_size_t grub_relocator_forward_size;
|
||||||
|
grub_size_t grub_relocator_backward_size;
|
||||||
|
grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF;
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_init (void)
|
||||||
|
{
|
||||||
|
grub_relocator_forward_size = RELOCATOR_SIZEOF(forward);
|
||||||
|
grub_relocator_backward_size = RELOCATOR_SIZEOF(backward);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_reg (int regn, grub_uint64_t val, void **target)
|
||||||
|
{
|
||||||
|
grub_uint32_t lui;
|
||||||
|
grub_uint32_t ori;
|
||||||
|
grub_uint32_t dsll;
|
||||||
|
|
||||||
|
/* lui $r, 0 */
|
||||||
|
lui = (0x3c00 | regn) << 16;
|
||||||
|
/* ori $r, $r, 0 */
|
||||||
|
ori = (0x3400 | (regn << 5) | regn) << 16;
|
||||||
|
/* dsll $r, $r, 16 */
|
||||||
|
dsll = (regn << 16) | (regn << 11) | (16 << 6) | 56;
|
||||||
|
|
||||||
|
/* lui $r, val[63:48]. */
|
||||||
|
*(grub_uint32_t *) *target = lui | (grub_uint16_t) (val >> 48);
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* ori $r, val[47:32]. */
|
||||||
|
*(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 32);
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* dsll $r, $r, 16 */
|
||||||
|
*(grub_uint32_t *) *target = dsll;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* ori $r, val[31:16]. */
|
||||||
|
*(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 16);
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* dsll $r, $r, 16 */
|
||||||
|
*(grub_uint32_t *) *target = dsll;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* ori $r, val[15:0]. */
|
||||||
|
*(grub_uint32_t *) *target = ori | (grub_uint16_t) val;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_jump (int regn, void **target)
|
||||||
|
{
|
||||||
|
/* j $r. */
|
||||||
|
*(grub_uint32_t *) *target = (regn << 21) | 0x8;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* nop. */
|
||||||
|
*(grub_uint32_t *) *target = 0;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
|
||||||
|
{
|
||||||
|
write_reg (1, addr, &rels);
|
||||||
|
write_jump (1, &rels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_backward (void *ptr0, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = ptr0;
|
||||||
|
write_reg (8, (grub_uint64_t) src, &ptr);
|
||||||
|
write_reg (9, (grub_uint64_t) dest, &ptr);
|
||||||
|
write_reg (10, (grub_uint64_t) size, &ptr);
|
||||||
|
grub_memcpy (ptr, &grub_relocator_backward_start,
|
||||||
|
RELOCATOR_SRC_SIZEOF (backward));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_forward (void *ptr0, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = ptr0;
|
||||||
|
write_reg (8, (grub_uint64_t) src, &ptr);
|
||||||
|
write_reg (9, (grub_uint64_t) dest, &ptr);
|
||||||
|
write_reg (10, (grub_uint64_t) size, &ptr);
|
||||||
|
grub_memcpy (ptr, &grub_relocator_forward_start,
|
||||||
|
RELOCATOR_SRC_SIZEOF (forward));
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator64_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator64_state state)
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
void *ptr;
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_size_t relsize;
|
||||||
|
grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF;
|
||||||
|
unsigned i;
|
||||||
|
grub_addr_t vtarget;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
|
(0xffffffff - stateset_size)
|
||||||
|
+ 1, stateset_size,
|
||||||
|
grub_relocator_align,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ptr = get_virtual_current_address (ch);
|
||||||
|
for (i = 1; i < 32; i++)
|
||||||
|
write_reg (i, state.gpr[i], &ptr);
|
||||||
|
write_jump (state.jumpreg, &ptr);
|
||||||
|
|
||||||
|
vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch),
|
||||||
|
stateset_size);
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_arch_sync_caches ((void *) relst, relsize);
|
||||||
|
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
56
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S
Normal file
56
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2017 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/symbol.h>
|
||||||
|
|
||||||
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
|
.set push
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_forward_start)
|
||||||
|
|
||||||
|
copycont1:
|
||||||
|
ld $11,0($8)
|
||||||
|
sd $11,0($9)
|
||||||
|
daddiu $8, $8, 8
|
||||||
|
daddiu $10, $10, -8
|
||||||
|
bne $10, $0, copycont1
|
||||||
|
daddiu $9, $9, 8
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_forward_end)
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_backward_start)
|
||||||
|
|
||||||
|
daddu $9, $9, $10
|
||||||
|
daddu $8, $8, $10
|
||||||
|
/* Backward movsl is implicitly off-by-one. compensate that. */
|
||||||
|
daddiu $9, $9, -8
|
||||||
|
daddiu $8, $8, -8
|
||||||
|
copycont2:
|
||||||
|
ld $11,0($8)
|
||||||
|
sd $11,0($9)
|
||||||
|
daddiu $8, $8, -8
|
||||||
|
daddiu $10, $10, -8
|
||||||
|
bne $10, $0, copycont2
|
||||||
|
daddiu $9, $9, -8
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_backward_end)
|
||||||
|
|
||||||
|
.set pop
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user