mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-09-24 04:31:15 +00:00
Compare commits
884 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60d88cb7b1 | ||
|
|
f7e6bbc70c | ||
|
|
ee994a0569 | ||
|
|
966ed21de7 | ||
|
|
ff7ee9c10e | ||
|
|
f43461a16c | ||
|
|
377e3fb7bc | ||
|
|
f62bd1be14 | ||
|
|
b11c38779d | ||
|
|
f202542c62 | ||
|
|
279491a36a | ||
|
|
cb209f9b9e | ||
|
|
b7b2f6a5c1 | ||
|
|
3967fb5fb5 | ||
|
|
a2ad95792d | ||
|
|
791308d2ce | ||
|
|
0ffb1b15ef | ||
|
|
d6e1730ca0 | ||
|
|
4d55f505f9 | ||
|
|
30a61ac5c4 | ||
|
|
9b79831516 | ||
|
|
af2d6bc247 | ||
|
|
d8ae740427 | ||
|
|
b685157ae3 | ||
|
|
3f6ddb6fb6 | ||
|
|
b8838b305d | ||
|
|
00de8b932d | ||
|
|
1e49dbe957 | ||
|
|
580416facc | ||
|
|
75cf728fa9 | ||
|
|
8723aeb4cc | ||
|
|
dc9a99bb20 | ||
|
|
a40456d9d2 | ||
|
|
bdab55e8aa | ||
|
|
1b2483ec14 | ||
|
|
c16e76130b | ||
|
|
d672af4819 | ||
|
|
712f10e86a | ||
|
|
2be340d2e8 | ||
|
|
b77ef718b4 | ||
|
|
72f5710b88 | ||
|
|
ee7da60d88 | ||
|
|
44fb9f4564 | ||
|
|
3f65f0ef03 | ||
|
|
4faa5e4344 | ||
|
|
c7693d4ecd | ||
|
|
4527e1db79 | ||
|
|
757cacf274 | ||
|
|
39703cabb7 | ||
|
|
854d17a4e9 | ||
|
|
a326b13fc3 | ||
|
|
3ff1867a2a | ||
|
|
7f63a1c327 | ||
|
|
d617985093 | ||
|
|
605da1ba94 | ||
|
|
c8dc36a5c3 | ||
|
|
689f7df902 | ||
|
|
a9d53e7448 | ||
|
|
46061bcd41 | ||
|
|
01b0de7811 | ||
|
|
2fee243a56 | ||
|
|
d0e10f8e48 | ||
|
|
7ff243f9bb | ||
|
|
f8811a4656 | ||
|
|
0ce90ad9b9 | ||
|
|
5bfddae81d | ||
|
|
2991f097fb | ||
|
|
986835338d | ||
|
|
f2562fecb9 | ||
|
|
529541f218 | ||
|
|
430f81ac49 | ||
|
|
038c0533d9 | ||
|
|
102b179cd9 | ||
|
|
6785f5d049 | ||
|
|
0c812ed5e9 | ||
|
|
9f2b9b0867 | ||
|
|
c79b072680 | ||
|
|
6b4509a550 | ||
|
|
feea11e2bb | ||
|
|
35c952d891 | ||
|
|
82053680bf | ||
|
|
6d5de12f52 | ||
|
|
84b2ee7ee3 | ||
|
|
da1b306e81 | ||
|
|
0961ce5624 | ||
|
|
07574f0379 | ||
|
|
142aa47944 | ||
|
|
11739fa9d0 | ||
|
|
9fc85051a7 | ||
|
|
b9e82bcf16 | ||
|
|
cff3a01289 | ||
|
|
0f90149c4e | ||
|
|
8ef9732931 | ||
|
|
b32eda4262 | ||
|
|
e743f7c15f | ||
|
|
652475f1ef | ||
|
|
abfc2a6343 | ||
|
|
e73ac04cb6 | ||
|
|
8727e63880 | ||
|
|
2d281d7dee | ||
|
|
385c806adf | ||
|
|
e869bc2386 | ||
|
|
b47aa1abc7 | ||
|
|
d8698b2194 | ||
|
|
7fa4724743 | ||
|
|
2717405a7a | ||
|
|
d494007df9 | ||
|
|
bc9e3f641b | ||
|
|
9f02d37001 | ||
|
|
fa1461bac7 | ||
|
|
3d56c3fa17 | ||
|
|
a7e3d78d14 | ||
|
|
879a7592bd | ||
|
|
5a433f49f7 | ||
|
|
0cce956c54 | ||
|
|
0b6372857c | ||
|
|
028663de9a | ||
|
|
5feb3f7b4b | ||
|
|
7035787f38 | ||
|
|
7dd0f509f5 | ||
|
|
15947caea2 | ||
|
|
6aeba8f8b4 | ||
|
|
fd46b2c3c3 | ||
|
|
e502f4291e | ||
|
|
9c59c27eff | ||
|
|
daeb96ce80 | ||
|
|
b7e878c466 | ||
|
|
b76ebf5b07 | ||
|
|
9532776f39 | ||
|
|
d8e81d41e4 | ||
|
|
fa3aa3b36f | ||
|
|
e717d00d53 | ||
|
|
6bcaf19a1a | ||
|
|
bcbe8835d4 | ||
|
|
ed746ce13e | ||
|
|
07a790fc6a | ||
|
|
fd393a02fd | ||
|
|
0501d03dbb | ||
|
|
c9939a8cfc | ||
|
|
5067020a61 | ||
|
|
4f5334026e | ||
|
|
3e34dd8514 | ||
|
|
4df793e021 | ||
|
|
e0132ac4b5 | ||
|
|
2b3192b098 | ||
|
|
7ee3a6d9f8 | ||
|
|
e1d3ca9fc4 | ||
|
|
8653832551 | ||
|
|
c308892db0 | ||
|
|
1300f7f4f1 | ||
|
|
d9182dbfa4 | ||
|
|
e988c0dfe2 | ||
|
|
0714971f8c | ||
|
|
3c03df31ce | ||
|
|
e24dacadcd | ||
|
|
315cabb945 | ||
|
|
72f25f14fc | ||
|
|
47e1553d23 | ||
|
|
9a2a7e83eb | ||
|
|
5f747148c6 | ||
|
|
686ed11037 | ||
|
|
7fe4762faa | ||
|
|
eac1c35f76 | ||
|
|
c7dcaa5734 | ||
|
|
4b17ee30c4 | ||
|
|
a18aa36c01 | ||
|
|
1de7489c6d | ||
|
|
afb3340ce7 | ||
|
|
fdce4a756a | ||
|
|
5a7fa0c565 | ||
|
|
287d77224c | ||
|
|
c6bd857cbe | ||
|
|
b4bb6efd3c | ||
|
|
7386f64ed8 | ||
|
|
044ca8811d | ||
|
|
8c6fd872af | ||
|
|
683101ae1a | ||
|
|
0e968e266e | ||
|
|
d94d59583a | ||
|
|
05bbef63c1 | ||
|
|
8923d4b8f1 | ||
|
|
377cd9e468 | ||
|
|
be78728342 | ||
|
|
3938fbb351 | ||
|
|
a2e7afd893 | ||
|
|
27bb4a1168 | ||
|
|
b8b8c7bd66 | ||
|
|
12b51bcf09 | ||
|
|
911d5dcab9 | ||
|
|
f597497da6 | ||
|
|
54bca8c942 | ||
|
|
6b422ad9c1 | ||
|
|
925d057883 | ||
|
|
a377dd6172 | ||
|
|
4707022ef9 | ||
|
|
e03c73978a | ||
|
|
f434d1f5d0 | ||
|
|
23f8bc8aeb | ||
|
|
f2016ab899 | ||
|
|
7acbf7e819 | ||
|
|
0135bf1934 | ||
|
|
f2c94bd963 | ||
|
|
676ae725ae | ||
|
|
54dd35d277 | ||
|
|
3e75b2df3b | ||
|
|
2d1230cba4 | ||
|
|
309f85fd35 | ||
|
|
a13d6d9c0e | ||
|
|
9b7d6cbc3d | ||
|
|
bf797ceadb | ||
|
|
cd0c7ca884 | ||
|
|
201f7cc13c | ||
|
|
44a3e23740 | ||
|
|
9c3e1a6880 | ||
|
|
8a664faa04 | ||
|
|
398ba9fb56 | ||
|
|
e7a0c2d359 | ||
|
|
22ad828df2 | ||
|
|
83f22173a5 | ||
|
|
2de7d9ffe0 | ||
|
|
5c174c4521 | ||
|
|
c76ece4b74 | ||
|
|
27eda4d1e7 | ||
|
|
acf5a84467 | ||
|
|
c93e406aa5 | ||
|
|
1b164e74e4 | ||
|
|
308cb86f83 | ||
|
|
2ec593d355 | ||
|
|
594e735b91 | ||
|
|
6203366040 | ||
|
|
64f4400305 | ||
|
|
d00e08e2e1 | ||
|
|
c6008be394 | ||
|
|
a5c6859f5f | ||
|
|
497d4cc991 | ||
|
|
7e7687afe3 | ||
|
|
dd3276badf | ||
|
|
4a06f4a694 | ||
|
|
c73bf256be | ||
|
|
21851f7e96 | ||
|
|
f222f8cac9 | ||
|
|
40c4825aac | ||
|
|
dd906e0b16 | ||
|
|
324f2b927c | ||
|
|
5797ca3396 | ||
|
|
b36b322c03 | ||
|
|
fd7e34b632 | ||
|
|
e85c02756b | ||
|
|
c1d68bd787 | ||
|
|
a35a822723 | ||
|
|
05137c83e2 | ||
|
|
8058856182 | ||
|
|
33b958e112 | ||
|
|
9eb50a85e4 | ||
|
|
3cc7e3772e | ||
|
|
9c8292867f | ||
|
|
a4053d2d05 | ||
|
|
5c14ea0a4a | ||
|
|
194e948cb6 | ||
|
|
c896c03efe | ||
|
|
574b4d850c | ||
|
|
68a98325e6 | ||
|
|
25b055bb0f | ||
|
|
bda74cd89b | ||
|
|
511b8091eb | ||
|
|
3be4aacd78 | ||
|
|
2d8b27b172 | ||
|
|
c174410d35 | ||
|
|
f83e84f868 | ||
|
|
a39078b87a | ||
|
|
2576235f97 | ||
|
|
ee04af5243 | ||
|
|
118bedd546 | ||
|
|
44ff3dd8d4 | ||
|
|
9da5a6ce65 | ||
|
|
604b25ec82 | ||
|
|
0918355035 | ||
|
|
ce76fd5649 | ||
|
|
42535f35bc | ||
|
|
68a9cebe19 | ||
|
|
cc77c74bf4 | ||
|
|
ee952e3f69 | ||
|
|
b11a499939 | ||
|
|
fdf4693433 | ||
|
|
ac65c0fb24 | ||
|
|
ea0afe7c8b | ||
|
|
f8ca8b13d3 | ||
|
|
678a2abdf1 | ||
|
|
e645301713 | ||
|
|
43b415c032 | ||
|
|
311d2961ca | ||
|
|
1d66584190 | ||
|
|
553c853865 | ||
|
|
7d90912a09 | ||
|
|
c2336f555a | ||
|
|
87391e8b32 | ||
|
|
f9c56c6686 | ||
|
|
1ab1799b72 | ||
|
|
4a42bdfce7 | ||
|
|
3f09fb9a23 | ||
|
|
c87ad1d734 | ||
|
|
5590208885 | ||
|
|
09a6d33d62 | ||
|
|
9852252aba | ||
|
|
0585d83a8f | ||
|
|
ebe0b7d282 | ||
|
|
261ddcef45 | ||
|
|
ebc5e2e993 | ||
|
|
d58bd8c3f7 | ||
|
|
17f9e2fd09 | ||
|
|
6b22a6200e | ||
|
|
860dce6683 | ||
|
|
7fc72d5ce6 | ||
|
|
b7c3cbd23b | ||
|
|
3de97bdf44 | ||
|
|
e79dc57ebe | ||
|
|
7bf85a1ef8 | ||
|
|
a5e0641226 | ||
|
|
2c65eec9ec | ||
|
|
0c310c5bd8 | ||
|
|
c81b49807b | ||
|
|
085e20f64d | ||
|
|
ff3ce4da66 | ||
|
|
81d3492a61 | ||
|
|
635b1a1c6c | ||
|
|
10b80f2690 | ||
|
|
36c21a21e4 | ||
|
|
13eb9829fa | ||
|
|
88f77c01e4 | ||
|
|
11b30dab5f | ||
|
|
fb729146de | ||
|
|
92bd6733dd | ||
|
|
9e28dd1394 | ||
|
|
4100e7a886 | ||
|
|
a4f5ce2c9e | ||
|
|
c7967ea476 | ||
|
|
3e7f1ca764 | ||
|
|
1bc18295ae | ||
|
|
b4f1f11742 | ||
|
|
20010c5e88 | ||
|
|
1de18e43c5 | ||
|
|
15299d4d87 | ||
|
|
5d6d6df39b | ||
|
|
096cc99c3c | ||
|
|
602e8c7fdf | ||
|
|
da35a99f7c | ||
|
|
e46e24dde7 | ||
|
|
0b81845e42 | ||
|
|
3c621e4aca | ||
|
|
aecc579fcc | ||
|
|
598af7f45c | ||
|
|
24b05c0345 | ||
|
|
6d72617ef6 | ||
|
|
351f15ff18 | ||
|
|
1ee65a60c2 | ||
|
|
ecbf45defe | ||
|
|
b976923f00 | ||
|
|
8db8e07b61 | ||
|
|
f200c14730 | ||
|
|
c090197717 | ||
|
|
3ac17aa825 | ||
|
|
595b9441e9 | ||
|
|
0f3d48b3d9 | ||
|
|
61f289aa8a | ||
|
|
b099547af6 | ||
|
|
23bd2d24e9 | ||
|
|
85d1910722 | ||
|
|
9b2b4aa354 | ||
|
|
45122b59c0 | ||
|
|
5e607b7f9f | ||
|
|
1c0b4ee903 | ||
|
|
bf2517bb25 | ||
|
|
1065a41992 | ||
|
|
954cb14d87 | ||
|
|
4f64aecfa3 | ||
|
|
8af432b74b | ||
|
|
d8bca311b2 | ||
|
|
025425f260 | ||
|
|
b4120c4079 | ||
|
|
7f2f845a68 | ||
|
|
2cd22da8fb | ||
|
|
7b70a5278a | ||
|
|
f8b1f98304 | ||
|
|
ddf0617d83 | ||
|
|
9b14b418b4 | ||
|
|
fe137522ad | ||
|
|
121d927367 | ||
|
|
75f3e4c5ee | ||
|
|
fcf10deff3 | ||
|
|
4d4f958429 | ||
|
|
e667233994 | ||
|
|
57944520e5 | ||
|
|
4544e221d3 | ||
|
|
3263b64b8a | ||
|
|
69da3a59d8 | ||
|
|
75c6c7257f | ||
|
|
d4d8736620 | ||
|
|
63f9331c31 | ||
|
|
e1d161af4f | ||
|
|
9baa95359c | ||
|
|
5f3d7f3823 | ||
|
|
3d1dc81fda | ||
|
|
3ebc610e7d | ||
|
|
60588c8442 | ||
|
|
c4c05fc073 | ||
|
|
0984f5ba58 | ||
|
|
fd0d335eb6 | ||
|
|
12a284b543 | ||
|
|
9e2e4ec0a9 | ||
|
|
480afee1a7 | ||
|
|
1305945bc0 | ||
|
|
2feb148982 | ||
|
|
5eec535391 | ||
|
|
33a562c273 | ||
|
|
75517039a1 | ||
|
|
620229508b | ||
|
|
5553dd4fc4 | ||
|
|
89addae48f | ||
|
|
682e8cdc42 | ||
|
|
1882cfcce2 | ||
|
|
b8be46f0dc | ||
|
|
07693bf840 | ||
|
|
b4a059dd68 | ||
|
|
858eec99a1 | ||
|
|
8180382fe1 | ||
|
|
a5d9b1fd43 | ||
|
|
8b76e06f6d | ||
|
|
ecb133ed5e | ||
|
|
da20eb5568 | ||
|
|
2d76fa7303 | ||
|
|
8fc8cc6867 | ||
|
|
132649c4e5 | ||
|
|
c3c8100866 | ||
|
|
94e24e63c5 | ||
|
|
c19cd649d8 | ||
|
|
20914350fb | ||
|
|
8b411663cf | ||
|
|
01292939d3 | ||
|
|
dcc5889677 | ||
|
|
04828df028 | ||
|
|
2f95139c77 | ||
|
|
f2bb3667c4 | ||
|
|
791da48673 | ||
|
|
f683bcbd59 | ||
|
|
15b8b1f358 | ||
|
|
a20592ecd1 | ||
|
|
ed1aa3d5be | ||
|
|
8e66110374 | ||
|
|
f5f65aa868 | ||
|
|
4e5fcf211b | ||
|
|
9789069c0d | ||
|
|
1cf45ac0c5 | ||
|
|
40fe21f909 | ||
|
|
e6bdf075ca | ||
|
|
7c76e57bf4 | ||
|
|
7fe038b697 | ||
|
|
c01c69db3b | ||
|
|
0e996e74c9 | ||
|
|
1371159f0b | ||
|
|
44b38dce74 | ||
|
|
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 |
6
.github/FUNDING.yml
vendored
6
.github/FUNDING.yml
vendored
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
patreon: # Replace with a single Patreon username
|
patreon: # Replace with a single Patreon username
|
||||||
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
|
||||||
|
open_collective: 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
|
||||||
110
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
110
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
name: Issue Report
|
||||||
|
description: File an issue report
|
||||||
|
title: "[issue]: "
|
||||||
|
assignees:
|
||||||
|
- octocat
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this issue report!
|
||||||
|
- type: checkboxes
|
||||||
|
id: faq
|
||||||
|
attributes:
|
||||||
|
label: Official FAQ
|
||||||
|
description: Have you checked the official FAQ at [https://www.ventoy.net/en/faq.html](https://www.ventoy.net/en/faq.html) ?
|
||||||
|
options:
|
||||||
|
- label: I have checked the official FAQ.
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Ventoy Version
|
||||||
|
description: What version of ventoy are you running?
|
||||||
|
placeholder: 1.0.96
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: latestrelease
|
||||||
|
attributes:
|
||||||
|
label: What about latest release
|
||||||
|
description: Have you tried with the latest release of Ventoy?
|
||||||
|
options:
|
||||||
|
- Yes. I have tried the latest release, but the bug still exist.
|
||||||
|
- No. I didn't try the latest release.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: alternativemode
|
||||||
|
attributes:
|
||||||
|
label: Try alternative boot mode
|
||||||
|
description: Have you tried alternative boot mode? (wimboot mode for Windows/WinPE, grub2 mode for linux)
|
||||||
|
options:
|
||||||
|
- Yes. I have tried them, but the bug still exist.
|
||||||
|
- No. I didn't try these alternative boot modes.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: bios
|
||||||
|
attributes:
|
||||||
|
label: BIOS Mode
|
||||||
|
description: In which BIOS mode did you find the bug?
|
||||||
|
options:
|
||||||
|
- Legacy BIOS Mode
|
||||||
|
- UEFI Mode
|
||||||
|
- Both
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: partstyle
|
||||||
|
attributes:
|
||||||
|
label: Partition Style
|
||||||
|
description: Which partition style did you select when you install Ventoy?
|
||||||
|
options:
|
||||||
|
- MBR
|
||||||
|
- GPT
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: capacity
|
||||||
|
attributes:
|
||||||
|
label: Disk Capacity
|
||||||
|
description: What is the capacity of the disk installed with Ventoy?
|
||||||
|
placeholder: 32GB
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: vendor
|
||||||
|
attributes:
|
||||||
|
label: Disk Manufacturer
|
||||||
|
description: What is the manufacturer of the disk installed with Ventoy? (e.g. SanDisk/Kingston...)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: dropdown
|
||||||
|
id: checksum
|
||||||
|
attributes:
|
||||||
|
label: Image file checksum (if applicable)
|
||||||
|
description: Have you checked the image file in Ventoy's menu as [https://www.ventoy.net/en/faq.html#faq_boot_checksum](https://www.ventoy.net/en/faq.html#faq_boot_checksum) ?
|
||||||
|
options:
|
||||||
|
- Yes.
|
||||||
|
- No.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: link
|
||||||
|
attributes:
|
||||||
|
label: Image file download link (if applicable)
|
||||||
|
description: What is the image file download link?
|
||||||
|
placeholder: https://xxx
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: Tell me what happened. It's highly recommended to include some photo or video about the bug.
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
value: "A bug happened!"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
101
.github/ISSUE_TEMPLATE/success_image_report.yml
vendored
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 environment
|
||||||
|
description: The manufacturer/model and other details about your computer (or VM).
|
||||||
|
placeholder: Lenovo Thinkpad T420 laptop
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: details
|
||||||
|
attributes:
|
||||||
|
label: More Details?
|
||||||
|
description: You can give more details here.
|
||||||
|
value: "This image file booted successfully in Ventoy."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
31
.github/workflows/ci.yml
vendored
31
.github/workflows/ci.yml
vendored
@@ -6,19 +6,32 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Run docker-compose up
|
- name: Run docker compose up
|
||||||
run: docker-compose up
|
run: docker compose up
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
|
||||||
name: ventoy-linux
|
|
||||||
path: INSTALL/ventoy-*linux*
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
with:
|
||||||
name: ventoy-windows
|
name: ventoy-windows
|
||||||
path: INSTALL/ventoy-*windows*
|
path: INSTALL/ventoy-*windows*
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ventoy-linux
|
||||||
|
path: INSTALL/ventoy-*linux*
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ventoy-livecd
|
||||||
|
path: INSTALL/ventoy-*livecd*
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: SHA256SUM
|
||||||
|
path: INSTALL/sha256.txt
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: xxx-build-log
|
||||||
|
path: DOC/build.log
|
||||||
|
|||||||
25
.github/workflows/sync2gitee.yml
vendored
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
|
||||||
@@ -13,6 +13,25 @@ ARCH=arm64 CROSS_COMPILE=aarch64-linux- make
|
|||||||
rename ./busybox to xzcat
|
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 build ash/hexdump/xzcat for x86_64 ==========
|
||||||
#How to get ash.config/hexdump.cofig/xzcat.config
|
#How to get ash.config/hexdump.cofig/xzcat.config
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
DSTDIR=../../IMG/cpio/ventoy/busybox
|
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 vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64
|
||||||
rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64
|
rm -f $DSTDIR1/vtchmod32 $DSTDIR1/vtchmod64 $DSTDIR2/vtchmodaa64 $DSTDIR3/vtchmodm64e
|
||||||
|
|
||||||
/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32
|
/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32
|
||||||
/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64
|
/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64
|
||||||
aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64
|
aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64
|
||||||
aarch64-linux-strip --strip-all 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
|
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static vtchmod.c -o vtchmod64_musl
|
||||||
strip --strip-all vtchmod64_musl
|
strip --strip-all vtchmod64_musl
|
||||||
|
|
||||||
@@ -17,9 +23,11 @@ chmod 777 vtchmod32
|
|||||||
chmod 777 vtchmod64
|
chmod 777 vtchmod64
|
||||||
chmod 777 vtchmodaa64
|
chmod 777 vtchmodaa64
|
||||||
chmod 777 vtchmod64_musl
|
chmod 777 vtchmod64_musl
|
||||||
|
chmod 777 vtchmodm64e
|
||||||
|
|
||||||
cp -a vtchmod32 $DSTDIR/
|
cp -a vtchmod32 $DSTDIR1/
|
||||||
cp -a vtchmod64 $DSTDIR/
|
cp -a vtchmod64 $DSTDIR1/
|
||||||
cp -a vtchmodaa64 $DSTDIR/
|
cp -a vtchmod64_musl $DSTDIR1/
|
||||||
cp -a vtchmod64_musl $DSTDIR/
|
cp -a vtchmodaa64 $DSTDIR2/
|
||||||
|
cp -a vtchmodm64e $DSTDIR3/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -8,6 +11,24 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
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);
|
return chmod(argv[1], 0777);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
BUSYBOX/chmod/vtchmodm64e
Normal file
BIN
BUSYBOX/chmod/vtchmodm64e
Normal file
Binary file not shown.
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
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
|
||||||
|
|
||||||
7
DMPATCH/Makefile_IBT
Normal file
7
DMPATCH/Makefile_IBT
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
obj-m += dm_patch_ibt.o
|
||||||
|
|
||||||
|
EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register
|
||||||
|
|
||||||
|
dm_patch_ibt-objs := dmpatch.o
|
||||||
|
|
||||||
632
DMPATCH/dmpatch.c
Normal file
632
DMPATCH/dmpatch.c
Normal file
@@ -0,0 +1,632 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* dmpatch.c ---- patch for device-mapper
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/mempool.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#define MAX_PATCH 4
|
||||||
|
|
||||||
|
#define magic_sig 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
|
||||||
|
|
||||||
|
typedef int (*kprobe_reg_pf)(void *);
|
||||||
|
typedef void (*kprobe_unreg_pf)(void *);
|
||||||
|
typedef int (*printk_pf)(const char *fmt, ...);
|
||||||
|
typedef int (*set_memory_attr_pf)(unsigned long addr, int numpages);
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct ko_param
|
||||||
|
{
|
||||||
|
unsigned char magic[16];
|
||||||
|
unsigned long struct_size;
|
||||||
|
unsigned long pgsize;
|
||||||
|
unsigned long printk_addr;
|
||||||
|
unsigned long ro_addr;
|
||||||
|
unsigned long rw_addr;
|
||||||
|
unsigned long reg_kprobe_addr;
|
||||||
|
unsigned long unreg_kprobe_addr;
|
||||||
|
unsigned long sym_get_addr;
|
||||||
|
unsigned long sym_get_size;
|
||||||
|
unsigned long sym_put_addr;
|
||||||
|
unsigned long sym_put_size;
|
||||||
|
unsigned long kv_major;
|
||||||
|
unsigned long ibt;
|
||||||
|
unsigned long kv_minor;
|
||||||
|
unsigned long blkdev_get_addr;
|
||||||
|
unsigned long blkdev_put_addr;
|
||||||
|
unsigned long bdev_open_addr;
|
||||||
|
unsigned long kv_subminor;
|
||||||
|
unsigned long bdev_file_open_addr;
|
||||||
|
unsigned long padding[1];
|
||||||
|
}ko_param;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
static printk_pf kprintf = NULL;
|
||||||
|
static set_memory_attr_pf set_mem_ro = NULL;
|
||||||
|
static set_memory_attr_pf set_mem_rw = NULL;
|
||||||
|
static kprobe_reg_pf reg_kprobe = NULL;
|
||||||
|
static kprobe_unreg_pf unreg_kprobe = NULL;
|
||||||
|
|
||||||
|
static volatile ko_param g_ko_param =
|
||||||
|
{
|
||||||
|
{ magic_sig },
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_X86_64)
|
||||||
|
#define PATCH_OP_POS1 3
|
||||||
|
#define CODE_MATCH1(code, i) \
|
||||||
|
(code[i] == 0x40 && code[i + 1] == 0x80 && code[i + 2] == 0xce && code[i + 3] == 0x80)
|
||||||
|
|
||||||
|
#define PATCH_OP_POS2 1
|
||||||
|
#define CODE_MATCH2(code, i) \
|
||||||
|
(code[i] == 0x0C && code[i + 1] == 0x80 && code[i + 2] == 0x89 && code[i + 3] == 0xC6)
|
||||||
|
|
||||||
|
#define PATCH_OP_POS3 4
|
||||||
|
#define CODE_MATCH3(code, i) \
|
||||||
|
(code[i] == 0x44 && code[i + 1] == 0x89 && code[i + 2] == 0xe8 && code[i + 3] == 0x0c && code[i + 4] == 0x80)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(CONFIG_X86_32)
|
||||||
|
#define PATCH_OP_POS1 2
|
||||||
|
#define CODE_MATCH1(code, i) \
|
||||||
|
(code[i] == 0x80 && code[i + 1] == 0xca && code[i + 2] == 0x80 && code[i + 3] == 0xe8)
|
||||||
|
|
||||||
|
#define PATCH_OP_POS2 PATCH_OP_POS1
|
||||||
|
#define CODE_MATCH2 CODE_MATCH1
|
||||||
|
#define PATCH_OP_POS3 PATCH_OP_POS1
|
||||||
|
#define CODE_MATCH3 CODE_MATCH1
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "unsupported arch"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VTOY_IBT
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
/* Using 64-bit values saves one instruction clearing the high half of low */
|
||||||
|
#define DECLARE_ARGS(val, low, high) unsigned long low, high
|
||||||
|
#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32)
|
||||||
|
#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
|
||||||
|
#else
|
||||||
|
#define DECLARE_ARGS(val, low, high) unsigned long long val
|
||||||
|
#define EAX_EDX_VAL(val, low, high) (val)
|
||||||
|
#define EAX_EDX_RET(val, low, high) "=A" (val)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EX_TYPE_WRMSR 8
|
||||||
|
#define EX_TYPE_RDMSR 9
|
||||||
|
#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */
|
||||||
|
#define CET_ENDBR_EN (1ULL << 2)
|
||||||
|
|
||||||
|
/* Exception table entry */
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
|
#define _ASM_EXTABLE_TYPE(from, to, type) \
|
||||||
|
.pushsection "__ex_table","a" ; \
|
||||||
|
.balign 4 ; \
|
||||||
|
.long (from) - . ; \
|
||||||
|
.long (to) - . ; \
|
||||||
|
.long type ; \
|
||||||
|
.popsection
|
||||||
|
|
||||||
|
#else /* ! __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#define _ASM_EXTABLE_TYPE(from, to, type) \
|
||||||
|
" .pushsection \"__ex_table\",\"a\"\n" \
|
||||||
|
" .balign 4\n" \
|
||||||
|
" .long (" #from ") - .\n" \
|
||||||
|
" .long (" #to ") - .\n" \
|
||||||
|
" .long " __stringify(type) " \n" \
|
||||||
|
" .popsection\n"
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
#endif /* VTOY_IBT */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
|
||||||
|
|
||||||
|
static unsigned int g_claim_ptr = 0;
|
||||||
|
static unsigned char *g_get_patch[MAX_PATCH] = { NULL };
|
||||||
|
static unsigned char *g_put_patch[MAX_PATCH] = { NULL };
|
||||||
|
|
||||||
|
static int notrace dmpatch_kv_above(unsigned long Major, unsigned long Minor, unsigned long SubMinor)
|
||||||
|
{
|
||||||
|
if (g_ko_param.kv_major != Major)
|
||||||
|
{
|
||||||
|
return (g_ko_param.kv_major > Major) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ko_param.kv_minor != Minor)
|
||||||
|
{
|
||||||
|
return (g_ko_param.kv_minor > Minor) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ko_param.kv_subminor != SubMinor)
|
||||||
|
{
|
||||||
|
return (g_ko_param.kv_subminor > SubMinor) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notrace dmpatch_restore_code(int bytes, unsigned char *opCode, unsigned int code)
|
||||||
|
{
|
||||||
|
unsigned long align;
|
||||||
|
|
||||||
|
if (opCode)
|
||||||
|
{
|
||||||
|
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||||
|
set_mem_rw(align, 1);
|
||||||
|
if (bytes == 1)
|
||||||
|
{
|
||||||
|
*opCode = (unsigned char)code;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(unsigned int *)opCode = code;
|
||||||
|
}
|
||||||
|
set_mem_ro(align, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int notrace dmpatch_replace_code
|
||||||
|
(
|
||||||
|
int style,
|
||||||
|
unsigned long addr,
|
||||||
|
unsigned long size,
|
||||||
|
int expect,
|
||||||
|
const char *desc,
|
||||||
|
unsigned char **patch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
unsigned long align;
|
||||||
|
unsigned char *opCode = (unsigned char *)addr;
|
||||||
|
|
||||||
|
vdebug("patch for %s style[%d] 0x%lx %d\n", desc, style, addr, (int)size);
|
||||||
|
|
||||||
|
for (i = 0; i < (int)size - 8; i++)
|
||||||
|
{
|
||||||
|
if (style == 1)
|
||||||
|
{
|
||||||
|
if (CODE_MATCH1(opCode, i) && cnt < MAX_PATCH)
|
||||||
|
{
|
||||||
|
patch[cnt] = opCode + i + PATCH_OP_POS1;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (style == 2)
|
||||||
|
{
|
||||||
|
if (CODE_MATCH2(opCode, i) && cnt < MAX_PATCH)
|
||||||
|
{
|
||||||
|
patch[cnt] = opCode + i + PATCH_OP_POS2;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (style == 3)
|
||||||
|
{
|
||||||
|
if (CODE_MATCH3(opCode, i) && cnt < MAX_PATCH)
|
||||||
|
{
|
||||||
|
patch[cnt] = opCode + i + PATCH_OP_POS3;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (cnt != expect || cnt >= MAX_PATCH)
|
||||||
|
{
|
||||||
|
vdebug("patch error: cnt=%d expect=%d\n", cnt, expect);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < cnt; i++)
|
||||||
|
{
|
||||||
|
opCode = patch[i];
|
||||||
|
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||||
|
|
||||||
|
set_mem_rw(align, 1);
|
||||||
|
*opCode = 0;
|
||||||
|
set_mem_ro(align, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long notrace dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func)
|
||||||
|
{
|
||||||
|
unsigned long i = 0;
|
||||||
|
unsigned long dest;
|
||||||
|
unsigned char *opCode = NULL;
|
||||||
|
unsigned char aucOffset[8] = { 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
|
opCode = (unsigned char *)addr;
|
||||||
|
|
||||||
|
for (i = 0; i + 4 < size; i++)
|
||||||
|
{
|
||||||
|
if (opCode[i] == 0xE8)
|
||||||
|
{
|
||||||
|
aucOffset[0] = opCode[i + 1];
|
||||||
|
aucOffset[1] = opCode[i + 2];
|
||||||
|
aucOffset[2] = opCode[i + 3];
|
||||||
|
aucOffset[3] = opCode[i + 4];
|
||||||
|
|
||||||
|
dest = addr + i + 5 + *(unsigned long *)aucOffset;
|
||||||
|
if (dest == func)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int notrace dmpatch_patch_claim_ptr(void)
|
||||||
|
{
|
||||||
|
unsigned long i = 0;
|
||||||
|
unsigned long t = 0;
|
||||||
|
unsigned long offset1 = 0;
|
||||||
|
unsigned long offset2 = 0;
|
||||||
|
unsigned long align = 0;
|
||||||
|
unsigned char *opCode = NULL;
|
||||||
|
|
||||||
|
opCode = (unsigned char *)g_ko_param.sym_get_addr;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
vdebug("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||||
|
opCode[i + 0], opCode[i + 1], opCode[i + 2], opCode[i + 3],
|
||||||
|
opCode[i + 4], opCode[i + 5], opCode[i + 6], opCode[i + 7],
|
||||||
|
opCode[i + 8], opCode[i + 9], opCode[i + 10], opCode[i + 11],
|
||||||
|
opCode[i + 12], opCode[i + 13], opCode[i + 14], opCode[i + 15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmpatch_kv_above(6, 7, 0)) /* >= 6.7 kernel */
|
||||||
|
{
|
||||||
|
vdebug("Get addr: 0x%lx %lu open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
|
||||||
|
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
|
||||||
|
if (offset1 == 0)
|
||||||
|
{
|
||||||
|
vdebug("call bdev_open_addr Not found\n");
|
||||||
|
|
||||||
|
vdebug("Get addr: 0x%lx %lu file_open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
|
||||||
|
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
|
||||||
|
if (offset1 == 0)
|
||||||
|
{
|
||||||
|
vdebug("call bdev_file_open_addr Not found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
|
||||||
|
vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
|
||||||
|
|
||||||
|
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
|
||||||
|
offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
|
||||||
|
if (offset1 == 0 || offset2 == 0)
|
||||||
|
{
|
||||||
|
vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vdebug("call addr1:0x%lx call addr2:0x%lx\n",
|
||||||
|
g_ko_param.sym_get_addr + offset1,
|
||||||
|
g_ko_param.sym_put_addr + offset2);
|
||||||
|
|
||||||
|
opCode = (unsigned char *)g_ko_param.sym_get_addr;
|
||||||
|
for (i = offset1 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
|
||||||
|
{
|
||||||
|
/* rdx */
|
||||||
|
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc2)
|
||||||
|
{
|
||||||
|
g_claim_ptr = *(unsigned int *)(opCode + i + 3);
|
||||||
|
g_get_patch[0] = opCode + i + 3;
|
||||||
|
vdebug("claim_ptr(%08X) found at get addr 0x%lx\n", g_claim_ptr, g_ko_param.sym_get_addr + i + 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_claim_ptr == 0)
|
||||||
|
{
|
||||||
|
vdebug("Claim_ptr not found in get\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
align = (unsigned long)g_get_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||||
|
set_mem_rw(align, 1);
|
||||||
|
*(unsigned int *)(g_get_patch[0]) = 0;
|
||||||
|
set_mem_ro(align, 1);
|
||||||
|
|
||||||
|
|
||||||
|
if (offset2 > 0)
|
||||||
|
{
|
||||||
|
opCode = (unsigned char *)g_ko_param.sym_put_addr;
|
||||||
|
for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
|
||||||
|
{
|
||||||
|
/* rsi */
|
||||||
|
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6)
|
||||||
|
{
|
||||||
|
if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr)
|
||||||
|
{
|
||||||
|
vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3);
|
||||||
|
g_put_patch[0] = opCode + i + 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_put_patch[0] == 0)
|
||||||
|
{
|
||||||
|
vdebug("Claim_ptr not found in put\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
|
||||||
|
set_mem_rw(align, 1);
|
||||||
|
*(unsigned int *)(g_put_patch[0]) = 0;
|
||||||
|
set_mem_ro(align, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VTOY_IBT
|
||||||
|
static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr)
|
||||||
|
{
|
||||||
|
DECLARE_ARGS(val, low, high);
|
||||||
|
|
||||||
|
asm volatile("1: rdmsr\n"
|
||||||
|
"2:\n"
|
||||||
|
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR)
|
||||||
|
: EAX_EDX_RET(val, low, high) : "c" (msr));
|
||||||
|
|
||||||
|
return EAX_EDX_VAL(val, low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void dmpatch_wrmsr(unsigned int msr, u32 low, u32 high)
|
||||||
|
{
|
||||||
|
asm volatile("1: wrmsr\n"
|
||||||
|
"2:\n"
|
||||||
|
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
|
||||||
|
: : "c" (msr), "a"(low), "d" (high) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 notrace dmpatch_ibt_save(void)
|
||||||
|
{
|
||||||
|
u64 msr = 0;
|
||||||
|
u64 val = 0;
|
||||||
|
|
||||||
|
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
|
||||||
|
val = msr & ~CET_ENDBR_EN;
|
||||||
|
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(val & 0xffffffffULL), (u32)(val >> 32));
|
||||||
|
|
||||||
|
return msr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notrace dmpatch_ibt_restore(u64 save)
|
||||||
|
{
|
||||||
|
u64 msr;
|
||||||
|
|
||||||
|
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
|
||||||
|
|
||||||
|
msr &= ~CET_ENDBR_EN;
|
||||||
|
msr |= (save & CET_ENDBR_EN);
|
||||||
|
|
||||||
|
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(msr & 0xffffffffULL), (u32)(msr >> 32));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static u64 notrace dmpatch_ibt_save(void) { return 0; }
|
||||||
|
static void notrace dmpatch_ibt_restore(u64 save) { (void)save; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int notrace dmpatch_process(unsigned long a, unsigned long b, unsigned long c)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
int rc = 0;
|
||||||
|
unsigned long kv_major = 0;
|
||||||
|
unsigned long kv_minor = 0;
|
||||||
|
unsigned long kv_subminor = 0;
|
||||||
|
|
||||||
|
vdebug("dmpatch_process as KV %d.%d.%d ...\n", (int)a, (int)b, (int)c);
|
||||||
|
|
||||||
|
kv_major = g_ko_param.kv_major;
|
||||||
|
kv_minor = g_ko_param.kv_minor;
|
||||||
|
kv_subminor = g_ko_param.kv_subminor;
|
||||||
|
|
||||||
|
g_ko_param.kv_major = a;
|
||||||
|
g_ko_param.kv_minor = b;
|
||||||
|
g_ko_param.kv_subminor = c;
|
||||||
|
|
||||||
|
if (dmpatch_kv_above(6, 5, 0)) /* >= kernel 6.5 */
|
||||||
|
{
|
||||||
|
vdebug("new interface patch dm_get_table_device...\n");
|
||||||
|
r = dmpatch_patch_claim_ptr();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = dmpatch_replace_code(1, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device", g_get_patch);
|
||||||
|
if (r && g_ko_param.kv_major >= 5)
|
||||||
|
{
|
||||||
|
vdebug("new2 patch dm_get_table_device...\n");
|
||||||
|
r = dmpatch_replace_code(2, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r && g_ko_param.kv_major >= 5)
|
||||||
|
{
|
||||||
|
vdebug("new3 patch dm_get_table_device...\n");
|
||||||
|
r = dmpatch_replace_code(3, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
rc = -EFAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
vdebug("patch dm_get_table_device success\n");
|
||||||
|
|
||||||
|
if (dmpatch_kv_above(6, 5, 0))
|
||||||
|
{
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
rc = -EFAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
vdebug("patch dm_put_table_device success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
vdebug("#####################################\n");
|
||||||
|
vdebug("######## dm patch success ###########\n");
|
||||||
|
vdebug("#####################################\n");
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
g_ko_param.kv_major = kv_major;
|
||||||
|
g_ko_param.kv_minor = kv_minor;
|
||||||
|
g_ko_param.kv_subminor = kv_subminor;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int notrace dmpatch_init(void)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
u64 msr = 0;
|
||||||
|
|
||||||
|
if (g_ko_param.ibt == 0x8888)
|
||||||
|
{
|
||||||
|
msr = dmpatch_ibt_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf = (printk_pf)(g_ko_param.printk_addr);
|
||||||
|
|
||||||
|
vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu.%lu ...\n",
|
||||||
|
g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
|
||||||
|
|
||||||
|
if (g_ko_param.struct_size != sizeof(ko_param))
|
||||||
|
{
|
||||||
|
vdebug("Invalid struct size %d %d\n", (int)g_ko_param.struct_size, (int)sizeof(ko_param));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ko_param.sym_get_addr == 0 || g_ko_param.sym_put_addr == 0 ||
|
||||||
|
g_ko_param.ro_addr == 0 || g_ko_param.rw_addr == 0)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mem_ro = (set_memory_attr_pf)(g_ko_param.ro_addr);
|
||||||
|
set_mem_rw = (set_memory_attr_pf)(g_ko_param.rw_addr);
|
||||||
|
reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr;
|
||||||
|
unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr;
|
||||||
|
|
||||||
|
rc = dmpatch_process(g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
if (g_ko_param.kv_major >= 5)
|
||||||
|
{
|
||||||
|
rc = dmpatch_process(6, 5, 0);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
rc = dmpatch_process(6, 7, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ko_param.ibt == 0x8888)
|
||||||
|
{
|
||||||
|
dmpatch_ibt_restore(msr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notrace dmpatch_exit(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
u64 msr;
|
||||||
|
|
||||||
|
if (g_ko_param.ibt == 0x8888)
|
||||||
|
{
|
||||||
|
msr = dmpatch_ibt_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_claim_ptr)
|
||||||
|
{
|
||||||
|
dmpatch_restore_code(4, g_get_patch[0], g_claim_ptr);
|
||||||
|
if (g_put_patch[0])
|
||||||
|
{
|
||||||
|
dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < MAX_PATCH; i++)
|
||||||
|
{
|
||||||
|
dmpatch_restore_code(1, g_get_patch[i], 0x80);
|
||||||
|
dmpatch_restore_code(1, g_put_patch[i], 0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vdebug("dmpatch_exit success\n");
|
||||||
|
|
||||||
|
if (g_ko_param.ibt == 0x8888)
|
||||||
|
{
|
||||||
|
dmpatch_ibt_restore(msr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(dmpatch_init);
|
||||||
|
module_exit(dmpatch_exit);
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("dmpatch driver");
|
||||||
|
MODULE_AUTHOR("longpanda <admin@ventoy.net>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
38
DMPATCH/readme.txt
Normal file
38
DMPATCH/readme.txt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
1. install ubuntu 22.04 5.15.0-25
|
||||||
|
2. apt-get install build-essential flex libncurses-dev linux-headers-generic linux-source libssl-dev bison yacc vim libelf-dev ...... and so on
|
||||||
|
3. cp /lib/modules/5.15.0-25-generic/build/Module.symvers ./
|
||||||
|
4. /boot/config-5.15.0-25-generic as .config make oldconfig
|
||||||
|
5. make menuconfig
|
||||||
|
1. close CONFIG_STACKPROTECTOR
|
||||||
|
2. close CONFIG_RETPOLINE
|
||||||
|
3. close CONFIG_UBSAN_BOUNDS
|
||||||
|
4. close CONFIG_UBSAN_ENUM
|
||||||
|
|
||||||
|
6. modify ./scripts/mod/modpost.c
|
||||||
|
1. skip add_srcversion (just return)
|
||||||
|
2. force add_retpoline (#ifdef --> #ifndef)
|
||||||
|
3. force add_intree_flag
|
||||||
|
|
||||||
|
7. make modules_prepare LOCALVERSION=-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
|
||||||
|
8. Append padding at the end of struct module <include/linux/module.h>
|
||||||
|
struct module {
|
||||||
|
enum module_state state;
|
||||||
|
|
||||||
|
/* Member of list of modules */
|
||||||
|
struct list_head list;
|
||||||
|
|
||||||
|
/* Unique handle for this module */
|
||||||
|
char name[MODULE_NAME_LEN];
|
||||||
|
|
||||||
|
....
|
||||||
|
|
||||||
|
char padding[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
This is because struct module size is different in different kernel versions or with different CONFIG item.
|
||||||
|
|
||||||
|
|
||||||
|
9. make modules M=/home/dmpatch
|
||||||
|
10. strip --strip-debug /home/dmpatch/dm_patch.ko
|
||||||
|
|
||||||
65
DMPATCH/ubuntu_build.sh
Normal file
65
DMPATCH/ubuntu_build.sh
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FTPIP=192.168.44.1
|
||||||
|
FTPUSR='a:a'
|
||||||
|
|
||||||
|
rm -f dmpatch.c Makefile Makefile_IBT
|
||||||
|
|
||||||
|
for f in dmpatch.c Makefile Makefile_IBT; do
|
||||||
|
curl -s -u $FTPUSR ftp://$FTPIP/$f -o $f
|
||||||
|
if [ -f $f ]; then
|
||||||
|
echo "download $f OK ..."
|
||||||
|
else
|
||||||
|
echo "download $f FAILED ..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rm -f *.ko
|
||||||
|
|
||||||
|
|
||||||
|
echo "build dm_patch.ko ..."
|
||||||
|
rm -rf ./aa
|
||||||
|
mkdir ./aa
|
||||||
|
|
||||||
|
cp -a *.c aa/
|
||||||
|
cp -a Makefile aa/
|
||||||
|
|
||||||
|
cd /home/panda/linux-source-5.15.0
|
||||||
|
make modules M=/home/panda/build/aa/
|
||||||
|
strip --strip-debug /home/panda/build/aa/dm_patch.ko
|
||||||
|
cd -
|
||||||
|
|
||||||
|
cp -a aa/dm_patch.ko ./
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "build dm_patch_ibt.ko ..."
|
||||||
|
rm -rf ./aa
|
||||||
|
mkdir ./aa
|
||||||
|
|
||||||
|
cp -a *.c aa/
|
||||||
|
cp -a Makefile_IBT aa/Makefile
|
||||||
|
|
||||||
|
cd /home/panda/linux-source-5.15.0
|
||||||
|
make modules M=/home/panda/build/aa/
|
||||||
|
strip --strip-debug /home/panda/build/aa/dm_patch_ibt.ko
|
||||||
|
cd -
|
||||||
|
|
||||||
|
cp -a aa/dm_patch_ibt.ko ./
|
||||||
|
|
||||||
|
rm -rf ./aa
|
||||||
|
|
||||||
|
|
||||||
|
curl -s -T dm_patch.ko -u $FTPUSR ftp://$FTPIP/dm_patch_64.ko || exit 1
|
||||||
|
curl -s -T dm_patch_ibt.ko -u $FTPUSR ftp://$FTPIP/dm_patch_ibt_64.ko || exit 1
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f ./dm_patch.ko -a -f ./dm_patch_ibt.ko ]; then
|
||||||
|
echo -e "\n\n=============== SUCCESS =============\n\n"
|
||||||
|
else
|
||||||
|
echo -e "\n\n=============== FAILED ==============\n\n"
|
||||||
|
fi
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ use an old version of dmsetup
|
|||||||
http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm
|
http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm
|
||||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz
|
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz
|
||||||
|
|
||||||
======== Build Envrioment ========
|
======== Build Environment ========
|
||||||
build for 32bit, static linked with dietlibc
|
build for 32bit, static linked with dietlibc
|
||||||
1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso
|
1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso
|
||||||
2. yum install gcc kernel-devel package
|
2. yum install gcc kernel-devel package
|
||||||
@@ -55,6 +55,16 @@ build for 32bit, static linked with dietlibc
|
|||||||
6. get dmsetup/dmsetup.static as the dmsetupaa64 binary file
|
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/dmsetupm64e
Normal file
BIN
DMSETUP/dmsetupm64e
Normal file
Binary file not shown.
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
==========================================
|
==========================================
|
||||||
1. Compile Enviroment
|
1. Compile Environment
|
||||||
==========================================
|
==========================================
|
||||||
My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch.
|
My build environment 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 environment is important. I suggest you test it on a virtual machine first.
|
Ventoy is based on many open source projects, so the build environment is important. I suggest you first test it on a virtual machine.
|
||||||
|
|
||||||
1.1 Install CentOS 7.8
|
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,17 +14,17 @@
|
|||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==========================================
|
==========================================
|
||||||
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-party source code and tool
|
||||||
|
|
||||||
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz
|
https://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://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz
|
||||||
@@ -34,8 +34,15 @@
|
|||||||
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://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
|
||||||
https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2
|
https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2
|
||||||
|
https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz
|
||||||
|
https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2
|
||||||
|
|
||||||
2.3 Prepare third-part tools
|
|
||||||
|
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/vmlinuz64 ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/vmlinuz64
|
||||||
|
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz
|
||||||
|
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz
|
||||||
|
|
||||||
|
2.3 Prepare third-party tools
|
||||||
cd /home/Ventoy-master/DOC/
|
cd /home/Ventoy-master/DOC/
|
||||||
tar xf musl-1.2.1.tar.gz
|
tar xf musl-1.2.1.tar.gz
|
||||||
cd musl-1.2.1
|
cd musl-1.2.1
|
||||||
@@ -43,28 +50,33 @@
|
|||||||
|
|
||||||
tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt
|
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/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
|
2.4 Set PATH environment
|
||||||
|
export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin
|
||||||
better to add this line to /root/.bashrc and relogin as root
|
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 an all-in-one script `all_in_one.sh`. You can run this script to build and pack ventoy.
|
||||||
If you want to compile a certain part separately, you can continue to refer to the later chapters of this text.
|
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:
|
||||||
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.
|
1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other parts contain binaries and are rarely modified, so will not be recompiled everytime.
|
||||||
Fortunately these parts are few modified, you only need to build once or you can directly use the binary I have built.
|
You can rebuild these parts separately if you want.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
2. Some parts of Ventoy have a 32-bit and 64-bit version (like 4.9, 4.10, 4.11 follows)
|
||||||
|
all_in_one.sh only builds the 64bit version of them. If you want to rebuild the 32bit verison, you should create a 32-bit CentOS environment and build them.
|
||||||
|
Fortunately these parts are rarely modified, so you only need to build once or you can directly use the binaries I have built.
|
||||||
|
|
||||||
|
Besides, after a full compile and packaging, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package.
|
||||||
|
|
||||||
==========================================
|
==========================================
|
||||||
4. Build every part of Ventoy
|
4. Build every part of Ventoy
|
||||||
@@ -96,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 ==
|
||||||
@@ -110,14 +122,14 @@
|
|||||||
After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64
|
After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64
|
||||||
After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64
|
After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64
|
||||||
|
|
||||||
Use the same build step to build exfat-util 32bit in a 32bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32
|
Use the same build step to build exfat-util 32-bit in a 32-bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32
|
||||||
|
|
||||||
4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 ==
|
4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 ==
|
||||||
cd /home/Ventoy-master/FUSEISO
|
cd /home/Ventoy-master/FUSEISO
|
||||||
sh build_libfuse.sh
|
sh build_libfuse.sh
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
Use the same build step to build in a 32bit CentOS system and get vtoy_fuse_iso_32
|
Use the same build step to build in a 32-bit CentOS system and get vtoy_fuse_iso_32
|
||||||
|
|
||||||
4.11 == Build unsquashfs_64/unsquashfs_32 ==
|
4.11 == Build unsquashfs_64/unsquashfs_32 ==
|
||||||
cd /home/Ventoy-master/SQUASHFS/SRC
|
cd /home/Ventoy-master/SQUASHFS/SRC
|
||||||
@@ -129,7 +141,7 @@
|
|||||||
cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools
|
cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
Use the same build step to build in a 32bit CentOS system and get unsquashfs_32
|
Use the same build step to build in a 32-bit CentOS system and get unsquashfs_32
|
||||||
|
|
||||||
4.12 == Build vblade_64/vblade_32 ==
|
4.12 == Build vblade_64/vblade_32 ==
|
||||||
cd /home/Ventoy-master/VBLADE/vblade-master
|
cd /home/Ventoy-master/VBLADE/vblade-master
|
||||||
|
|||||||
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
|
||||||
20
Dockerfile
20
Dockerfile
@@ -1,17 +1,15 @@
|
|||||||
FROM centos:7
|
FROM centos:7
|
||||||
|
|
||||||
RUN yum -y install \
|
RUN sed -i \
|
||||||
|
-e 's/^mirrorlist/#mirrorlist/' \
|
||||||
|
-e 's/^#baseurl/baseurl/' \
|
||||||
|
-e 's/mirror\.centos\.org/vault.centos.org/' \
|
||||||
|
/etc/yum.repos.d/*.repo && \
|
||||||
|
yum -y -q install \
|
||||||
libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \
|
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,14 +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 gDotEfiBoot = FALSE;
|
||||||
BOOLEAN gLoadIsoEfi = FALSE;
|
BOOLEAN gLoadIsoEfi = FALSE;
|
||||||
BOOLEAN gIsoUdf = 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;
|
||||||
@@ -56,6 +59,9 @@ 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[VTOY_MAX_CONF_REPLACE];
|
||||||
|
|
||||||
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
|
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
|
||||||
CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH;
|
CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH;
|
||||||
|
|
||||||
@@ -65,6 +71,9 @@ 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[] =
|
||||||
@@ -220,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();
|
||||||
@@ -269,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)
|
||||||
{
|
{
|
||||||
@@ -359,11 +371,23 @@ 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));
|
||||||
@@ -377,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));
|
||||||
@@ -404,10 +445,20 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -526,10 +577,11 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 &&
|
||||||
|
CompareMem(g_chain->os_param.vtoy_disk_signature, pBuffer + 0x1b8, 4) == 0)
|
||||||
{
|
{
|
||||||
pMBR = (MBR_HEAD *)pBuffer;
|
pMBR = (MBR_HEAD *)pBuffer;
|
||||||
if (pMBR->PartTbl[0].FsFlag != 0xEE)
|
if (g_os_param_reserved[6] == 0 && pMBR->PartTbl[0].FsFlag != 0xEE)
|
||||||
{
|
{
|
||||||
if (pMBR->PartTbl[0].StartSectorId != 2048 ||
|
if (pMBR->PartTbl[0].StartSectorId != 2048 ||
|
||||||
pMBR->PartTbl[1].SectorCount != 65536 ||
|
pMBR->PartTbl[1].SectorCount != 65536 ||
|
||||||
@@ -548,7 +600,7 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
|
|||||||
Handles[i],
|
Handles[i],
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
|
||||||
debug("Find Ventoy Disk Handle:%p DP:%s", Handles[i],
|
debug("Find Ventoy Disk Sig Handle:%p DP:%s", Handles[i],
|
||||||
ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE));
|
ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -664,6 +716,106 @@ STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle)
|
|||||||
return EFI_SUCCESS;
|
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;
|
||||||
@@ -677,6 +829,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
ventoy_grub_param *pGrubParam = NULL;
|
ventoy_grub_param *pGrubParam = NULL;
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
|
EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
|
||||||
ventoy_chain_head *chain = NULL;
|
ventoy_chain_head *chain = NULL;
|
||||||
|
ventoy_grub_param_file_replace *replace = NULL;
|
||||||
|
|
||||||
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
|
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
|
||||||
if (EFI_ERROR(Status))
|
if (EFI_ERROR(Status))
|
||||||
@@ -694,6 +847,11 @@ 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"))
|
if (StrStr(pCmdLine, L"dotefi"))
|
||||||
{
|
{
|
||||||
gDotEfiBoot = TRUE;
|
gDotEfiBoot = TRUE;
|
||||||
@@ -769,6 +927,28 @@ 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] : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++)
|
||||||
|
{
|
||||||
|
replace = pGrubParam->img_replace + i;
|
||||||
|
if (replace->magic == GRUB_IMG_REPLACE_MAGIC)
|
||||||
|
{
|
||||||
|
ventoy_proc_img_replace_name(replace);
|
||||||
|
old_cnt = replace->old_file_cnt;
|
||||||
|
debug("img replace[%d]: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
|
||||||
|
i, replace->magic,
|
||||||
|
replace->new_file_virtual_id,
|
||||||
|
old_cnt,
|
||||||
|
old_cnt > 0 ? replace->old_file_name[0] : "",
|
||||||
|
old_cnt > 1 ? replace->old_file_name[1] : "",
|
||||||
|
old_cnt > 2 ? replace->old_file_name[2] : "",
|
||||||
|
old_cnt > 3 ? replace->old_file_name[3] : ""
|
||||||
|
);
|
||||||
|
g_img_replace_list = pGrubParam->img_replace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pPos = StrStr(pCmdLine, L"mem:");
|
pPos = StrStr(pCmdLine, L"mem:");
|
||||||
chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
|
chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
|
||||||
|
|
||||||
@@ -789,6 +969,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
debug("memdisk mode iso_buf_size:%u", g_iso_buf_size);
|
debug("memdisk mode iso_buf_size:%u", g_iso_buf_size);
|
||||||
|
|
||||||
g_chain = chain;
|
g_chain = chain;
|
||||||
|
g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved);
|
||||||
gMemdiskMode = TRUE;
|
gMemdiskMode = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -817,6 +998,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++)
|
||||||
@@ -873,12 +1059,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;
|
||||||
}
|
}
|
||||||
@@ -999,7 +1188,7 @@ 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)
|
||||||
{
|
{
|
||||||
ventoy_wrapper_push_openvolume(pFile->OpenVolume);
|
ventoy_wrapper_push_openvolume(pFile->OpenVolume);
|
||||||
pFile->OpenVolume = ventoy_wrapper_open_volume;
|
pFile->OpenVolume = ventoy_wrapper_open_volume;
|
||||||
@@ -1030,7 +1219,7 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug("Fs not found, now wait and retry...");
|
debug("Fs not found, now wait and retry...");
|
||||||
sleep(2);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,6 +1263,8 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ventoy_disable_ex_filesystem();
|
||||||
|
|
||||||
if (gMemdiskMode)
|
if (gMemdiskMode)
|
||||||
{
|
{
|
||||||
g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_iso_data_buf;
|
g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_iso_data_buf;
|
||||||
@@ -1130,7 +1321,7 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||||||
ventoy_clean_env();
|
ventoy_clean_env();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FALSE == gDotEfiBoot)
|
if (FALSE == gDotEfiBoot && FALSE == gBootFallBack)
|
||||||
{
|
{
|
||||||
if (EFI_NOT_FOUND == Status)
|
if (EFI_NOT_FOUND == Status)
|
||||||
{
|
{
|
||||||
@@ -1148,6 +1339,8 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||||||
grub_env_set("vtoy_dotefi_retry", "YES");
|
grub_env_set("vtoy_dotefi_retry", "YES");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ventoy_enable_ex_filesystem();
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ typedef struct ventoy_os_param
|
|||||||
|
|
||||||
UINT64 vtoy_reserved[4]; // Internal use by ventoy
|
UINT64 vtoy_reserved[4]; // Internal use by ventoy
|
||||||
|
|
||||||
UINT8 reserved[31];
|
UINT8 vtoy_disk_signature[4];
|
||||||
|
|
||||||
|
UINT8 reserved[27];
|
||||||
}ventoy_os_param;
|
}ventoy_os_param;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
@@ -169,7 +171,6 @@ typedef struct ventoy_virt_chunk
|
|||||||
{ 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"
|
||||||
@@ -243,7 +244,9 @@ typedef int (*grub_env_printf_pf)(const char *fmt, ...);
|
|||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
#define VTOY_MAX_CONF_REPLACE 2
|
||||||
#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
|
||||||
{
|
{
|
||||||
@@ -268,6 +271,7 @@ 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;
|
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[VTOY_MAX_CONF_REPLACE];
|
||||||
grub_env_printf_pf grub_env_printf;
|
grub_env_printf_pf grub_env_printf;
|
||||||
}ventoy_grub_param;
|
}ventoy_grub_param;
|
||||||
|
|
||||||
@@ -344,6 +348,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;\
|
||||||
@@ -351,6 +363,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);
|
||||||
@@ -373,6 +401,7 @@ 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[VTOY_MAX_CONF_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;
|
||||||
@@ -380,6 +409,7 @@ extern BOOLEAN gSector512Mode;
|
|||||||
extern UINTN g_iso_buf_size;
|
extern UINTN g_iso_buf_size;
|
||||||
extern UINT8 *g_iso_data_buf;
|
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;
|
||||||
@@ -396,6 +426,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,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>
|
||||||
|
|
||||||
UINT8 *g_iso_data_buf = NULL;
|
UINT8 *g_iso_data_buf = NULL;
|
||||||
@@ -73,6 +74,9 @@ STATIC UINT8 g_sector_buf[2048];
|
|||||||
STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
|
STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
|
||||||
STATIC EFI_BLOCK_WRITE g_sector_2048_write = 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;
|
||||||
@@ -148,7 +152,8 @@ 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 blk:%u",
|
||||||
|
Sector, Count, Buffer, pRawBlockIo->Media->IoAlign, pRawBlockIo->Media->BlockSize);
|
||||||
|
|
||||||
ReadStart = Sector * 2048;
|
ReadStart = Sector * 2048;
|
||||||
ReadEnd = (Sector + Count) * 2048;
|
ReadEnd = (Sector + Count) * 2048;
|
||||||
@@ -174,7 +179,6 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector;
|
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;
|
||||||
secRead = (Count < secLeft) ? Count : secLeft;
|
secRead = (Count < secLeft) ? Count : secLeft;
|
||||||
|
|
||||||
@@ -182,7 +186,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,7 +429,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,
|
||||||
@@ -438,6 +442,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;
|
||||||
@@ -445,7 +451,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;
|
||||||
|
|
||||||
@@ -461,6 +467,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)
|
||||||
{
|
{
|
||||||
@@ -529,6 +557,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,
|
||||||
@@ -561,26 +625,74 @@ EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *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;
|
||||||
}
|
}
|
||||||
@@ -613,11 +725,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))
|
||||||
{
|
{
|
||||||
@@ -655,11 +763,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))
|
||||||
{
|
{
|
||||||
@@ -684,6 +788,223 @@ 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
|
EFI_STATUS EFIAPI ventoy_block_io_read_512
|
||||||
(
|
(
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
@@ -698,7 +1019,7 @@ EFI_STATUS EFIAPI ventoy_block_io_read_512
|
|||||||
UINT8 *CurBuf = NULL;
|
UINT8 *CurBuf = NULL;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
debug("ventoy_block_io_read_512 %lu %lu\n", Lba, BufferSize / 512);
|
debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer);
|
||||||
|
|
||||||
CurBuf = (UINT8 *)Buffer;
|
CurBuf = (UINT8 *)Buffer;
|
||||||
|
|
||||||
@@ -818,14 +1139,15 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im
|
|||||||
{
|
{
|
||||||
gBlockData.Media.BlockSize = 512;
|
gBlockData.Media.BlockSize = 512;
|
||||||
gBlockData.Media.LastBlock = ImgSize / 512 - 1;
|
gBlockData.Media.LastBlock = ImgSize / 512 - 1;
|
||||||
|
gBlockData.Media.ReadOnly = FALSE;
|
||||||
}
|
}
|
||||||
else
|
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;
|
||||||
|
|
||||||
@@ -924,6 +1246,98 @@ 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_img0(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
||||||
|
{
|
||||||
|
(VOID)This;
|
||||||
|
(VOID)Token;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
/* Ex version */
|
||||||
|
STATIC EFI_STATUS EFIAPI
|
||||||
|
ventoy_wrapper_file_flush_ex_img1(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
||||||
|
{
|
||||||
|
(VOID)This;
|
||||||
|
(VOID)Token;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_WRAP_FUNC(n) \
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_flush_ex_img#n(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) \
|
||||||
|
{\
|
||||||
|
(VOID)This;\
|
||||||
|
(VOID)Token;\
|
||||||
|
return EFI_SUCCESS;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ITEM_WRAP_FUNC(n) ventoy_wrapper_file_flush_ex_img#n
|
||||||
|
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 2)
|
||||||
|
DEF_WRAP_FUNC(2);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 3)
|
||||||
|
DEF_WRAP_FUNC(3);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 4)
|
||||||
|
DEF_WRAP_FUNC(4);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 5)
|
||||||
|
DEF_WRAP_FUNC(5);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 6)
|
||||||
|
DEF_WRAP_FUNC(6);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 7)
|
||||||
|
DEF_WRAP_FUNC(7);
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 8)
|
||||||
|
#error "VTOY_MAX_CONF_REPLACE overflow"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static EFI_FILE_FLUSH_EX g_img_flush_func[VTOY_MAX_CONF_REPLACE] =
|
||||||
|
{
|
||||||
|
ventoy_wrapper_file_flush_ex_img0,
|
||||||
|
ventoy_wrapper_file_flush_ex_img1,
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 2)
|
||||||
|
ITEM_WRAP_FUNC(2),
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 3)
|
||||||
|
ITEM_WRAP_FUNC(3),
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 4)
|
||||||
|
ITEM_WRAP_FUNC(4),
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 5)
|
||||||
|
ITEM_WRAP_FUNC(5),
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 6)
|
||||||
|
ITEM_WRAP_FUNC(6),
|
||||||
|
#endif
|
||||||
|
#if (VTOY_MAX_CONF_REPLACE > 7)
|
||||||
|
ITEM_WRAP_FUNC(7),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC ventoy_efi_file_replace *ventoy_wrapper_get_replace(EFI_FILE_HANDLE This)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
|
||||||
|
if (This->FlushEx == ventoy_wrapper_file_flush_ex)
|
||||||
|
{
|
||||||
|
return &g_efi_file_replace;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++)
|
||||||
|
{
|
||||||
|
if (This->FlushEx == g_img_flush_func[i])
|
||||||
|
{
|
||||||
|
return g_img_file_replace + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -949,19 +1363,20 @@ 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;
|
||||||
|
|
||||||
if (Position <= g_efi_file_replace.FileSizeBytes)
|
replace = ventoy_wrapper_get_replace(This);
|
||||||
|
|
||||||
|
if (Position <= replace->FileSizeBytes)
|
||||||
{
|
{
|
||||||
g_efi_file_replace.CurPos = Position;
|
replace->CurPos = Position;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes;
|
replace->CurPos = replace->FileSizeBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
@@ -970,9 +1385,11 @@ ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
|
|||||||
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;
|
replace = ventoy_wrapper_get_replace(This);
|
||||||
|
|
||||||
|
*Position = replace->CurPos;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -982,6 +1399,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;
|
||||||
|
|
||||||
|
replace = ventoy_wrapper_get_replace(This);
|
||||||
|
|
||||||
debug("ventoy_wrapper_file_get_info ... %u", *Len);
|
debug("ventoy_wrapper_file_get_info ... %u", *Len);
|
||||||
|
|
||||||
@@ -999,8 +1419,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;
|
||||||
|
|
||||||
@@ -1014,23 +1434,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;
|
replace = ventoy_wrapper_get_replace(This);
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1462,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, UINTN Index)
|
||||||
{
|
{
|
||||||
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
|
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
|
||||||
File->Open = ventoy_wrapper_fs_open;
|
File->Open = ventoy_wrapper_fs_open;
|
||||||
@@ -1057,11 +1478,47 @@ 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;
|
||||||
|
|
||||||
|
if (Img)
|
||||||
|
{
|
||||||
|
File->FlushEx = g_img_flush_func[Index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
File->FlushEx = ventoy_wrapper_file_flush_ex;
|
File->FlushEx = ventoy_wrapper_file_flush_ex;
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC BOOLEAN EFIAPI ventoy_replace_name_match(CHAR8 *pReplace, CHAR8 *pName)
|
||||||
|
{
|
||||||
|
UINTN Len1, Len2;
|
||||||
|
|
||||||
|
Len1 = AsciiStrLen(pReplace);
|
||||||
|
Len2 = AsciiStrLen(pName);
|
||||||
|
|
||||||
|
if (Len1 == 0 || Len2 == 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == AsciiStriCmp(pReplace, pName))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Len1 > 2 && Len2 > 2)
|
||||||
|
{
|
||||||
|
if ((pReplace[0] != '\\') && (pName[0] == '\\') && (0 == AsciiStriCmp(pReplace, pName + 1)))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
||||||
(
|
(
|
||||||
EFI_FILE_HANDLE This,
|
EFI_FILE_HANDLE This,
|
||||||
@@ -1076,27 +1533,40 @@ 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;
|
||||||
|
ventoy_grub_param_file_replace *replace = NULL;
|
||||||
|
|
||||||
debug("## ventoy_wrapper_file_open <%s> ", Name);
|
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)
|
||||||
{
|
{
|
||||||
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
|
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName))
|
if (ventoy_replace_name_match(g_file_replace_list[i].old_file_name[j], TmpName))
|
||||||
{
|
{
|
||||||
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, 0);
|
||||||
|
|
||||||
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
|
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
|
||||||
|
|
||||||
@@ -1122,6 +1592,52 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; g_img_replace_list && i < VTOY_MAX_CONF_REPLACE; i++)
|
||||||
|
{
|
||||||
|
replace = g_img_replace_list + i;
|
||||||
|
if (replace->magic != GRUB_IMG_REPLACE_MAGIC || replace->new_file_virtual_id >= g_virt_chunk_num)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
|
||||||
|
for (j = 0; j < replace->old_file_cnt; j++)
|
||||||
|
{
|
||||||
|
AsciiStrCpyS(OldName, sizeof(OldName), replace->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[i].WrapperHandle);
|
||||||
|
ventoy_wrapper_file_procotol(*New, TRUE, i);
|
||||||
|
|
||||||
|
virt = g_virt_chunk + replace->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[i].BlockIoSectorStart = virt->mem_sector_start;
|
||||||
|
g_img_file_replace[i].FileSizeBytes = Sectors * 2048;
|
||||||
|
|
||||||
|
if (gDebugPrint)
|
||||||
|
{
|
||||||
|
debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
|
||||||
|
g_img_file_replace[i].BlockIoSectorStart, Sectors, Sectors * 2048);
|
||||||
|
sleep(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_img_replace_list && 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;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ 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, ...);
|
||||||
|
|
||||||
|
#define VTOY_MAX_CONF_REPLACE 2
|
||||||
|
|
||||||
typedef struct ventoy_grub_param_file_replace
|
typedef struct ventoy_grub_param_file_replace
|
||||||
{
|
{
|
||||||
UINT32 magic;
|
UINT32 magic;
|
||||||
@@ -41,6 +43,7 @@ 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;
|
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[VTOY_MAX_CONF_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()
|
||||||
@@ -57,7 +60,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
|
||||||
|
|||||||
@@ -12,13 +12,15 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
# use mini-native-x86_64 UCLIBC to build for x86_64
|
# 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"
|
||||||
|
|||||||
@@ -33,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 ..
|
||||||
|
|||||||
Binary file not shown.
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;
|
||||||
@@ -828,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;
|
||||||
@@ -898,6 +913,12 @@ module = {
|
|||||||
enable = x86_64_efi;
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = fwload;
|
||||||
|
efi = commands/efi/fwload.c;
|
||||||
|
enable = efi;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = gptsync;
|
name = gptsync;
|
||||||
common = commands/gptsync.c;
|
common = commands/gptsync.c;
|
||||||
@@ -1108,6 +1129,21 @@ module = {
|
|||||||
common = commands/sleep.c;
|
common = commands/sleep.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = smbios;
|
||||||
|
|
||||||
|
common = commands/smbios.c;
|
||||||
|
efi = commands/efi/smbios.c;
|
||||||
|
i386_pc = commands/i386/pc/smbios.c;
|
||||||
|
i386_coreboot = commands/i386/pc/smbios.c;
|
||||||
|
i386_multiboot = commands/i386/pc/smbios.c;
|
||||||
|
|
||||||
|
enable = efi;
|
||||||
|
enable = i386_pc;
|
||||||
|
enable = i386_coreboot;
|
||||||
|
enable = i386_multiboot;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = suspend;
|
name = suspend;
|
||||||
ieee1275 = commands/ieee1275/suspend.c;
|
ieee1275 = commands/ieee1275/suspend.c;
|
||||||
@@ -1497,7 +1533,7 @@ module = {
|
|||||||
name = squash4;
|
name = squash4;
|
||||||
common = fs/squash4.c;
|
common = fs/squash4.c;
|
||||||
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H';
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
@@ -1588,18 +1624,31 @@ 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_unix.c;
|
||||||
common = ventoy/ventoy_windows.c;
|
common = ventoy/ventoy_windows.c;
|
||||||
common = ventoy/ventoy_vhd.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/xpress.c;
|
||||||
common = ventoy/huffman.c;
|
common = ventoy/huffman.c;
|
||||||
common = ventoy/miniz.c;
|
common = ventoy/miniz.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = setkey;
|
||||||
|
common = term/setkey.c;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = mouse;
|
||||||
|
efi = term/efi/mouse.c;
|
||||||
|
enable = efi;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = hello;
|
name = hello;
|
||||||
common = hello/hello.c;
|
common = hello/hello.c;
|
||||||
@@ -1662,6 +1711,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;
|
||||||
@@ -1674,6 +1725,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;
|
||||||
@@ -1804,6 +1856,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;
|
||||||
@@ -1910,6 +1963,7 @@ module = {
|
|||||||
enable = riscv32_efi;
|
enable = riscv32_efi;
|
||||||
enable = riscv64_efi;
|
enable = riscv64_efi;
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
enable = mips64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
|||||||
205
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/fwload.c
Normal file
205
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/fwload.c
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/extcmd.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
|
||||||
|
|
||||||
|
static grub_efi_status_t
|
||||||
|
grub_efi_connect_all (void)
|
||||||
|
{
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_uintn_t handle_count;
|
||||||
|
grub_efi_handle_t *handle_buffer;
|
||||||
|
grub_efi_uintn_t index;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_dprintf ("efi", "Connecting ...\n");
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_5 (b->locate_handle_buffer,
|
||||||
|
GRUB_EFI_ALL_HANDLES, NULL, NULL,
|
||||||
|
&handle_count, &handle_buffer);
|
||||||
|
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (index = 0; index < handle_count; index++)
|
||||||
|
{
|
||||||
|
status = efi_call_4 (b->connect_controller,
|
||||||
|
handle_buffer[index], NULL, NULL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle_buffer)
|
||||||
|
{
|
||||||
|
efi_call_1 (b->free_pool, handle_buffer);
|
||||||
|
}
|
||||||
|
return GRUB_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_efi_load_driver (grub_size_t size, void *boot_image, int connect)
|
||||||
|
{
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_handle_t driver_handle;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_loaded_image_t *loaded_image;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
|
||||||
|
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, NULL,
|
||||||
|
boot_image, size, &driver_handle);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
|
||||||
|
else
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
loaded_image = grub_efi_get_loaded_image (driver_handle);
|
||||||
|
if (! loaded_image)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
grub_dprintf ("efi", "Registering loaded image\n");
|
||||||
|
status = efi_call_3 (b->handle_protocol, driver_handle,
|
||||||
|
&loaded_image_guid, (void **)&loaded_image);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "not a dirver");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
grub_dprintf ("efi", "StartImage: %p\n", boot_image);
|
||||||
|
status = efi_call_3 (b->start_image, driver_handle, NULL, NULL);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "StartImage failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (connect)
|
||||||
|
{
|
||||||
|
status = grub_efi_connect_all ();
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "cannot connect controllers\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grub_dprintf ("efi", "Driver installed\n");
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct grub_arg_option options_fwload[] =
|
||||||
|
{
|
||||||
|
{"nc", 'n', 0, N_("Loads the driver, but does not connect the driver."), 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_fwload (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
{
|
||||||
|
struct grub_arg_list *state = ctxt->state;
|
||||||
|
int connect = 1;
|
||||||
|
grub_file_t file = 0;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_uintn_t pages = 0;
|
||||||
|
grub_ssize_t size;
|
||||||
|
grub_efi_physical_address_t address;
|
||||||
|
void *boot_image = 0;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
if (argc != 1)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
file = grub_file_open (args[0], GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
|
||||||
|
if (! file)
|
||||||
|
goto fail;
|
||||||
|
size = grub_file_size (file);
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
|
||||||
|
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
|
||||||
|
GRUB_EFI_LOADER_CODE, pages, &address);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
boot_image = (void *) ((grub_addr_t) address);
|
||||||
|
if (grub_file_read (file, boot_image, size) != size)
|
||||||
|
{
|
||||||
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
grub_file_close (file);
|
||||||
|
if (state[0].set)
|
||||||
|
connect = 0;
|
||||||
|
if (grub_efi_load_driver (size, boot_image, connect))
|
||||||
|
goto fail;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
fail:
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
if (address)
|
||||||
|
efi_call_2 (b->free_pages, address, pages);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_fwconnect (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||||
|
int argc __attribute__ ((unused)),
|
||||||
|
char **args __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
grub_efi_connect_all ();
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_extcmd_t cmd_fwload, cmd_fwconnect;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(fwload)
|
||||||
|
{
|
||||||
|
cmd_fwload = grub_register_extcmd ("fwload", grub_cmd_fwload, 0, N_("FILE"),
|
||||||
|
N_("Install UEFI driver."), options_fwload);
|
||||||
|
cmd_fwconnect = grub_register_extcmd ("fwconnect", grub_cmd_fwconnect, 0,
|
||||||
|
NULL, N_("Connect drivers."), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(fwload)
|
||||||
|
{
|
||||||
|
grub_unregister_extcmd (cmd_fwload);
|
||||||
|
grub_unregister_extcmd (cmd_fwconnect);
|
||||||
|
}
|
||||||
61
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/smbios.c
Normal file
61
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/smbios.c
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* smbios.c - get smbios tables. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_machine_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
|
||||||
|
|
||||||
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
|
{
|
||||||
|
grub_efi_packed_guid_t *guid =
|
||||||
|
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||||
|
|
||||||
|
if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t)))
|
||||||
|
return (struct grub_smbios_eps *)
|
||||||
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_smbios_eps3 *
|
||||||
|
grub_machine_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
|
||||||
|
|
||||||
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
|
{
|
||||||
|
grub_efi_packed_guid_t *guid =
|
||||||
|
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||||
|
|
||||||
|
if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t)))
|
||||||
|
return (struct grub_smbios_eps3 *)
|
||||||
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
351
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c
Normal file
351
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/extcmd.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/normal.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
static const struct grub_arg_option options[] = {
|
||||||
|
{"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
|
||||||
|
{"check", 'c', 0, N_("Check hashes of files with hash list FILE."),
|
||||||
|
N_("FILE"), ARG_TYPE_STRING},
|
||||||
|
{"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"),
|
||||||
|
ARG_TYPE_STRING},
|
||||||
|
{"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
|
||||||
|
{"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct { const char *name; const char *hashname; } aliases[] =
|
||||||
|
{
|
||||||
|
{"sha256sum", "sha256"},
|
||||||
|
{"sha512sum", "sha512"},
|
||||||
|
{"sha1sum", "sha1"},
|
||||||
|
{"md5sum", "md5"},
|
||||||
|
{"crc", "crc32"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
hextoval (char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
if (c >= 'a' && c <= 'f')
|
||||||
|
return c - 'a' + 10;
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
|
||||||
|
{
|
||||||
|
int progress = 0;
|
||||||
|
grub_uint64_t ro = 0;
|
||||||
|
grub_uint64_t div = 0;
|
||||||
|
grub_uint64_t total = 0;
|
||||||
|
void *context;
|
||||||
|
grub_uint8_t *readbuf;
|
||||||
|
#define BUF_SIZE 1024 * 1024
|
||||||
|
readbuf = grub_malloc (BUF_SIZE);
|
||||||
|
if (!readbuf)
|
||||||
|
return grub_errno;
|
||||||
|
context = grub_zalloc (hash->contextsize);
|
||||||
|
if (!readbuf || !context)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (file->size > 16 * 1024 * 1024)
|
||||||
|
progress = 1;
|
||||||
|
|
||||||
|
hash->init (context);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
grub_ssize_t r;
|
||||||
|
r = grub_file_read (file, readbuf, BUF_SIZE);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
hash->write (context, readbuf, r);
|
||||||
|
if (progress)
|
||||||
|
{
|
||||||
|
total += r;
|
||||||
|
div = grub_divmod64(total * 100, (grub_uint64_t)file->size, &ro);
|
||||||
|
grub_printf("\rCalculating %s %d%% ", hash->name, (int)div);
|
||||||
|
grub_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash->final (context);
|
||||||
|
grub_memcpy (result, hash->read (context), hash->mdlen);
|
||||||
|
|
||||||
|
grub_free (readbuf);
|
||||||
|
grub_free (context);
|
||||||
|
if (progress)
|
||||||
|
{
|
||||||
|
grub_printf("\rCalculating %s 100%% \n\r\n", hash->name);
|
||||||
|
grub_refresh();
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (readbuf);
|
||||||
|
grub_free (context);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||||
|
const char *prefix, int keep, int uncompress)
|
||||||
|
{
|
||||||
|
grub_file_t hashlist, file;
|
||||||
|
char *buf = NULL;
|
||||||
|
grub_uint8_t expected[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
|
grub_uint8_t actual[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
|
grub_err_t err;
|
||||||
|
unsigned i;
|
||||||
|
unsigned unread = 0, mismatch = 0;
|
||||||
|
|
||||||
|
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||||
|
|
||||||
|
hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST);
|
||||||
|
if (!hashlist)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
while (grub_free (buf), (buf = grub_file_getline (hashlist)))
|
||||||
|
{
|
||||||
|
const char *p = buf;
|
||||||
|
while (grub_isspace (p[0]))
|
||||||
|
p++;
|
||||||
|
for (i = 0; i < hash->mdlen; i++)
|
||||||
|
{
|
||||||
|
int high, low;
|
||||||
|
high = hextoval (*p++);
|
||||||
|
low = hextoval (*p++);
|
||||||
|
if (high < 0 || low < 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||||
|
expected[i] = (high << 4) | low;
|
||||||
|
}
|
||||||
|
if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t'))
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||||
|
p += 2;
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
filename = grub_xasprintf ("%s/%s", prefix, p);
|
||||||
|
if (!filename)
|
||||||
|
return grub_errno;
|
||||||
|
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
|
||||||
|
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||||
|
: GRUB_FILE_TYPE_NONE));
|
||||||
|
grub_free (filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH
|
||||||
|
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||||
|
: GRUB_FILE_TYPE_NONE));
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
grub_file_close (hashlist);
|
||||||
|
grub_free (buf);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
err = hash_file (file, hash, actual);
|
||||||
|
grub_file_close (file);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_printf_ (N_("%s: READ ERROR\n"), p);
|
||||||
|
if (!keep)
|
||||||
|
{
|
||||||
|
grub_file_close (hashlist);
|
||||||
|
grub_free (buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
unread++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
|
||||||
|
{
|
||||||
|
grub_printf_ (N_("%s: HASH MISMATCH\n"), p);
|
||||||
|
if (!keep)
|
||||||
|
{
|
||||||
|
grub_file_close (hashlist);
|
||||||
|
grub_free (buf);
|
||||||
|
return grub_error (GRUB_ERR_TEST_FAILURE,
|
||||||
|
"hash of '%s' mismatches", p);
|
||||||
|
}
|
||||||
|
mismatch++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
grub_printf_ (N_("%s: OK\n"), p);
|
||||||
|
}
|
||||||
|
if (mismatch || unread)
|
||||||
|
return grub_error (GRUB_ERR_TEST_FAILURE,
|
||||||
|
"%d files couldn't be read and hash "
|
||||||
|
"of %d files mismatches", unread, mismatch);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
|
||||||
|
int argc, char **args)
|
||||||
|
{
|
||||||
|
struct grub_arg_list *state = ctxt->state;
|
||||||
|
const char *hashname = NULL;
|
||||||
|
const char *prefix = NULL;
|
||||||
|
const gcry_md_spec_t *hash;
|
||||||
|
unsigned i;
|
||||||
|
int keep = state[3].set;
|
||||||
|
int uncompress = state[4].set;
|
||||||
|
unsigned unread = 0;
|
||||||
|
int len = 0;
|
||||||
|
char hashsum[256];
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (aliases); i++)
|
||||||
|
if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0)
|
||||||
|
hashname = aliases[i].hashname;
|
||||||
|
if (state[0].set)
|
||||||
|
hashname = state[0].arg;
|
||||||
|
|
||||||
|
if (!hashname)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified");
|
||||||
|
|
||||||
|
hash = grub_crypto_lookup_md_by_name (hashname);
|
||||||
|
if (!hash)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash");
|
||||||
|
|
||||||
|
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||||
|
|
||||||
|
if (state[2].set)
|
||||||
|
prefix = state[2].arg;
|
||||||
|
|
||||||
|
if (state[1].set)
|
||||||
|
{
|
||||||
|
if (argc != 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"--check is incompatible with file list");
|
||||||
|
return check_list (hash, state[1].arg, prefix, keep, uncompress);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (unsigned) argc; i++)
|
||||||
|
{
|
||||||
|
GRUB_PROPERLY_ALIGNED_ARRAY (result, GRUB_CRYPTO_MAX_MDLEN);
|
||||||
|
grub_file_t file;
|
||||||
|
grub_err_t err;
|
||||||
|
unsigned j;
|
||||||
|
int vlnk = 0;
|
||||||
|
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
|
||||||
|
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||||
|
: GRUB_FILE_TYPE_NONE));
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
if (!keep)
|
||||||
|
return grub_errno;
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
unread++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vlnk = file->vlnk;
|
||||||
|
err = hash_file (file, hash, result);
|
||||||
|
grub_file_close (file);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (!keep)
|
||||||
|
return err;
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
unread++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (j = 0; j < hash->mdlen; j++)
|
||||||
|
{
|
||||||
|
grub_printf ("%02x", ((grub_uint8_t *) result)[j]);
|
||||||
|
len += grub_snprintf(hashsum + len, sizeof(hashsum) - len, "%02x", ((grub_uint8_t *) result)[j]);
|
||||||
|
}
|
||||||
|
grub_printf (" %s\n", vlnk ? grub_file_get_vlnk(args[i], NULL) : args[i]);
|
||||||
|
grub_env_set("VT_LAST_CHECK_SUM", hashsum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unread)
|
||||||
|
return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read",
|
||||||
|
unread);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(hashsum)
|
||||||
|
{
|
||||||
|
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0,
|
||||||
|
N_("-h HASH [-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
/* TRANSLATORS: "hash checksum" is just to
|
||||||
|
be a bit more precise, you can treat it as
|
||||||
|
just "hash". */
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0,
|
||||||
|
N_("[-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0,
|
||||||
|
N_("[-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0,
|
||||||
|
N_("[-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0,
|
||||||
|
N_("[-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
|
||||||
|
cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0,
|
||||||
|
N_("[-c FILE [-p PREFIX]] "
|
||||||
|
"[FILE1 [FILE2 ...]]"),
|
||||||
|
N_("Compute or check hash checksum."),
|
||||||
|
options);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(hashsum)
|
||||||
|
{
|
||||||
|
grub_unregister_extcmd (cmd);
|
||||||
|
grub_unregister_extcmd (cmd_md5);
|
||||||
|
grub_unregister_extcmd (cmd_sha1);
|
||||||
|
grub_unregister_extcmd (cmd_sha256);
|
||||||
|
grub_unregister_extcmd (cmd_sha512);
|
||||||
|
grub_unregister_extcmd (cmd_crc);
|
||||||
|
}
|
||||||
52
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/i386/pc/smbios.c
Normal file
52
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/i386/pc/smbios.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* smbios.c - get smbios tables. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/acpi.h>
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_machine_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
|
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
||||||
|
|
||||||
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
|
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
||||||
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
||||||
|
return (struct grub_smbios_eps *) ptr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_smbios_eps3 *
|
||||||
|
grub_machine_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
|
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
||||||
|
|
||||||
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
|
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
||||||
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
||||||
|
return (struct grub_smbios_eps3 *) ptr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -68,7 +68,7 @@ iterate_device (const char *name, void *data)
|
|||||||
/* Skip floppy drives when requested. */
|
/* Skip floppy drives when requested. */
|
||||||
if (ctx->no_floppy &&
|
if (ctx->no_floppy &&
|
||||||
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) {
|
if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
399
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/smbios.c
Normal file
399
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/smbios.c
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
/* smbios.c - retrieve smbios information. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/extcmd.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
|
||||||
|
static struct {
|
||||||
|
grub_addr_t start;
|
||||||
|
grub_addr_t end;
|
||||||
|
grub_uint16_t structures;
|
||||||
|
} table_desc;
|
||||||
|
|
||||||
|
static grub_extcmd_t cmd;
|
||||||
|
|
||||||
|
/* Locate the SMBIOS entry point structure depending on the hardware. */
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
static struct grub_smbios_eps *eps = NULL;
|
||||||
|
|
||||||
|
if (eps != NULL)
|
||||||
|
return eps;
|
||||||
|
|
||||||
|
eps = grub_machine_smbios_get_eps ();
|
||||||
|
|
||||||
|
return eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
||||||
|
static struct grub_smbios_eps3 *
|
||||||
|
grub_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
static struct grub_smbios_eps3 *eps = NULL;
|
||||||
|
|
||||||
|
if (eps != NULL)
|
||||||
|
return eps;
|
||||||
|
|
||||||
|
eps = grub_machine_smbios_get_eps3 ();
|
||||||
|
|
||||||
|
return eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
linux_string (const char *value)
|
||||||
|
{
|
||||||
|
char *out = grub_malloc( grub_strlen (value) + 1);
|
||||||
|
const char *src = value;
|
||||||
|
char *dst = out;
|
||||||
|
|
||||||
|
for (; *src; src++)
|
||||||
|
if (*src > ' ' && *src < 127 && *src != ':')
|
||||||
|
*dst++ = *src;
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These functions convert values from the various SMBIOS structure field types
|
||||||
|
* into a string formatted to be returned to the user. They expect that the
|
||||||
|
* structure and offset were already validated. When the requested data is
|
||||||
|
* successfully retrieved and formatted, the pointer to the string is returned;
|
||||||
|
* otherwise, NULL is returned on failure. Don't free the result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("255")];
|
||||||
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("65535")];
|
||||||
|
|
||||||
|
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%u", value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("4294967295")];
|
||||||
|
|
||||||
|
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("18446744073709551615")];
|
||||||
|
|
||||||
|
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
const grub_uint8_t *ptr = structure + structure[1];
|
||||||
|
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||||
|
const grub_uint8_t referenced_string_number = structure[offset];
|
||||||
|
grub_uint8_t i;
|
||||||
|
|
||||||
|
/* A string referenced with zero is interpreted as unset. */
|
||||||
|
if (referenced_string_number == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Search the string set. */
|
||||||
|
for (i = 1; *ptr != 0 && ptr < table_end; i++)
|
||||||
|
if (i == referenced_string_number)
|
||||||
|
{
|
||||||
|
const char *str = (const char *)ptr;
|
||||||
|
while (*ptr++ != 0)
|
||||||
|
if (ptr >= table_end)
|
||||||
|
return NULL; /* The string isn't terminated. */
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (*ptr++ != 0 && ptr < table_end);
|
||||||
|
|
||||||
|
/* The string number is greater than the number of strings in the set. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")];
|
||||||
|
const grub_uint8_t *f = structure + offset; /* little-endian fields */
|
||||||
|
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
||||||
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer),
|
||||||
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||||
|
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
|
||||||
|
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List the field formatting functions and the number of bytes they need. */
|
||||||
|
static const struct {
|
||||||
|
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
|
||||||
|
grub_uint8_t field_length;
|
||||||
|
} field_extractors[] = {
|
||||||
|
{grub_smbios_format_byte, 1},
|
||||||
|
{grub_smbios_format_word, 2},
|
||||||
|
{grub_smbios_format_dword, 4},
|
||||||
|
{grub_smbios_format_qword, 8},
|
||||||
|
{grub_smbios_get_string, 1},
|
||||||
|
{grub_smbios_format_uuid, 16}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List command options, with structure field getters ordered as above. */
|
||||||
|
#define FIRST_GETTER_OPT (3)
|
||||||
|
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
|
||||||
|
#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1)
|
||||||
|
|
||||||
|
static const struct grub_arg_option options[] = {
|
||||||
|
{"type", 't', 0, N_("Match structures with the given type."),
|
||||||
|
N_("type"), ARG_TYPE_INT},
|
||||||
|
{"handle", 'h', 0, N_("Match structures with the given handle."),
|
||||||
|
N_("handle"), ARG_TYPE_INT},
|
||||||
|
{"match", 'm', 0, N_("Select a structure when several match."),
|
||||||
|
N_("match"), ARG_TYPE_INT},
|
||||||
|
{"get-byte", 'b', 0, N_("Get the byte's value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-word", 'w', 0, N_("Get two bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-string", 's', 0, N_("Get the string specified at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
||||||
|
N_("variable"), ARG_TYPE_STRING},
|
||||||
|
{"linux", '\0', 0, N_("Filter the result like linux does."),
|
||||||
|
N_("variable"), ARG_TYPE_NONE},
|
||||||
|
{0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a matching SMBIOS structure.
|
||||||
|
*
|
||||||
|
* This method can use up to three criteria for selecting a structure:
|
||||||
|
* - The "type" field (use -1 to ignore)
|
||||||
|
* - The "handle" field (use -1 to ignore)
|
||||||
|
* - Which to return if several match (use 0 to ignore)
|
||||||
|
*
|
||||||
|
* The return value is a pointer to the first matching structure. If no
|
||||||
|
* structures match the given parameters, NULL is returned.
|
||||||
|
*/
|
||||||
|
static const grub_uint8_t *
|
||||||
|
grub_smbios_match_structure (const grub_int16_t type,
|
||||||
|
const grub_int32_t handle,
|
||||||
|
const grub_uint16_t match)
|
||||||
|
{
|
||||||
|
const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start;
|
||||||
|
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||||
|
grub_uint16_t structures = table_desc.structures;
|
||||||
|
grub_uint16_t structure_count = 0;
|
||||||
|
grub_uint16_t matches = 0;
|
||||||
|
|
||||||
|
while (ptr < table_end
|
||||||
|
&& ptr[1] >= 4 /* Valid structures include the 4-byte header. */
|
||||||
|
&& (structure_count++ < structures || structures == 0))
|
||||||
|
{
|
||||||
|
grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2);
|
||||||
|
grub_uint8_t structure_type = ptr[0];
|
||||||
|
|
||||||
|
if ((handle < 0 || handle == structure_handle)
|
||||||
|
&& (type < 0 || type == structure_type)
|
||||||
|
&& (match == 0 || match == ++matches))
|
||||||
|
return ptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr += ptr[1];
|
||||||
|
while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
|
int argc __attribute__ ((unused)),
|
||||||
|
char **argv __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
struct grub_arg_list *state = ctxt->state;
|
||||||
|
|
||||||
|
grub_int16_t type = -1;
|
||||||
|
grub_int32_t handle = -1;
|
||||||
|
grub_uint16_t match = 0;
|
||||||
|
grub_uint8_t offset = 0;
|
||||||
|
|
||||||
|
const grub_uint8_t *structure;
|
||||||
|
const char *value;
|
||||||
|
char *modified_value = NULL;
|
||||||
|
grub_int32_t option;
|
||||||
|
grub_int8_t field_type = -1;
|
||||||
|
grub_uint8_t i;
|
||||||
|
|
||||||
|
if (table_desc.start == 0)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("the SMBIOS entry point structure was not found"));
|
||||||
|
|
||||||
|
/* Read the given filtering options. */
|
||||||
|
if (state[0].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[0].arg, NULL, 0);
|
||||||
|
if (option < 0 || option > 255)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the type must be between 0 and 255"));
|
||||||
|
type = (grub_int16_t)option;
|
||||||
|
}
|
||||||
|
if (state[1].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[1].arg, NULL, 0);
|
||||||
|
if (option < 0 || option > 65535)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the handle must be between 0 and 65535"));
|
||||||
|
handle = (grub_int32_t)option;
|
||||||
|
}
|
||||||
|
if (state[2].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[2].arg, NULL, 0);
|
||||||
|
if (option <= 0 || option > 65535)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the match must be a positive integer"));
|
||||||
|
match = (grub_uint16_t)option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the data type of the structure field to retrieve. */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(field_extractors); i++)
|
||||||
|
if (state[FIRST_GETTER_OPT + i].set)
|
||||||
|
{
|
||||||
|
if (field_type >= 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("only one --get option is usable at a time"));
|
||||||
|
field_type = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Require a choice of a structure field to return. */
|
||||||
|
if (field_type < 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("one of the --get options is required"));
|
||||||
|
|
||||||
|
/* Locate a matching SMBIOS structure. */
|
||||||
|
structure = grub_smbios_match_structure (type, handle, match);
|
||||||
|
if (structure == NULL)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("no structure matched the given options"));
|
||||||
|
|
||||||
|
/* Ensure the requested byte offset is inside the structure. */
|
||||||
|
option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0);
|
||||||
|
if (option < 0 || option >= structure[1])
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
N_("the given offset is outside the structure"));
|
||||||
|
|
||||||
|
/* Ensure the requested data type at the offset is inside the structure. */
|
||||||
|
offset = (grub_uint8_t)option;
|
||||||
|
if (offset + field_extractors[field_type].field_length > structure[1])
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
N_("the field ends outside the structure"));
|
||||||
|
|
||||||
|
/* Format the requested structure field into a readable string. */
|
||||||
|
value = field_extractors[field_type].format (structure, offset);
|
||||||
|
if (value == NULL)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("failed to retrieve the structure field"));
|
||||||
|
|
||||||
|
if (state[LINUX_OPT].set)
|
||||||
|
value = modified_value = linux_string (value);
|
||||||
|
|
||||||
|
/* Store or print the formatted value. */
|
||||||
|
if (state[SETTER_OPT].set)
|
||||||
|
grub_env_set (state[SETTER_OPT].arg, value);
|
||||||
|
else
|
||||||
|
grub_printf ("%s\n", value);
|
||||||
|
|
||||||
|
grub_free(modified_value);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(smbios)
|
||||||
|
{
|
||||||
|
struct grub_smbios_eps3 *eps3;
|
||||||
|
struct grub_smbios_eps *eps;
|
||||||
|
|
||||||
|
if ((eps3 = grub_smbios_get_eps3 ()))
|
||||||
|
{
|
||||||
|
table_desc.start = (grub_addr_t)eps3->table_address;
|
||||||
|
table_desc.end = table_desc.start + eps3->maximum_table_length;
|
||||||
|
table_desc.structures = 0; /* SMBIOS3 drops the structure count. */
|
||||||
|
}
|
||||||
|
else if ((eps = grub_smbios_get_eps ()))
|
||||||
|
{
|
||||||
|
table_desc.start = (grub_addr_t)eps->intermediate.table_address;
|
||||||
|
table_desc.end = table_desc.start + eps->intermediate.table_length;
|
||||||
|
table_desc.structures = eps->intermediate.structures;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0,
|
||||||
|
N_("[-t type] [-h handle] [-m match] "
|
||||||
|
"(-b|-w|-d|-q|-s|-u) offset "
|
||||||
|
"[--set variable]"),
|
||||||
|
N_("Retrieve SMBIOS information."), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(smbios)
|
||||||
|
{
|
||||||
|
grub_unregister_extcmd (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -229,6 +229,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-EQ") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
== grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
|
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
|
||||||
{
|
{
|
||||||
@@ -237,6 +244,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-GE") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
>= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
|
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
|
||||||
{
|
{
|
||||||
@@ -245,6 +259,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-GT") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
> grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_strcmp (args[*argn + 1], "-le") == 0)
|
if (grub_strcmp (args[*argn + 1], "-le") == 0)
|
||||||
{
|
{
|
||||||
@@ -253,6 +274,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-LE") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
<= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
|
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
|
||||||
{
|
{
|
||||||
@@ -261,6 +289,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-LT") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
< grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
|
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
|
||||||
{
|
{
|
||||||
@@ -269,6 +304,13 @@ test_parse (char **args, int *argn, int argc)
|
|||||||
(*argn) += 3;
|
(*argn) += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (grub_strcmp (args[*argn + 1], "-NE") == 0)
|
||||||
|
{
|
||||||
|
update_val (grub_strtoull (args[*argn], 0, 0)
|
||||||
|
!= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
|
||||||
|
(*argn) += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* GRUB extension: compare numbers skipping prefixes.
|
/* GRUB extension: compare numbers skipping prefixes.
|
||||||
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
|
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
|
||||||
|
|||||||
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
@@ -103,6 +103,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||||||
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
|
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
|
||||||
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
||||||
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
||||||
|
#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000
|
||||||
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
|
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
|
||||||
|
|
||||||
/* The set of back-incompatible features this driver DOES support. Add (OR)
|
/* The set of back-incompatible features this driver DOES support. Add (OR)
|
||||||
@@ -123,9 +124,16 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||||||
* mmp: Not really back-incompatible - was added as such to
|
* mmp: Not really back-incompatible - was added as such to
|
||||||
* avoid multiple read-write mounts. Safe to ignore for this
|
* avoid multiple read-write mounts. Safe to ignore for this
|
||||||
* RO driver.
|
* RO driver.
|
||||||
|
* checksum seed: Not really back-incompatible - was added to allow tools
|
||||||
|
* such as tune2fs to change the UUID on a mounted metadata
|
||||||
|
* checksummed filesystem. Safe to ignore for now since the
|
||||||
|
* driver doesn't support checksum verification. But it must
|
||||||
|
* be removed from this list if that support is added later.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
|
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
|
||||||
| EXT4_FEATURE_INCOMPAT_MMP)
|
| EXT4_FEATURE_INCOMPAT_MMP \
|
||||||
|
| EXT4_FEATURE_INCOMPAT_CSUM_SEED)
|
||||||
|
|
||||||
|
|
||||||
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
|
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
|
||||||
@@ -723,10 +731,11 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
|||||||
if (! symlink)
|
if (! symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the filesize of the symlink is bigger than
|
/*
|
||||||
60 the symlink is stored in a separate block,
|
* If the filesize of the symlink is equal to or bigger than 60 the symlink
|
||||||
otherwise it is stored in the inode. */
|
* is stored in a separate block, otherwise it is stored in the inode.
|
||||||
if (grub_le_to_cpu32 (diro->inode.size) <= sizeof (diro->inode.symlink))
|
*/
|
||||||
|
if (grub_le_to_cpu32 (diro->inode.size) < sizeof (diro->inode.symlink))
|
||||||
grub_memcpy (symlink,
|
grub_memcpy (symlink,
|
||||||
diro->inode.symlink,
|
diro->inode.symlink,
|
||||||
grub_le_to_cpu32 (diro->inode.size));
|
grub_le_to_cpu32 (diro->inode.size));
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
|
|||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (read_hook != (grub_disk_read_hook_t)grub_disk_blocklist_read)
|
else if (read_hook != (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read)
|
||||||
grub_memset (buf, 0, blockend);
|
grub_memset (buf, 0, blockend);
|
||||||
|
|
||||||
buf += blocksize - skipfirst;
|
buf += blocksize - skipfirst;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -889,6 +889,7 @@ grub_ntfs_mount (grub_disk_t disk)
|
|||||||
struct grub_ntfs_bpb bpb;
|
struct grub_ntfs_bpb bpb;
|
||||||
struct grub_ntfs_data *data = 0;
|
struct grub_ntfs_data *data = 0;
|
||||||
grub_uint32_t spc;
|
grub_uint32_t spc;
|
||||||
|
grub_uint32_t sectors_per_cluster;
|
||||||
|
|
||||||
if (!disk)
|
if (!disk)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -903,14 +904,18 @@ grub_ntfs_mount (grub_disk_t disk)
|
|||||||
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
|
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
sectors_per_cluster = bpb.sectors_per_cluster;
|
||||||
|
if (sectors_per_cluster > 0x80)
|
||||||
|
sectors_per_cluster = 1U << (256U - bpb.sectors_per_cluster);
|
||||||
|
|
||||||
if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0
|
if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0
|
||||||
|| bpb.sectors_per_cluster == 0
|
|| sectors_per_cluster == 0
|
||||||
|| (bpb.sectors_per_cluster & (bpb.sectors_per_cluster - 1)) != 0
|
|| (sectors_per_cluster & (sectors_per_cluster - 1)) != 0
|
||||||
|| bpb.bytes_per_sector == 0
|
|| bpb.bytes_per_sector == 0
|
||||||
|| (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0)
|
|| (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
spc = (((grub_uint32_t) bpb.sectors_per_cluster
|
spc = (((grub_uint32_t) sectors_per_cluster
|
||||||
* (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
|
* (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
|
||||||
>> GRUB_NTFS_BLK_SHR);
|
>> GRUB_NTFS_BLK_SHR);
|
||||||
if (spc == 0)
|
if (spc == 0)
|
||||||
|
|||||||
1067
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/squash4.c
Normal file
1067
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/squash4.c
Normal file
File diff suppressed because it is too large
Load Diff
285
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/zfs/zfs_lz4.c
Normal file
285
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/zfs/zfs_lz4.c
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* LZ4 - Fast LZ compression algorithm
|
||||||
|
* Header File
|
||||||
|
* Copyright (C) 2011-2013, Yann Collet.
|
||||||
|
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You can contact the author at :
|
||||||
|
* - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||||
|
* - LZ4 source repository : http://code.google.com/p/lz4/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
|
||||||
|
int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
|
||||||
|
int isize, int maxOutputSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU Feature Detection
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 32 or 64 bits ? */
|
||||||
|
#if (GRUB_CPU_SIZEOF_VOID_P == 8)
|
||||||
|
#define LZ4_ARCH64 1
|
||||||
|
#else
|
||||||
|
#define LZ4_ARCH64 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compiler Options
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
|
|
||||||
|
#if (GCC_VERSION >= 302) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 800) || defined(__clang__)
|
||||||
|
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||||
|
#else
|
||||||
|
#define expect(expr, value) (expr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define likely(expr) expect((expr) != 0, 1)
|
||||||
|
#define unlikely(expr) expect((expr) != 0, 0)
|
||||||
|
|
||||||
|
/* Basic types */
|
||||||
|
#define BYTE grub_uint8_t
|
||||||
|
#define U16 grub_uint16_t
|
||||||
|
#define U32 grub_uint32_t
|
||||||
|
#define S32 grub_int32_t
|
||||||
|
#define U64 grub_uint64_t
|
||||||
|
|
||||||
|
typedef struct _U16_S {
|
||||||
|
U16 v;
|
||||||
|
} GRUB_PACKED U16_S;
|
||||||
|
typedef struct _U32_S {
|
||||||
|
U32 v;
|
||||||
|
} GRUB_PACKED U32_S;
|
||||||
|
typedef struct _U64_S {
|
||||||
|
U64 v;
|
||||||
|
} GRUB_PACKED U64_S;
|
||||||
|
|
||||||
|
#define A64(x) (((U64_S *)(x))->v)
|
||||||
|
#define A32(x) (((U32_S *)(x))->v)
|
||||||
|
#define A16(x) (((U16_S *)(x))->v)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constants
|
||||||
|
*/
|
||||||
|
#define MINMATCH 4
|
||||||
|
|
||||||
|
#define COPYLENGTH 8
|
||||||
|
#define LASTLITERALS 5
|
||||||
|
|
||||||
|
#define ML_BITS 4
|
||||||
|
#define ML_MASK ((1U<<ML_BITS)-1)
|
||||||
|
#define RUN_BITS (8-ML_BITS)
|
||||||
|
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Architecture-specific macros
|
||||||
|
*/
|
||||||
|
#if LZ4_ARCH64
|
||||||
|
#define STEPSIZE 8
|
||||||
|
#define UARCH U64
|
||||||
|
#define AARCH A64
|
||||||
|
#define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8;
|
||||||
|
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d)
|
||||||
|
#define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e)
|
||||||
|
#define HTYPE U32
|
||||||
|
#define INITBASE(base) const BYTE* const base = ip
|
||||||
|
#else
|
||||||
|
#define STEPSIZE 4
|
||||||
|
#define UARCH U32
|
||||||
|
#define AARCH A32
|
||||||
|
#define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4;
|
||||||
|
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
|
||||||
|
#define LZ4_SECURECOPY LZ4_WILDCOPY
|
||||||
|
#define HTYPE const BYTE*
|
||||||
|
#define INITBASE(base) const int base = 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - grub_le_to_cpu16 (A16 (p)); }
|
||||||
|
#define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = grub_cpu_to_le16 (v); p += 2; }
|
||||||
|
|
||||||
|
/* Macros */
|
||||||
|
#define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
|
||||||
|
|
||||||
|
/* Decompression functions */
|
||||||
|
grub_err_t
|
||||||
|
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len);
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len)
|
||||||
|
{
|
||||||
|
const BYTE *src = s_start;
|
||||||
|
U32 bufsiz = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) |
|
||||||
|
src[3];
|
||||||
|
|
||||||
|
/* invalid compressed buffer size encoded at start */
|
||||||
|
if (bufsiz + 4 > s_len)
|
||||||
|
return grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed.");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 0 on success (decompression function returned non-negative)
|
||||||
|
* and appropriate error on failure (decompression function returned negative).
|
||||||
|
*/
|
||||||
|
return (LZ4_uncompress_unknownOutputSize((char*)s_start + 4, d_start, bufsiz,
|
||||||
|
d_len) < 0)?grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."):0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LZ4_uncompress_unknownOutputSize(const char *source,
|
||||||
|
char *dest, int isize, int maxOutputSize)
|
||||||
|
{
|
||||||
|
/* Local Variables */
|
||||||
|
const BYTE * ip = (const BYTE *) source;
|
||||||
|
const BYTE *const iend = ip + isize;
|
||||||
|
const BYTE * ref;
|
||||||
|
|
||||||
|
BYTE * op = (BYTE *) dest;
|
||||||
|
BYTE *const oend = op + maxOutputSize;
|
||||||
|
BYTE *cpy;
|
||||||
|
|
||||||
|
grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/* Main Loop */
|
||||||
|
while (ip < iend) {
|
||||||
|
BYTE token;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
/* get runlength */
|
||||||
|
token = *ip++;
|
||||||
|
if ((length = (token >> ML_BITS)) == RUN_MASK) {
|
||||||
|
int s = 255;
|
||||||
|
while ((ip < iend) && (s == 255)) {
|
||||||
|
s = *ip++;
|
||||||
|
length += s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* copy literals */
|
||||||
|
if ((grub_addr_t) length > ~(grub_addr_t)op)
|
||||||
|
goto _output_error;
|
||||||
|
cpy = op + length;
|
||||||
|
if ((cpy > oend - COPYLENGTH) ||
|
||||||
|
(ip + length > iend - COPYLENGTH)) {
|
||||||
|
if (cpy > oend)
|
||||||
|
/*
|
||||||
|
* Error: request to write beyond destination
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
goto _output_error;
|
||||||
|
if (ip + length > iend)
|
||||||
|
/*
|
||||||
|
* Error : request to read beyond source
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
goto _output_error;
|
||||||
|
grub_memcpy(op, ip, length);
|
||||||
|
op += length;
|
||||||
|
ip += length;
|
||||||
|
if (ip < iend)
|
||||||
|
/* Error : LZ4 format violation */
|
||||||
|
goto _output_error;
|
||||||
|
/* Necessarily EOF, due to parsing restrictions. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LZ4_WILDCOPY(ip, op, cpy);
|
||||||
|
ip -= (op - cpy);
|
||||||
|
op = cpy;
|
||||||
|
|
||||||
|
/* get offset */
|
||||||
|
LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
|
||||||
|
ip += 2;
|
||||||
|
if (ref < (BYTE * const) dest)
|
||||||
|
/*
|
||||||
|
* Error: offset creates reference outside of
|
||||||
|
* destination buffer.
|
||||||
|
*/
|
||||||
|
goto _output_error;
|
||||||
|
|
||||||
|
/* get matchlength */
|
||||||
|
if ((length = (token & ML_MASK)) == ML_MASK) {
|
||||||
|
while (ip < iend) {
|
||||||
|
int s = *ip++;
|
||||||
|
length += s;
|
||||||
|
if (s == 255)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* copy repeated sequence */
|
||||||
|
if unlikely(op - ref < STEPSIZE) {
|
||||||
|
#if LZ4_ARCH64
|
||||||
|
grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
||||||
|
grub_size_t dec2 = dec2table[op - ref];
|
||||||
|
#else
|
||||||
|
const int dec2 = 0;
|
||||||
|
#endif
|
||||||
|
*op++ = *ref++;
|
||||||
|
*op++ = *ref++;
|
||||||
|
*op++ = *ref++;
|
||||||
|
*op++ = *ref++;
|
||||||
|
ref -= dec[op - ref];
|
||||||
|
A32(op) = A32(ref);
|
||||||
|
op += STEPSIZE - 4;
|
||||||
|
ref -= dec2;
|
||||||
|
} else {
|
||||||
|
LZ4_COPYSTEP(ref, op);
|
||||||
|
}
|
||||||
|
cpy = op + length - (STEPSIZE - 4);
|
||||||
|
if (cpy > oend - COPYLENGTH) {
|
||||||
|
if (cpy > oend)
|
||||||
|
/*
|
||||||
|
* Error: request to write outside of
|
||||||
|
* destination buffer.
|
||||||
|
*/
|
||||||
|
goto _output_error;
|
||||||
|
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
|
||||||
|
while (op < cpy)
|
||||||
|
*op++ = *ref++;
|
||||||
|
op = cpy;
|
||||||
|
if (op == oend)
|
||||||
|
/*
|
||||||
|
* Check EOF (should never happen, since last
|
||||||
|
* 5 bytes are supposed to be literals).
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LZ4_SECURECOPY(ref, op, cpy);
|
||||||
|
op = cpy; /* correction */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of decoding */
|
||||||
|
return (int)(((char *)op) - dest);
|
||||||
|
|
||||||
|
/* write overflow error detected */
|
||||||
|
_output_error:
|
||||||
|
return (int)(-(((char *)ip) - source));
|
||||||
|
}
|
||||||
@@ -119,6 +119,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
|||||||
view->menu = menu;
|
view->menu = menu;
|
||||||
view->nested = nested;
|
view->nested = nested;
|
||||||
view->first_timeout = -1;
|
view->first_timeout = -1;
|
||||||
|
if (menu->size)
|
||||||
|
view->menu_title_offset = grub_zalloc (sizeof (*view->menu_title_offset) * menu->size);
|
||||||
|
|
||||||
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
|
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
|
||||||
if (view->double_repaint)
|
if (view->double_repaint)
|
||||||
@@ -134,6 +136,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
|||||||
instance->fini = grub_gfxmenu_viewer_fini;
|
instance->fini = grub_gfxmenu_viewer_fini;
|
||||||
instance->print_timeout = grub_gfxmenu_print_timeout;
|
instance->print_timeout = grub_gfxmenu_print_timeout;
|
||||||
instance->clear_timeout = grub_gfxmenu_clear_timeout;
|
instance->clear_timeout = grub_gfxmenu_clear_timeout;
|
||||||
|
if (view->menu_title_offset)
|
||||||
|
instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry;
|
||||||
|
|
||||||
grub_menu_register_viewer (instance);
|
grub_menu_register_viewer (instance);
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,10 @@
|
|||||||
|
|
||||||
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;
|
||||||
|
extern char g_ventoy_hotkey_tip[256];
|
||||||
|
|
||||||
static const char *align_options[] =
|
static const char *align_options[] =
|
||||||
{
|
{
|
||||||
@@ -57,11 +60,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 +95,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 +104,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 +130,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,14 +221,21 @@ 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") : " ";
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
|
else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
|
||||||
value = grub_env_get("VTOY_HOTKEY_TIP");
|
value = g_ventoy_hotkey_tip;
|
||||||
if (value == NULL) {
|
} else if (value[0] == '@' && value[1] == '@' && value[2]) {
|
||||||
value = _(" ");
|
value = grub_env_get(value + 2);
|
||||||
}
|
if (!value)
|
||||||
|
value = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
self->template = grub_strdup (value);
|
self->template = grub_strdup (value);
|
||||||
@@ -247,8 +270,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)
|
||||||
|
|||||||
961
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_list.c
Normal file
961
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_list.c
Normal file
@@ -0,0 +1,961 @@
|
|||||||
|
/* gui_list.c - GUI component to display a selectable list of items. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/gui.h>
|
||||||
|
#include <grub/gui_string_util.h>
|
||||||
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/gfxwidgets.h>
|
||||||
|
#include <grub/color.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
|
enum scrollbar_slice_mode {
|
||||||
|
SCROLLBAR_SLICE_WEST,
|
||||||
|
SCROLLBAR_SLICE_CENTER,
|
||||||
|
SCROLLBAR_SLICE_EAST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_gui_list_impl
|
||||||
|
{
|
||||||
|
struct grub_gui_list list;
|
||||||
|
|
||||||
|
grub_gui_container_t parent;
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
char *id;
|
||||||
|
int visible;
|
||||||
|
|
||||||
|
int icon_width;
|
||||||
|
int icon_height;
|
||||||
|
int item_height;
|
||||||
|
int item_padding;
|
||||||
|
int item_icon_space;
|
||||||
|
int item_spacing;
|
||||||
|
grub_font_t item_font;
|
||||||
|
int selected_item_font_inherit;
|
||||||
|
grub_font_t selected_item_font;
|
||||||
|
grub_video_rgba_color_t item_color;
|
||||||
|
int selected_item_color_inherit;
|
||||||
|
grub_video_rgba_color_t selected_item_color;
|
||||||
|
|
||||||
|
int draw_scrollbar;
|
||||||
|
int need_to_recreate_scrollbar;
|
||||||
|
char *scrollbar_frame_pattern;
|
||||||
|
char *scrollbar_thumb_pattern;
|
||||||
|
grub_gfxmenu_box_t scrollbar_frame;
|
||||||
|
grub_gfxmenu_box_t scrollbar_thumb;
|
||||||
|
int scrollbar_thumb_overlay;
|
||||||
|
int scrollbar_width;
|
||||||
|
enum scrollbar_slice_mode scrollbar_slice;
|
||||||
|
int scrollbar_left_pad;
|
||||||
|
int scrollbar_right_pad;
|
||||||
|
int scrollbar_top_pad;
|
||||||
|
int scrollbar_bottom_pad;
|
||||||
|
|
||||||
|
int first_shown_index;
|
||||||
|
|
||||||
|
int need_to_recreate_boxes;
|
||||||
|
char *theme_dir;
|
||||||
|
char *menu_box_pattern;
|
||||||
|
char *item_box_pattern;
|
||||||
|
int selected_item_box_pattern_inherit;
|
||||||
|
char *selected_item_box_pattern;
|
||||||
|
grub_gfxmenu_box_t menu_box;
|
||||||
|
grub_gfxmenu_box_t selected_item_box;
|
||||||
|
grub_gfxmenu_box_t item_box;
|
||||||
|
|
||||||
|
grub_gfxmenu_icon_manager_t icon_manager;
|
||||||
|
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct grub_gui_list_impl *list_impl_t;
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_destroy (void *vself)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
|
||||||
|
grub_free (self->theme_dir);
|
||||||
|
grub_free (self->menu_box_pattern);
|
||||||
|
grub_free (self->item_box_pattern);
|
||||||
|
grub_free (self->selected_item_box_pattern);
|
||||||
|
if (self->menu_box)
|
||||||
|
self->menu_box->destroy (self->menu_box);
|
||||||
|
if (self->item_box)
|
||||||
|
self->item_box->destroy (self->item_box);
|
||||||
|
if (self->selected_item_box)
|
||||||
|
self->selected_item_box->destroy (self->selected_item_box);
|
||||||
|
if (self->icon_manager)
|
||||||
|
grub_gfxmenu_icon_manager_destroy (self->icon_manager);
|
||||||
|
if (self->scrollbar_thumb)
|
||||||
|
self->scrollbar_thumb->destroy (self->scrollbar_thumb);
|
||||||
|
if (self->scrollbar_frame)
|
||||||
|
self->scrollbar_frame->destroy (self->scrollbar_frame);
|
||||||
|
grub_free (self->scrollbar_thumb_pattern);
|
||||||
|
grub_free (self->scrollbar_frame_pattern);
|
||||||
|
grub_free (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_num_shown_items (list_impl_t self)
|
||||||
|
{
|
||||||
|
int boxpad = self->item_padding;
|
||||||
|
int item_vspace = self->item_spacing;
|
||||||
|
int item_height = self->item_height;
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t box = self->menu_box;
|
||||||
|
int box_top_pad = box->get_top_pad (box);
|
||||||
|
int box_bottom_pad = box->get_bottom_pad (box);
|
||||||
|
grub_gfxmenu_box_t itembox = self->item_box;
|
||||||
|
grub_gfxmenu_box_t selbox = self->selected_item_box;
|
||||||
|
int item_top_pad = itembox->get_top_pad (itembox);
|
||||||
|
int item_bottom_pad = itembox->get_bottom_pad (itembox);
|
||||||
|
int sel_top_pad = selbox->get_top_pad (selbox);
|
||||||
|
int sel_bottom_pad = selbox->get_bottom_pad (selbox);
|
||||||
|
int max_top_pad = grub_max (item_top_pad, sel_top_pad);
|
||||||
|
int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad);
|
||||||
|
|
||||||
|
if (item_height + item_vspace <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return (self->bounds.height + item_vspace - 2 * boxpad
|
||||||
|
- max_top_pad - max_bottom_pad
|
||||||
|
- box_top_pad - box_bottom_pad) / (item_height + item_vspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_boxes (list_impl_t self)
|
||||||
|
{
|
||||||
|
if (self->need_to_recreate_boxes)
|
||||||
|
{
|
||||||
|
grub_gui_recreate_box (&self->menu_box,
|
||||||
|
self->menu_box_pattern,
|
||||||
|
self->theme_dir);
|
||||||
|
|
||||||
|
grub_gui_recreate_box (&self->item_box,
|
||||||
|
self->item_box_pattern,
|
||||||
|
self->theme_dir);
|
||||||
|
|
||||||
|
grub_gui_recreate_box (&self->selected_item_box,
|
||||||
|
self->selected_item_box_pattern,
|
||||||
|
self->theme_dir);
|
||||||
|
|
||||||
|
self->need_to_recreate_boxes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (self->menu_box != 0 && self->selected_item_box != 0
|
||||||
|
&& self->item_box != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_scrollbar (list_impl_t self)
|
||||||
|
{
|
||||||
|
if (self->need_to_recreate_scrollbar)
|
||||||
|
{
|
||||||
|
grub_gui_recreate_box (&self->scrollbar_frame,
|
||||||
|
self->scrollbar_frame_pattern,
|
||||||
|
self->theme_dir);
|
||||||
|
|
||||||
|
grub_gui_recreate_box (&self->scrollbar_thumb,
|
||||||
|
self->scrollbar_thumb_pattern,
|
||||||
|
self->theme_dir);
|
||||||
|
|
||||||
|
self->need_to_recreate_scrollbar = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->scrollbar_frame == 0 || self->scrollbar_thumb == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Sanity checks. */
|
||||||
|
grub_gfxmenu_box_t frame = self->scrollbar_frame;
|
||||||
|
grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
|
||||||
|
grub_gfxmenu_box_t menu = self->menu_box;
|
||||||
|
int min_width = frame->get_left_pad (frame)
|
||||||
|
+ frame->get_right_pad (frame);
|
||||||
|
int min_height = frame->get_top_pad (frame)
|
||||||
|
+ frame->get_bottom_pad (frame)
|
||||||
|
+ self->scrollbar_top_pad + self->scrollbar_bottom_pad
|
||||||
|
+ menu->get_top_pad (menu)
|
||||||
|
+ menu->get_bottom_pad (menu);
|
||||||
|
if (!self->scrollbar_thumb_overlay)
|
||||||
|
{
|
||||||
|
min_width += thumb->get_left_pad (thumb)
|
||||||
|
+ thumb->get_right_pad (thumb);
|
||||||
|
min_height += thumb->get_top_pad (thumb)
|
||||||
|
+ thumb->get_bottom_pad (thumb);
|
||||||
|
}
|
||||||
|
if (min_width <= self->scrollbar_width
|
||||||
|
&& min_height <= (int) self->bounds.height)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Unprintable dimenstions. */
|
||||||
|
self->draw_scrollbar = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
list_get_id (void *vself)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
return self->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
list_is_instance (void *vself __attribute__((unused)), const char *type)
|
||||||
|
{
|
||||||
|
return (grub_strcmp (type, "component") == 0
|
||||||
|
|| grub_strcmp (type, "list") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_video_bitmap *
|
||||||
|
get_item_icon (list_impl_t self, int item_index)
|
||||||
|
{
|
||||||
|
grub_menu_entry_t entry;
|
||||||
|
entry = grub_menu_get_entry (self->view->menu, item_index);
|
||||||
|
if (! entry)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_selected_item_visible (list_impl_t self)
|
||||||
|
{
|
||||||
|
int selected_index = self->view->selected;
|
||||||
|
if (selected_index < 0)
|
||||||
|
return; /* No item is selected. */
|
||||||
|
int num_shown_items = get_num_shown_items (self);
|
||||||
|
int last_shown_index = self->first_shown_index + (num_shown_items - 1);
|
||||||
|
if (selected_index < self->first_shown_index)
|
||||||
|
self->first_shown_index = selected_index;
|
||||||
|
else if (selected_index > last_shown_index)
|
||||||
|
self->first_shown_index = selected_index - (num_shown_items - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a scrollbar on the menu. */
|
||||||
|
static void
|
||||||
|
draw_scrollbar (list_impl_t self,
|
||||||
|
int value, int extent, int min, int max,
|
||||||
|
int scrollbar_width, int scrollbar_height)
|
||||||
|
{
|
||||||
|
unsigned thumby, thumbheight;
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t frame = self->scrollbar_frame;
|
||||||
|
grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
|
||||||
|
int frame_vertical_pad = (frame->get_top_pad (frame)
|
||||||
|
+ frame->get_bottom_pad (frame));
|
||||||
|
int frame_horizontal_pad = (frame->get_left_pad (frame)
|
||||||
|
+ frame->get_right_pad (frame));
|
||||||
|
unsigned thumb_vertical_pad = (thumb->get_top_pad (thumb)
|
||||||
|
+ thumb->get_bottom_pad (thumb));
|
||||||
|
int thumb_horizontal_pad = (thumb->get_left_pad (thumb)
|
||||||
|
+ thumb->get_right_pad (thumb));
|
||||||
|
int tracktop = frame->get_top_pad (frame);
|
||||||
|
unsigned tracklen;
|
||||||
|
if (scrollbar_height <= frame_vertical_pad)
|
||||||
|
tracklen = 0;
|
||||||
|
else
|
||||||
|
tracklen = scrollbar_height - frame_vertical_pad;
|
||||||
|
frame->set_content_size (frame,
|
||||||
|
scrollbar_width - frame_horizontal_pad,
|
||||||
|
tracklen);
|
||||||
|
if (self->scrollbar_thumb_overlay)
|
||||||
|
{
|
||||||
|
tracklen += thumb_vertical_pad;
|
||||||
|
tracktop -= thumb->get_top_pad (thumb);
|
||||||
|
}
|
||||||
|
if (value <= min || max <= min)
|
||||||
|
thumby = 0;
|
||||||
|
else
|
||||||
|
thumby = ((unsigned) tracklen * (value - min))
|
||||||
|
/ ((unsigned) (max - min));
|
||||||
|
if (max <= min)
|
||||||
|
thumbheight = 1;
|
||||||
|
else
|
||||||
|
thumbheight = ((unsigned) (tracklen * extent)
|
||||||
|
/ ((unsigned) (max - min))) + 1;
|
||||||
|
/* Rare occasion: too many entries or too low height. */
|
||||||
|
if (thumbheight < thumb_vertical_pad)
|
||||||
|
{
|
||||||
|
thumbheight = thumb_vertical_pad;
|
||||||
|
if (value <= min || max <= extent
|
||||||
|
|| tracklen <= thumb_vertical_pad)
|
||||||
|
thumby = 0;
|
||||||
|
else
|
||||||
|
thumby = ((unsigned) ((tracklen - thumb_vertical_pad) * (value - min))
|
||||||
|
/ ((unsigned)(max - extent)));
|
||||||
|
}
|
||||||
|
thumby += tracktop;
|
||||||
|
int thumbx = frame->get_left_pad (frame);
|
||||||
|
int thumbwidth = scrollbar_width - frame_horizontal_pad;
|
||||||
|
if (!self->scrollbar_thumb_overlay)
|
||||||
|
thumbwidth -= thumb_horizontal_pad;
|
||||||
|
else
|
||||||
|
thumbx -= thumb->get_left_pad (thumb);
|
||||||
|
thumb->set_content_size (thumb, thumbwidth,
|
||||||
|
thumbheight - thumb_vertical_pad);
|
||||||
|
frame->draw (frame, 0, 0);
|
||||||
|
thumb->draw (thumb, thumbx, thumby);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw the list of items. */
|
||||||
|
static void
|
||||||
|
draw_menu (list_impl_t self, int num_shown_items)
|
||||||
|
{
|
||||||
|
if (! self->menu_box || ! self->selected_item_box || ! self->item_box)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int boxpad = self->item_padding;
|
||||||
|
int icon_text_space = self->item_icon_space;
|
||||||
|
int item_vspace = self->item_spacing;
|
||||||
|
|
||||||
|
int ascent = grub_font_get_ascent (self->item_font);
|
||||||
|
int descent = grub_font_get_descent (self->item_font);
|
||||||
|
int selected_ascent = grub_font_get_ascent (self->selected_item_font);
|
||||||
|
int selected_descent = grub_font_get_descent (self->selected_item_font);
|
||||||
|
int text_box_height = self->item_height;
|
||||||
|
|
||||||
|
make_selected_item_visible (self);
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t itembox = self->item_box;
|
||||||
|
grub_gfxmenu_box_t selbox = self->selected_item_box;
|
||||||
|
int item_leftpad = itembox->get_left_pad (itembox);
|
||||||
|
int item_rightpad = itembox->get_right_pad (itembox);
|
||||||
|
int item_border_width = item_leftpad + item_rightpad;
|
||||||
|
int item_toppad = itembox->get_top_pad (itembox);
|
||||||
|
int sel_leftpad = selbox->get_left_pad (selbox);
|
||||||
|
int sel_rightpad = selbox->get_right_pad (selbox);
|
||||||
|
int sel_border_width = sel_leftpad + sel_rightpad;
|
||||||
|
int sel_toppad = selbox->get_top_pad (selbox);
|
||||||
|
|
||||||
|
int max_leftpad = grub_max (item_leftpad, sel_leftpad);
|
||||||
|
int max_toppad = grub_max (item_toppad, sel_toppad);
|
||||||
|
int item_top = 0;
|
||||||
|
int menu_index;
|
||||||
|
int visible_index;
|
||||||
|
struct grub_video_rect oviewport;
|
||||||
|
|
||||||
|
grub_video_get_viewport (&oviewport.x, &oviewport.y,
|
||||||
|
&oviewport.width, &oviewport.height);
|
||||||
|
grub_video_set_viewport (oviewport.x + boxpad,
|
||||||
|
oviewport.y + boxpad,
|
||||||
|
oviewport.width - 2 * boxpad,
|
||||||
|
oviewport.height - 2 * boxpad);
|
||||||
|
|
||||||
|
int cwidth = oviewport.width - 2 * boxpad;
|
||||||
|
|
||||||
|
itembox->set_content_size (itembox, cwidth - item_border_width,
|
||||||
|
text_box_height);
|
||||||
|
selbox->set_content_size (selbox, cwidth - sel_border_width,
|
||||||
|
text_box_height);
|
||||||
|
|
||||||
|
int text_left_offset = self->icon_width + icon_text_space;
|
||||||
|
int item_text_top_offset = (text_box_height - (ascent + descent)) / 2 + ascent;
|
||||||
|
int sel_text_top_offset = (text_box_height - (selected_ascent
|
||||||
|
+ selected_descent)) / 2
|
||||||
|
+ selected_ascent;
|
||||||
|
|
||||||
|
grub_video_rect_t svpsave, sviewport;
|
||||||
|
sviewport.x = max_leftpad + text_left_offset;
|
||||||
|
int text_viewport_width = cwidth - sviewport.x;
|
||||||
|
sviewport.height = text_box_height;
|
||||||
|
|
||||||
|
grub_video_color_t item_color;
|
||||||
|
grub_video_color_t sel_color;
|
||||||
|
item_color = grub_video_map_rgba_color (self->item_color);
|
||||||
|
sel_color = grub_video_map_rgba_color (self->selected_item_color);
|
||||||
|
|
||||||
|
int item_box_top_offset = max_toppad - item_toppad;
|
||||||
|
int sel_box_top_offset = max_toppad - sel_toppad;
|
||||||
|
int item_viewport_width = text_viewport_width - item_rightpad;
|
||||||
|
int sel_viewport_width = text_viewport_width - sel_rightpad;
|
||||||
|
int tmp_icon_top_offset = (text_box_height - self->icon_height) / 2;
|
||||||
|
int item_icon_top_offset = item_toppad + tmp_icon_top_offset;
|
||||||
|
int sel_icon_top_offset = sel_toppad + tmp_icon_top_offset;
|
||||||
|
|
||||||
|
for (visible_index = 0, menu_index = self->first_shown_index;
|
||||||
|
visible_index < num_shown_items && menu_index < self->view->menu->size;
|
||||||
|
visible_index++, menu_index++)
|
||||||
|
{
|
||||||
|
int is_selected = (menu_index == self->view->selected);
|
||||||
|
struct grub_video_bitmap *icon;
|
||||||
|
grub_font_t font;
|
||||||
|
grub_video_color_t color;
|
||||||
|
int text_top_offset;
|
||||||
|
int top_pad;
|
||||||
|
int icon_top_offset;
|
||||||
|
int viewport_width;
|
||||||
|
|
||||||
|
if (is_selected)
|
||||||
|
{
|
||||||
|
selbox->draw (selbox, 0, item_top + sel_box_top_offset);
|
||||||
|
font = self->selected_item_font;
|
||||||
|
color = sel_color;
|
||||||
|
text_top_offset = sel_text_top_offset;
|
||||||
|
top_pad = sel_toppad;
|
||||||
|
icon_top_offset = sel_icon_top_offset;
|
||||||
|
viewport_width = sel_viewport_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itembox->draw (itembox, 0, item_top + item_box_top_offset);
|
||||||
|
font = self->item_font;
|
||||||
|
color = item_color;
|
||||||
|
text_top_offset = item_text_top_offset;
|
||||||
|
top_pad = item_toppad;
|
||||||
|
icon_top_offset = item_icon_top_offset;
|
||||||
|
viewport_width = item_viewport_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon = get_item_icon (self, menu_index);
|
||||||
|
if (icon != 0)
|
||||||
|
grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
|
||||||
|
max_leftpad,
|
||||||
|
item_top + icon_top_offset,
|
||||||
|
0, 0, self->icon_width, self->icon_height);
|
||||||
|
|
||||||
|
const char *item_title =
|
||||||
|
grub_menu_get_entry (self->view->menu, menu_index)->title;
|
||||||
|
|
||||||
|
|
||||||
|
int off = self->view->menu_title_offset[menu_index];
|
||||||
|
const char *scrolled_title =
|
||||||
|
grub_utf8_offset_code (item_title, grub_strlen (item_title), off);
|
||||||
|
if (scrolled_title)
|
||||||
|
item_title = scrolled_title;
|
||||||
|
|
||||||
|
sviewport.y = item_top + top_pad;
|
||||||
|
sviewport.width = viewport_width;
|
||||||
|
grub_gui_set_viewport (&sviewport, &svpsave);
|
||||||
|
grub_font_draw_string (item_title,
|
||||||
|
font,
|
||||||
|
color,
|
||||||
|
0,
|
||||||
|
text_top_offset);
|
||||||
|
grub_gui_restore_viewport (&svpsave);
|
||||||
|
|
||||||
|
item_top += text_box_height + item_vspace;
|
||||||
|
}
|
||||||
|
grub_video_set_viewport (oviewport.x,
|
||||||
|
oviewport.y,
|
||||||
|
oviewport.width,
|
||||||
|
oviewport.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_paint (void *vself, const grub_video_rect_t *region)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
grub_video_rect_t vpsave;
|
||||||
|
|
||||||
|
if (! self->visible)
|
||||||
|
return;
|
||||||
|
if (!grub_video_have_common_points (region, &self->bounds))
|
||||||
|
return;
|
||||||
|
|
||||||
|
check_boxes (self);
|
||||||
|
|
||||||
|
if (! self->menu_box || ! self->selected_item_box || ! self->item_box)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_gui_set_viewport (&self->bounds, &vpsave);
|
||||||
|
{
|
||||||
|
grub_gfxmenu_box_t box = self->menu_box;
|
||||||
|
int box_left_pad = box->get_left_pad (box);
|
||||||
|
int box_top_pad = box->get_top_pad (box);
|
||||||
|
int box_right_pad = box->get_right_pad (box);
|
||||||
|
int box_bottom_pad = box->get_bottom_pad (box);
|
||||||
|
grub_video_rect_t vpsave2, content_rect;
|
||||||
|
int num_shown_items = get_num_shown_items (self);
|
||||||
|
int drawing_scrollbar = (self->draw_scrollbar
|
||||||
|
&& (num_shown_items < self->view->menu->size)
|
||||||
|
&& check_scrollbar (self));
|
||||||
|
int scrollbar_width = self->scrollbar_width;
|
||||||
|
|
||||||
|
content_rect.x = box_left_pad;
|
||||||
|
content_rect.y = box_top_pad;
|
||||||
|
content_rect.width = self->bounds.width - box_left_pad - box_right_pad;
|
||||||
|
content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad;
|
||||||
|
|
||||||
|
box->set_content_size (box, content_rect.width, content_rect.height);
|
||||||
|
|
||||||
|
box->draw (box, 0, 0);
|
||||||
|
|
||||||
|
switch (self->scrollbar_slice)
|
||||||
|
{
|
||||||
|
case SCROLLBAR_SLICE_WEST:
|
||||||
|
content_rect.x += self->scrollbar_right_pad;
|
||||||
|
content_rect.width -= self->scrollbar_right_pad;
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_CENTER:
|
||||||
|
if (drawing_scrollbar)
|
||||||
|
content_rect.width -= scrollbar_width + self->scrollbar_left_pad
|
||||||
|
+ self->scrollbar_right_pad;
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_EAST:
|
||||||
|
content_rect.width -= self->scrollbar_left_pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_gui_set_viewport (&content_rect, &vpsave2);
|
||||||
|
draw_menu (self, num_shown_items);
|
||||||
|
grub_gui_restore_viewport (&vpsave2);
|
||||||
|
|
||||||
|
if (drawing_scrollbar)
|
||||||
|
{
|
||||||
|
content_rect.y += self->scrollbar_top_pad;
|
||||||
|
content_rect.height -= self->scrollbar_top_pad
|
||||||
|
+ self->scrollbar_bottom_pad;
|
||||||
|
content_rect.width = scrollbar_width;
|
||||||
|
switch (self->scrollbar_slice)
|
||||||
|
{
|
||||||
|
case SCROLLBAR_SLICE_WEST:
|
||||||
|
if (box_left_pad > scrollbar_width)
|
||||||
|
{
|
||||||
|
content_rect.x = box_left_pad - scrollbar_width;
|
||||||
|
content_rect.width = scrollbar_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content_rect.x = 0;
|
||||||
|
content_rect.width = box_left_pad;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_CENTER:
|
||||||
|
content_rect.x = self->bounds.width - box_right_pad
|
||||||
|
- scrollbar_width - self->scrollbar_right_pad;
|
||||||
|
content_rect.width = scrollbar_width;
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_EAST:
|
||||||
|
content_rect.x = self->bounds.width - box_right_pad;
|
||||||
|
content_rect.width = box_right_pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_gui_set_viewport (&content_rect, &vpsave2);
|
||||||
|
draw_scrollbar (self,
|
||||||
|
self->first_shown_index, num_shown_items,
|
||||||
|
0, self->view->menu->size,
|
||||||
|
scrollbar_width,
|
||||||
|
content_rect.height);
|
||||||
|
grub_gui_restore_viewport (&vpsave2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_gui_restore_viewport (&vpsave);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_set_parent (void *vself, grub_gui_container_t parent)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
self->parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_gui_container_t
|
||||||
|
list_get_parent (void *vself)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
return self->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_set_bounds (void *vself, const grub_video_rect_t *bounds)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
self->bounds = *bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_get_bounds (void *vself, grub_video_rect_t *bounds)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
*bounds = self->bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
|
||||||
|
if (check_boxes (self))
|
||||||
|
{
|
||||||
|
int boxpad = self->item_padding;
|
||||||
|
int item_vspace = self->item_spacing;
|
||||||
|
int item_height = self->item_height;
|
||||||
|
int num_items = 3;
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t box = self->menu_box;
|
||||||
|
int box_left_pad = box->get_left_pad (box);
|
||||||
|
int box_top_pad = box->get_top_pad (box);
|
||||||
|
int box_right_pad = box->get_right_pad (box);
|
||||||
|
int box_bottom_pad = box->get_bottom_pad (box);
|
||||||
|
unsigned width_s;
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t selbox = self->selected_item_box;
|
||||||
|
int sel_top_pad = selbox->get_top_pad (selbox);
|
||||||
|
int sel_bottom_pad = selbox->get_bottom_pad (selbox);
|
||||||
|
int sel_left_pad = selbox->get_left_pad (selbox);
|
||||||
|
int sel_right_pad = selbox->get_right_pad (selbox);
|
||||||
|
|
||||||
|
grub_gfxmenu_box_t itembox = self->item_box;
|
||||||
|
int item_top_pad = itembox->get_top_pad (itembox);
|
||||||
|
int item_bottom_pad = itembox->get_bottom_pad (itembox);
|
||||||
|
int item_left_pad = itembox->get_left_pad (itembox);
|
||||||
|
int item_right_pad = itembox->get_right_pad (itembox);
|
||||||
|
|
||||||
|
int max_left_pad = grub_max (item_left_pad, sel_left_pad);
|
||||||
|
int max_right_pad = grub_max (item_right_pad, sel_right_pad);
|
||||||
|
int max_top_pad = grub_max (item_top_pad, sel_top_pad);
|
||||||
|
int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad);
|
||||||
|
|
||||||
|
*width = grub_font_get_string_width (self->item_font, "Typical OS");
|
||||||
|
width_s = grub_font_get_string_width (self->selected_item_font,
|
||||||
|
"Typical OS");
|
||||||
|
if (*width < width_s)
|
||||||
|
*width = width_s;
|
||||||
|
|
||||||
|
*width += 2 * boxpad + box_left_pad + box_right_pad
|
||||||
|
+ max_left_pad + max_right_pad
|
||||||
|
+ self->item_icon_space + self->icon_width;
|
||||||
|
|
||||||
|
switch (self->scrollbar_slice)
|
||||||
|
{
|
||||||
|
case SCROLLBAR_SLICE_WEST:
|
||||||
|
*width += self->scrollbar_right_pad;
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_CENTER:
|
||||||
|
*width += self->scrollbar_width + self->scrollbar_left_pad
|
||||||
|
+ self->scrollbar_right_pad;
|
||||||
|
break;
|
||||||
|
case SCROLLBAR_SLICE_EAST:
|
||||||
|
*width += self->scrollbar_left_pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the menu box height to fit the items. */
|
||||||
|
*height = (item_height * num_items
|
||||||
|
+ item_vspace * (num_items - 1)
|
||||||
|
+ 2 * boxpad
|
||||||
|
+ box_top_pad + box_bottom_pad
|
||||||
|
+ max_top_pad + max_bottom_pad);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
list_set_property (void *vself, const char *name, const char *value)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
if (grub_strcmp (name, "item_font") == 0)
|
||||||
|
{
|
||||||
|
self->item_font = grub_font_get (value);
|
||||||
|
if (self->selected_item_font_inherit)
|
||||||
|
self->selected_item_font = self->item_font;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "selected_item_font") == 0)
|
||||||
|
{
|
||||||
|
if (! value || grub_strcmp (value, "inherit") == 0)
|
||||||
|
{
|
||||||
|
self->selected_item_font = self->item_font;
|
||||||
|
self->selected_item_font_inherit = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->selected_item_font = grub_font_get (value);
|
||||||
|
self->selected_item_font_inherit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_color") == 0)
|
||||||
|
{
|
||||||
|
grub_video_rgba_color_t color;
|
||||||
|
if (grub_video_parse_color (value, &color) == GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
self->item_color = color;
|
||||||
|
if (self->selected_item_color_inherit)
|
||||||
|
self->selected_item_color = self->item_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "selected_item_color") == 0)
|
||||||
|
{
|
||||||
|
if (! value || grub_strcmp (value, "inherit") == 0)
|
||||||
|
{
|
||||||
|
self->selected_item_color = self->item_color;
|
||||||
|
self->selected_item_color_inherit = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_video_rgba_color_t color;
|
||||||
|
if (grub_video_parse_color (value, &color)
|
||||||
|
== GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
self->selected_item_color = color;
|
||||||
|
self->selected_item_color_inherit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "icon_width") == 0)
|
||||||
|
{
|
||||||
|
self->icon_width = grub_strtol (value, 0, 10);
|
||||||
|
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
|
||||||
|
self->icon_width,
|
||||||
|
self->icon_height);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "icon_height") == 0)
|
||||||
|
{
|
||||||
|
self->icon_height = grub_strtol (value, 0, 10);
|
||||||
|
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
|
||||||
|
self->icon_width,
|
||||||
|
self->icon_height);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_height") == 0)
|
||||||
|
{
|
||||||
|
self->item_height = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_padding") == 0)
|
||||||
|
{
|
||||||
|
self->item_padding = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_icon_space") == 0)
|
||||||
|
{
|
||||||
|
self->item_icon_space = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_spacing") == 0)
|
||||||
|
{
|
||||||
|
self->item_spacing = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "visible") == 0)
|
||||||
|
{
|
||||||
|
self->visible = grub_strcmp (value, "false") != 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "menu_pixmap_style") == 0)
|
||||||
|
{
|
||||||
|
self->need_to_recreate_boxes = 1;
|
||||||
|
grub_free (self->menu_box_pattern);
|
||||||
|
self->menu_box_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "item_pixmap_style") == 0)
|
||||||
|
{
|
||||||
|
self->need_to_recreate_boxes = 1;
|
||||||
|
grub_free (self->item_box_pattern);
|
||||||
|
self->item_box_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
if (self->selected_item_box_pattern_inherit)
|
||||||
|
{
|
||||||
|
grub_free (self->selected_item_box_pattern);
|
||||||
|
self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "selected_item_pixmap_style") == 0)
|
||||||
|
{
|
||||||
|
if (!value || grub_strcmp (value, "inherit") == 0)
|
||||||
|
{
|
||||||
|
grub_free (self->selected_item_box_pattern);
|
||||||
|
char *tmp = self->item_box_pattern;
|
||||||
|
self->selected_item_box_pattern = tmp ? grub_strdup (tmp) : 0;
|
||||||
|
self->selected_item_box_pattern_inherit = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->need_to_recreate_boxes = 1;
|
||||||
|
grub_free (self->selected_item_box_pattern);
|
||||||
|
self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
self->selected_item_box_pattern_inherit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_frame") == 0)
|
||||||
|
{
|
||||||
|
self->need_to_recreate_scrollbar = 1;
|
||||||
|
grub_free (self->scrollbar_frame_pattern);
|
||||||
|
self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_thumb") == 0)
|
||||||
|
{
|
||||||
|
self->need_to_recreate_scrollbar = 1;
|
||||||
|
grub_free (self->scrollbar_thumb_pattern);
|
||||||
|
self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_thumb_overlay") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_thumb_overlay = grub_strcmp (value, "true") == 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_width") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_width = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_slice") == 0)
|
||||||
|
{
|
||||||
|
if (grub_strcmp (value, "west") == 0)
|
||||||
|
self->scrollbar_slice = SCROLLBAR_SLICE_WEST;
|
||||||
|
else if (grub_strcmp (value, "center") == 0)
|
||||||
|
self->scrollbar_slice = SCROLLBAR_SLICE_CENTER;
|
||||||
|
else if (grub_strcmp (value, "east") == 0)
|
||||||
|
self->scrollbar_slice = SCROLLBAR_SLICE_EAST;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_left_pad") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_left_pad = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_right_pad") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_right_pad = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_top_pad") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_top_pad = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar_bottom_pad") == 0)
|
||||||
|
{
|
||||||
|
self->scrollbar_bottom_pad = grub_strtol (value, 0, 10);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "scrollbar") == 0)
|
||||||
|
{
|
||||||
|
self->draw_scrollbar = grub_strcmp (value, "false") != 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "theme_dir") == 0)
|
||||||
|
{
|
||||||
|
self->need_to_recreate_boxes = 1;
|
||||||
|
grub_free (self->theme_dir);
|
||||||
|
self->theme_dir = value ? grub_strdup (value) : 0;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "id") == 0)
|
||||||
|
{
|
||||||
|
grub_free (self->id);
|
||||||
|
if (value)
|
||||||
|
self->id = grub_strdup (value);
|
||||||
|
else
|
||||||
|
self->id = 0;
|
||||||
|
}
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set necessary information that the gfxmenu view provides. */
|
||||||
|
static void
|
||||||
|
list_set_view_info (void *vself,
|
||||||
|
grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager,
|
||||||
|
view->theme_path);
|
||||||
|
self->view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Refresh list variables */
|
||||||
|
static void
|
||||||
|
list_refresh_info (void *vself,
|
||||||
|
grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
list_impl_t self = vself;
|
||||||
|
if (view->nested)
|
||||||
|
self->first_shown_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_gui_component_ops list_comp_ops =
|
||||||
|
{
|
||||||
|
.destroy = list_destroy,
|
||||||
|
.get_id = list_get_id,
|
||||||
|
.is_instance = list_is_instance,
|
||||||
|
.paint = list_paint,
|
||||||
|
.set_parent = list_set_parent,
|
||||||
|
.get_parent = list_get_parent,
|
||||||
|
.set_bounds = list_set_bounds,
|
||||||
|
.get_bounds = list_get_bounds,
|
||||||
|
.get_minimal_size = list_get_minimal_size,
|
||||||
|
.set_property = list_set_property
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct grub_gui_list_ops list_ops =
|
||||||
|
{
|
||||||
|
.set_view_info = list_set_view_info,
|
||||||
|
.refresh_list = list_refresh_info
|
||||||
|
};
|
||||||
|
|
||||||
|
grub_gui_component_t
|
||||||
|
grub_gui_list_new (void)
|
||||||
|
{
|
||||||
|
list_impl_t self;
|
||||||
|
grub_font_t default_font;
|
||||||
|
grub_video_rgba_color_t default_fg_color;
|
||||||
|
|
||||||
|
self = grub_zalloc (sizeof (*self));
|
||||||
|
if (! self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
self->list.ops = &list_ops;
|
||||||
|
self->list.component.ops = &list_comp_ops;
|
||||||
|
|
||||||
|
self->visible = 1;
|
||||||
|
|
||||||
|
default_font = grub_font_get ("Unknown Regular 16");
|
||||||
|
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
||||||
|
|
||||||
|
self->icon_width = 32;
|
||||||
|
self->icon_height = 32;
|
||||||
|
self->item_height = 42;
|
||||||
|
self->item_padding = 14;
|
||||||
|
self->item_icon_space = 4;
|
||||||
|
self->item_spacing = 16;
|
||||||
|
self->item_font = default_font;
|
||||||
|
self->selected_item_font_inherit = 1; /* Default to using the item_font. */
|
||||||
|
self->selected_item_font = default_font;
|
||||||
|
self->item_color = default_fg_color;
|
||||||
|
self->selected_item_color_inherit = 1; /* Default to using the item_color. */
|
||||||
|
self->selected_item_color = default_fg_color;
|
||||||
|
|
||||||
|
self->draw_scrollbar = 1;
|
||||||
|
self->need_to_recreate_scrollbar = 1;
|
||||||
|
self->scrollbar_frame = 0;
|
||||||
|
self->scrollbar_thumb = 0;
|
||||||
|
self->scrollbar_frame_pattern = 0;
|
||||||
|
self->scrollbar_thumb_pattern = 0;
|
||||||
|
self->scrollbar_thumb_overlay = 0;
|
||||||
|
self->scrollbar_width = 16;
|
||||||
|
self->scrollbar_slice = SCROLLBAR_SLICE_EAST;
|
||||||
|
self->scrollbar_left_pad = 2;
|
||||||
|
self->scrollbar_right_pad = 0;
|
||||||
|
self->scrollbar_top_pad = 0;
|
||||||
|
self->scrollbar_bottom_pad = 0;
|
||||||
|
|
||||||
|
self->first_shown_index = 0;
|
||||||
|
|
||||||
|
self->need_to_recreate_boxes = 0;
|
||||||
|
self->theme_dir = 0;
|
||||||
|
self->menu_box_pattern = 0;
|
||||||
|
self->item_box_pattern = 0;
|
||||||
|
self->selected_item_box_pattern_inherit = 1;/*Default to using the item_box.*/
|
||||||
|
self->selected_item_box_pattern = 0;
|
||||||
|
self->menu_box = grub_gfxmenu_create_box (0, 0);
|
||||||
|
self->item_box = grub_gfxmenu_create_box (0, 0);
|
||||||
|
self->selected_item_box = grub_gfxmenu_create_box (0, 0);
|
||||||
|
|
||||||
|
self->icon_manager = grub_gfxmenu_icon_manager_new ();
|
||||||
|
if (! self->icon_manager)
|
||||||
|
{
|
||||||
|
self->list.component.ops->destroy (self);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
|
||||||
|
self->icon_width,
|
||||||
|
self->icon_height);
|
||||||
|
return (grub_gui_component_t) self;
|
||||||
|
}
|
||||||
@@ -163,6 +163,12 @@ theme_set_string (grub_gfxmenu_view_t view,
|
|||||||
grub_video_parse_color (value, &view->message_color);
|
grub_video_parse_color (value, &view->message_color);
|
||||||
else if (! grub_strcmp ("message-bg-color", name))
|
else if (! grub_strcmp ("message-bg-color", name))
|
||||||
grub_video_parse_color (value, &view->message_bg_color);
|
grub_video_parse_color (value, &view->message_bg_color);
|
||||||
|
else if (! grub_strcmp("menu-tip-left", name))
|
||||||
|
grub_env_set("VTOY_TIP_LEFT", value);
|
||||||
|
else if (! grub_strcmp("menu-tip-top", name))
|
||||||
|
grub_env_set("VTOY_TIP_TOP", value);
|
||||||
|
else if (! grub_strcmp("menu-tip-color", name))
|
||||||
|
grub_env_set("VTOY_TIP_COLOR", value);
|
||||||
else if (! grub_strcmp ("desktop-image", name))
|
else if (! grub_strcmp ("desktop-image", name))
|
||||||
{
|
{
|
||||||
struct grub_video_bitmap *raw_bitmap;
|
struct grub_video_bitmap *raw_bitmap;
|
||||||
@@ -289,6 +295,8 @@ theme_set_string (grub_gfxmenu_view_t view,
|
|||||||
if (! view->title_text)
|
if (! view->title_text)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
else if (! grub_strcmp ("ventoy_left_top_color", name))
|
||||||
|
return grub_errno;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
@@ -450,7 +458,8 @@ read_expression (struct parsebuf *p)
|
|||||||
/* Read as a single word -- for numeric values or words without
|
/* Read as a single word -- for numeric values or words without
|
||||||
whitespace. */
|
whitespace. */
|
||||||
start = p->pos;
|
start = p->pos;
|
||||||
while (has_more (p) && ! is_whitespace (peek_char (p)))
|
while (has_more (p) && ! is_whitespace (peek_char (p))
|
||||||
|
&& peek_char (p) != '}')
|
||||||
read_char (p);
|
read_char (p);
|
||||||
end = p->pos;
|
end = p->pos;
|
||||||
}
|
}
|
||||||
@@ -725,6 +734,11 @@ read_property (struct parsebuf *p)
|
|||||||
"%s:%d:%d property value invalid; "
|
"%s:%d:%d property value invalid; "
|
||||||
"enclose literal values in quotes (\")",
|
"enclose literal values in quotes (\")",
|
||||||
p->filename, p->line_num, p->col_num);
|
p->filename, p->line_num, p->col_num);
|
||||||
|
|
||||||
|
grub_printf("File: %s\nLine:%d Column:%d\n"
|
||||||
|
"property value invalid; enclose literal values in quotes (\")\n\n",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,11 +747,14 @@ done:
|
|||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int g_menu_update_mode;
|
||||||
|
|
||||||
/* Set properties on the view based on settings from the specified
|
/* Set properties on the view based on settings from the specified
|
||||||
theme file. */
|
theme file. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
||||||
{
|
{
|
||||||
|
int flag = 0;
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
struct parsebuf p;
|
struct parsebuf p;
|
||||||
|
|
||||||
@@ -752,7 +769,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.len = grub_file_size (file);
|
p.len = grub_file_size (file);
|
||||||
p.buf = grub_malloc (p.len + 4096);
|
p.buf = grub_malloc (p.len + 8192);
|
||||||
p.pos = 0;
|
p.pos = 0;
|
||||||
p.line_num = 1;
|
p.line_num = 1;
|
||||||
p.col_num = 1;
|
p.col_num = 1;
|
||||||
@@ -781,6 +798,8 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (view->canvas)
|
if (view->canvas)
|
||||||
view->canvas->component.ops->destroy (view->canvas);
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
|
||||||
@@ -791,6 +810,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
|||||||
->ops->set_bounds ((grub_gui_component_t) view->canvas,
|
->ops->set_bounds ((grub_gui_component_t) view->canvas,
|
||||||
&view->screen);
|
&view->screen);
|
||||||
|
|
||||||
|
parse:
|
||||||
while (has_more (&p))
|
while (has_more (&p))
|
||||||
{
|
{
|
||||||
/* Skip comments (lines beginning with #). */
|
/* Skip comments (lines beginning with #). */
|
||||||
@@ -819,6 +839,40 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (flag == 0)
|
||||||
|
{
|
||||||
|
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")
|
||||||
|
);
|
||||||
|
|
||||||
|
flag = 1;
|
||||||
|
goto parse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the new theme path. */
|
/* Set the new theme path. */
|
||||||
grub_free (view->theme_path);
|
grub_free (view->theme_path);
|
||||||
view->theme_path = grub_strdup (theme_path);
|
view->theme_path = grub_strdup (theme_path);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <grub/gui_string_util.h>
|
#include <grub/gui_string_util.h>
|
||||||
#include <grub/icon_manager.h>
|
#include <grub/icon_manager.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_terminal (grub_gfxmenu_view_t view);
|
init_terminal (grub_gfxmenu_view_t view);
|
||||||
@@ -142,6 +143,8 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
|
|||||||
grub_free (view->title_text);
|
grub_free (view->title_text);
|
||||||
grub_free (view->progress_message_text);
|
grub_free (view->progress_message_text);
|
||||||
grub_free (view->theme_path);
|
grub_free (view->theme_path);
|
||||||
|
if (view->menu_title_offset)
|
||||||
|
grub_free (view->menu_title_offset);
|
||||||
if (view->canvas)
|
if (view->canvas)
|
||||||
view->canvas->component.ops->destroy (view->canvas);
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
grub_free (view);
|
grub_free (view);
|
||||||
@@ -386,21 +389,37 @@ redraw_menu_visit (grub_gui_component_t component,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
|
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
|
||||||
{
|
{
|
||||||
update_menu_components (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,
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
redraw_menu_visit, view);
|
redraw_menu_visit, view);
|
||||||
|
|
||||||
grub_video_swap_buffers ();
|
grub_video_swap_buffers ();
|
||||||
if (view->double_repaint)
|
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,
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
redraw_menu_visit, view);
|
redraw_menu_visit, view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_gfxmenu_set_chosen_entry (int entry, void *data)
|
grub_gfxmenu_set_chosen_entry (int entry, void *data)
|
||||||
{
|
{
|
||||||
@@ -408,6 +427,34 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data)
|
|||||||
|
|
||||||
view->selected = entry;
|
view->selected = entry;
|
||||||
grub_gfxmenu_redraw_menu (view);
|
grub_gfxmenu_redraw_menu (view);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_scroll_chosen_entry (void *data, int diren)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = data;
|
||||||
|
const char *item_title;
|
||||||
|
int off;
|
||||||
|
int max;
|
||||||
|
|
||||||
|
if (!view->menu->size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
item_title = grub_menu_get_entry (view->menu, view->selected)->title;
|
||||||
|
off = view->menu_title_offset[view->selected] + diren;
|
||||||
|
max = grub_utf8_get_num_code (item_title, grub_strlen(item_title));
|
||||||
|
|
||||||
|
if (diren == 1000000)
|
||||||
|
off = (max >= 20) ? (max - 20) : 0;
|
||||||
|
else if (off < 0)
|
||||||
|
off = 0;
|
||||||
|
else if (off > max)
|
||||||
|
off = max;
|
||||||
|
|
||||||
|
view->menu_title_offset[view->selected] = off;
|
||||||
|
grub_gfxmenu_redraw_menu (view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ grub_err_t
|
|||||||
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
grub_off_t offset, grub_size_t size, void *buf)
|
grub_off_t offset, grub_size_t size, void *buf)
|
||||||
{
|
{
|
||||||
if (disk->read_hook == (grub_disk_read_hook_t)grub_disk_blocklist_read)
|
if (disk->read_hook == (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read)
|
||||||
{
|
{
|
||||||
return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size);
|
return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
702
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c
Normal file
702
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* 160MB 160 * 1024 * 1024 / 4096 */
|
||||||
|
#define VTOY_CHAIN_MIN_PAGES (160 * 256)
|
||||||
|
static grub_efi_uint64_t g_total_pages;
|
||||||
|
static grub_efi_uint64_t g_org_required_pages;
|
||||||
|
static grub_efi_uint64_t g_new_required_pages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
g_org_required_pages = required_pages;
|
||||||
|
if (((total_pages - required_pages) >> 2) < VTOY_CHAIN_MIN_PAGES)
|
||||||
|
{
|
||||||
|
if (total_pages > (VTOY_CHAIN_MIN_PAGES << 2))
|
||||||
|
{
|
||||||
|
g_new_required_pages = total_pages - (VTOY_CHAIN_MIN_PAGES << 2);
|
||||||
|
if (g_new_required_pages >= 8192)
|
||||||
|
{
|
||||||
|
required_pages = g_new_required_pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_total_pages = total_pages;
|
||||||
|
g_new_required_pages = required_pages;
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
void grub_efi_get_reserved_page_num(grub_uint64_t *total, grub_uint64_t *org_required, grub_uint64_t *new_required)
|
||||||
|
{
|
||||||
|
*total = g_total_pages;
|
||||||
|
*org_required = g_org_required_pages;
|
||||||
|
*new_required = g_new_required_pages;
|
||||||
|
}
|
||||||
|
|
||||||
250
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/env.c
Normal file
250
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/env.c
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/* env.c - Environment variables */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2003,2005,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/env.h>
|
||||||
|
#include <grub/env_private.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
|
/* The initial context. */
|
||||||
|
static struct grub_env_context initial_context;
|
||||||
|
|
||||||
|
/* The current context. */
|
||||||
|
struct grub_env_context *grub_current_context = &initial_context;
|
||||||
|
|
||||||
|
static grub_env_read_hook_t vtoy_menu_lang_read_hook;
|
||||||
|
|
||||||
|
/* Return the hash representation of the string S. */
|
||||||
|
static unsigned int
|
||||||
|
grub_env_hashval (const char *s)
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
/* XXX: This can be done much more efficiently. */
|
||||||
|
while (*s)
|
||||||
|
i += 5 * *(s++);
|
||||||
|
|
||||||
|
return i % HASHSZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_env_var *
|
||||||
|
grub_env_find (const char *name)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
int idx = grub_env_hashval (name);
|
||||||
|
|
||||||
|
/* Look for the variable in the current context. */
|
||||||
|
for (var = grub_current_context->vars[idx]; var; var = var->next)
|
||||||
|
if (grub_strcmp (var->name, name) == 0)
|
||||||
|
return var;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_env_insert (struct grub_env_context *context,
|
||||||
|
struct grub_env_var *var)
|
||||||
|
{
|
||||||
|
int idx = grub_env_hashval (var->name);
|
||||||
|
|
||||||
|
/* Insert the variable into the hashtable. */
|
||||||
|
var->prevp = &context->vars[idx];
|
||||||
|
var->next = context->vars[idx];
|
||||||
|
if (var->next)
|
||||||
|
var->next->prevp = &(var->next);
|
||||||
|
context->vars[idx] = var;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_env_remove (struct grub_env_var *var)
|
||||||
|
{
|
||||||
|
/* Remove the entry from the variable table. */
|
||||||
|
*var->prevp = var->next;
|
||||||
|
if (var->next)
|
||||||
|
var->next->prevp = var->prevp;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_env_set (const char *name, const char *val)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
|
||||||
|
/* If the variable does already exist, just update the variable. */
|
||||||
|
var = grub_env_find (name);
|
||||||
|
if (var)
|
||||||
|
{
|
||||||
|
char *old = var->value;
|
||||||
|
|
||||||
|
if (var->write_hook)
|
||||||
|
var->value = var->write_hook (var, val);
|
||||||
|
else
|
||||||
|
var->value = grub_strdup (val);
|
||||||
|
|
||||||
|
if (! var->value)
|
||||||
|
{
|
||||||
|
var->value = old;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free (old);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The variable does not exist, so create a new one. */
|
||||||
|
var = grub_zalloc (sizeof (*var));
|
||||||
|
if (! var)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
var->name = grub_strdup (name);
|
||||||
|
if (! var->name)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
var->value = grub_strdup (val);
|
||||||
|
if (! var->value)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_env_insert (grub_current_context, var);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (var->name);
|
||||||
|
grub_free (var->value);
|
||||||
|
grub_free (var);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
grub_env_get (const char *name)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
|
||||||
|
if (name && vtoy_menu_lang_read_hook && grub_strncmp(name, "VTLANG_", 7) == 0)
|
||||||
|
return vtoy_menu_lang_read_hook(NULL, name);
|
||||||
|
|
||||||
|
var = grub_env_find (name);
|
||||||
|
if (! var)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (var->read_hook)
|
||||||
|
return var->read_hook (var, var->value);
|
||||||
|
|
||||||
|
return var->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_env_unset (const char *name)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
|
||||||
|
var = grub_env_find (name);
|
||||||
|
if (! var)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (var->read_hook || var->write_hook)
|
||||||
|
{
|
||||||
|
grub_env_set (name, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_env_remove (var);
|
||||||
|
|
||||||
|
grub_free (var->name);
|
||||||
|
grub_free (var->value);
|
||||||
|
grub_free (var);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_env_var *
|
||||||
|
grub_env_update_get_sorted (void)
|
||||||
|
{
|
||||||
|
struct grub_env_var *sorted_list = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Add variables associated with this context into a sorted list. */
|
||||||
|
for (i = 0; i < HASHSZ; i++)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
|
||||||
|
for (var = grub_current_context->vars[i]; var; var = var->next)
|
||||||
|
{
|
||||||
|
struct grub_env_var *p, **q;
|
||||||
|
|
||||||
|
for (q = &sorted_list, p = *q; p; q = &((*q)->sorted_next), p = *q)
|
||||||
|
{
|
||||||
|
if (grub_strcmp (p->name, var->name) > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var->sorted_next = *q;
|
||||||
|
*q = var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sorted_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_register_variable_hook (const char *name,
|
||||||
|
grub_env_read_hook_t read_hook,
|
||||||
|
grub_env_write_hook_t write_hook)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var = grub_env_find (name);
|
||||||
|
|
||||||
|
if (! var)
|
||||||
|
{
|
||||||
|
if (grub_env_set (name, "") != GRUB_ERR_NONE)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
var = grub_env_find (name);
|
||||||
|
/* XXX Insert an assertion? */
|
||||||
|
}
|
||||||
|
|
||||||
|
var->read_hook = read_hook;
|
||||||
|
var->write_hook = write_hook;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_register_vtoy_menu_lang_hook(grub_env_read_hook_t read_hook)
|
||||||
|
{
|
||||||
|
vtoy_menu_lang_read_hook = read_hook;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_env_export (const char *name)
|
||||||
|
{
|
||||||
|
struct grub_env_var *var;
|
||||||
|
|
||||||
|
var = grub_env_find (name);
|
||||||
|
if (! var)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
err = grub_env_set (name, "");
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
var = grub_env_find (name);
|
||||||
|
}
|
||||||
|
var->global = 1;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
@@ -106,20 +106,137 @@ 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)
|
||||||
|
{
|
||||||
|
if (vlnk)
|
||||||
|
*vlnk = 1;
|
||||||
|
return g_vtoy_vlnk.dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
if (node->srclen == len && grub_strcmp(name, node->src) == 0)
|
||||||
|
{
|
||||||
|
if (vlnk)
|
||||||
|
*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 +258,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
|
||||||
@@ -224,11 +342,13 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (file->name) {
|
||||||
if (grub_strncmp(file->name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) {
|
if (grub_strncmp(file->name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) {
|
||||||
grub_memcpy(buf, (grub_uint8_t *)(file->data) + file->offset, len);
|
grub_memcpy(buf, (grub_uint8_t *)(file->data) + file->offset, len);
|
||||||
file->offset += len;
|
file->offset += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
read_hook = file->read_hook;
|
read_hook = file->read_hook;
|
||||||
read_hook_data = file->read_hook_data;
|
read_hook_data = file->read_hook_data;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
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
|
||||||
69
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S
Normal file
69
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2003,2007,2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/symbol.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/mips64/asm.h>
|
||||||
|
|
||||||
|
.file "setjmp.S"
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE "GPLv3+"
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int grub_setjmp (grub_jmp_buf env)
|
||||||
|
*/
|
||||||
|
FUNCTION(grub_setjmp)
|
||||||
|
GRUB_ASM_REG_S $s0, 0($a0)
|
||||||
|
GRUB_ASM_REG_S $s1, 8($a0)
|
||||||
|
GRUB_ASM_REG_S $s2, 16($a0)
|
||||||
|
GRUB_ASM_REG_S $s3, 24($a0)
|
||||||
|
GRUB_ASM_REG_S $s4, 32($a0)
|
||||||
|
GRUB_ASM_REG_S $s5, 40($a0)
|
||||||
|
GRUB_ASM_REG_S $s6, 48($a0)
|
||||||
|
GRUB_ASM_REG_S $s7, 56($a0)
|
||||||
|
GRUB_ASM_REG_S $s8, 64($a0)
|
||||||
|
GRUB_ASM_REG_S $gp, 72($a0)
|
||||||
|
GRUB_ASM_REG_S $sp, 80($a0)
|
||||||
|
GRUB_ASM_REG_S $ra, 88($a0)
|
||||||
|
move $v0, $zero
|
||||||
|
move $v1, $zero
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
|
/*
|
||||||
|
* int grub_longjmp (grub_jmp_buf env, int val)
|
||||||
|
*/
|
||||||
|
FUNCTION(grub_longjmp)
|
||||||
|
GRUB_ASM_REG_L $s0, 0($a0)
|
||||||
|
GRUB_ASM_REG_L $s1, 8($a0)
|
||||||
|
GRUB_ASM_REG_L $s2, 16($a0)
|
||||||
|
GRUB_ASM_REG_L $s3, 24($a0)
|
||||||
|
GRUB_ASM_REG_L $s4, 32($a0)
|
||||||
|
GRUB_ASM_REG_L $s5, 40($a0)
|
||||||
|
GRUB_ASM_REG_L $s6, 48($a0)
|
||||||
|
GRUB_ASM_REG_L $s7, 56($a0)
|
||||||
|
GRUB_ASM_REG_L $s8, 64($a0)
|
||||||
|
GRUB_ASM_REG_L $gp, 72($a0)
|
||||||
|
GRUB_ASM_REG_L $sp, 80($a0)
|
||||||
|
GRUB_ASM_REG_L $ra, 88($a0)
|
||||||
|
addiu $v0, $zero, 1
|
||||||
|
movn $v0, $a1, $a1
|
||||||
|
move $v1, $zero
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
1660
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c
Normal file
1660
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c
Normal file
File diff suppressed because it is too large
Load Diff
26
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S
Normal file
26
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#if defined(__i386__)
|
||||||
|
#include "./i386/setjmp.S"
|
||||||
|
#elif defined(__x86_64__)
|
||||||
|
#include "./x86_64/setjmp.S"
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
#include "./sparc64/setjmp.S"
|
||||||
|
#elif defined(__mips__)
|
||||||
|
#if _MIPS_SIM == _ABI64
|
||||||
|
#include "./mips64/setjmp.S"
|
||||||
|
#else
|
||||||
|
#include "./mips/setjmp.S"
|
||||||
|
#endif
|
||||||
|
#elif defined(__powerpc__) || defined(__PPC__)
|
||||||
|
#include "./powerpc/setjmp.S"
|
||||||
|
#elif defined(__ia64__)
|
||||||
|
#include "./ia64/setjmp.S"
|
||||||
|
#include "./ia64/longjmp.S"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#include "./arm/setjmp.S"
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#include "./arm64/setjmp.S"
|
||||||
|
#elif defined(__riscv)
|
||||||
|
#include "./riscv/setjmp.S"
|
||||||
|
#else
|
||||||
|
#error "Unknown target cpu type"
|
||||||
|
#endif
|
||||||
@@ -362,7 +362,8 @@ static grub_err_t
|
|||||||
cmd_append (const char *line, struct syslinux_menu *menu)
|
cmd_append (const char *line, struct syslinux_menu *menu)
|
||||||
{
|
{
|
||||||
if (!menu->entries)
|
if (!menu->entries)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
|
return GRUB_ERR_NONE;
|
||||||
|
//return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
|
||||||
|
|
||||||
menu->entries->append = grub_strdup (line);
|
menu->entries->append = grub_strdup (line);
|
||||||
if (!menu->entries->append)
|
if (!menu->entries->append)
|
||||||
|
|||||||
859
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c
Normal file
859
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c
Normal file
@@ -0,0 +1,859 @@
|
|||||||
|
/*
|
||||||
|
* 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/charset.h>
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/fdt.h>
|
||||||
|
#include <grub/linux.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/cpu/linux.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/efi/fdtload.h>
|
||||||
|
#include <grub/efi/memory.h>
|
||||||
|
#include <grub/efi/pe32.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/lib/cmdline.h>
|
||||||
|
#include <grub/verify.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
static grub_dl_t my_mod;
|
||||||
|
static int loaded;
|
||||||
|
|
||||||
|
static void *kernel_addr;
|
||||||
|
static grub_uint64_t kernel_size;
|
||||||
|
|
||||||
|
static char *linux_args;
|
||||||
|
static grub_uint32_t cmdline_size;
|
||||||
|
|
||||||
|
static grub_addr_t initrd_start;
|
||||||
|
static grub_addr_t initrd_end;
|
||||||
|
|
||||||
|
#define LINUX_MAX_ARGC 1024
|
||||||
|
static int ventoy_debug = 0;
|
||||||
|
static int ventoy_initrd_called = 0;
|
||||||
|
static int ventoy_linux_argc = 0;
|
||||||
|
static char **ventoy_linux_args = NULL;
|
||||||
|
static int ventoy_extra_initrd_num = 0;
|
||||||
|
static char *ventoy_extra_initrd_list[256];
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
|
||||||
|
{
|
||||||
|
if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
|
||||||
|
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
||||||
|
|
||||||
|
if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
|
||||||
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||||
|
grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
finalize_params_linux (void)
|
||||||
|
{
|
||||||
|
int node, retval;
|
||||||
|
|
||||||
|
void *fdt;
|
||||||
|
|
||||||
|
fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
||||||
|
|
||||||
|
if (!fdt)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||||
|
if (node < 0)
|
||||||
|
node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||||
|
|
||||||
|
if (node < 1)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
/* Set initrd info */
|
||||||
|
if (initrd_start && initrd_end > initrd_start)
|
||||||
|
{
|
||||||
|
grub_dprintf ("linux", "Initrd @ %p-%p\n",
|
||||||
|
(void *) initrd_start, (void *) initrd_end);
|
||||||
|
|
||||||
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
||||||
|
initrd_start);
|
||||||
|
if (retval)
|
||||||
|
goto failure;
|
||||||
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
||||||
|
initrd_end);
|
||||||
|
if (retval)
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_fdt_install() != GRUB_ERR_NONE)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
grub_fdt_unload();
|
||||||
|
return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||||
|
{
|
||||||
|
grub_efi_memory_mapped_device_path_t *mempath;
|
||||||
|
grub_efi_handle_t image_handle;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_loaded_image_t *loaded_image;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
||||||
|
if (!mempath)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
|
||||||
|
mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
||||||
|
mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
||||||
|
mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
||||||
|
mempath[0].start_address = addr;
|
||||||
|
mempath[0].end_address = addr + size;
|
||||||
|
|
||||||
|
mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
|
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
mempath[1].header.length = sizeof (grub_efi_device_path_t);
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = b->load_image (0, grub_efi_image_handle,
|
||||||
|
(grub_efi_device_path_t *) mempath,
|
||||||
|
(void *) addr, size, &image_handle);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||||
|
|
||||||
|
/* Convert command line to UCS-2 */
|
||||||
|
loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||||
|
loaded_image->load_options_size = len =
|
||||||
|
(grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
|
||||||
|
loaded_image->load_options =
|
||||||
|
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||||
|
if (!loaded_image->load_options)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
loaded_image->load_options_size =
|
||||||
|
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||||
|
(grub_uint8_t *) args, len, NULL);
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "starting image %p\n", image_handle);
|
||||||
|
status = b->start_image (image_handle, 0, NULL);
|
||||||
|
|
||||||
|
/* When successful, not reached */
|
||||||
|
b->unload_image (image_handle);
|
||||||
|
grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
|
||||||
|
GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ventoy_debug_pause(void)
|
||||||
|
{
|
||||||
|
char key;
|
||||||
|
|
||||||
|
if (0 == ventoy_debug)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_printf("press Enter to continue ......\n");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
key = grub_getkey();
|
||||||
|
if (key == '\n' || key == '\r')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_preboot(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *file;
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called);
|
||||||
|
ventoy_debug_pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_linux_argc == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_initrd_called)
|
||||||
|
{
|
||||||
|
ventoy_initrd_called = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size"));
|
||||||
|
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
|
||||||
|
|
||||||
|
file = grub_env_get("vtoy_img_part_file");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
grub_printf("========== initrd list ==========\n");
|
||||||
|
for (i = 0; i < ventoy_extra_initrd_num; i++)
|
||||||
|
{
|
||||||
|
grub_printf("%s\n", ventoy_extra_initrd_list[i]);
|
||||||
|
}
|
||||||
|
grub_printf("=================================\n");
|
||||||
|
|
||||||
|
ventoy_debug_pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_boot_opt_filter(char *opt)
|
||||||
|
{
|
||||||
|
if (grub_strcmp(opt, "noinitrd") == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strcmp(opt, "vga=current") == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(opt, "rdinit=", 7) == 0)
|
||||||
|
{
|
||||||
|
if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0)
|
||||||
|
{
|
||||||
|
opt[0] = 'v';
|
||||||
|
opt[1] = 't';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(opt, "init=", 5) == 0)
|
||||||
|
{
|
||||||
|
opt[0] = 'v';
|
||||||
|
opt[1] = 't';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(opt, "dm=", 3) == 0)
|
||||||
|
{
|
||||||
|
opt[0] = 'D';
|
||||||
|
opt[1] = 'M';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
if (grub_strcmp(opt, "quiet") == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(opt, "loglevel=", 9) == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strcmp(opt, "splash") == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_bootopt_hook(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int TmpIdx;
|
||||||
|
int count = 0;
|
||||||
|
const char *env;
|
||||||
|
char c;
|
||||||
|
char *newenv;
|
||||||
|
char *last, *pos;
|
||||||
|
|
||||||
|
//grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc);
|
||||||
|
|
||||||
|
if (ventoy_linux_argc == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To avoid --- parameter, we split two parts */
|
||||||
|
for (TmpIdx = 0; TmpIdx < argc; TmpIdx++)
|
||||||
|
{
|
||||||
|
if (ventoy_boot_opt_filter(argv[TmpIdx]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(argv[TmpIdx], "--", 2) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ventoy_linux_argc; i++)
|
||||||
|
{
|
||||||
|
ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)];
|
||||||
|
ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL;
|
||||||
|
|
||||||
|
if (ventoy_linux_args[count][0] == '@')
|
||||||
|
{
|
||||||
|
env = grub_env_get(ventoy_linux_args[count] + 1);
|
||||||
|
if (env)
|
||||||
|
{
|
||||||
|
grub_free(ventoy_linux_args[count]);
|
||||||
|
|
||||||
|
newenv = grub_strdup(env);
|
||||||
|
last = newenv;
|
||||||
|
|
||||||
|
while (*last)
|
||||||
|
{
|
||||||
|
while (*last)
|
||||||
|
{
|
||||||
|
if (*last != ' ' && *last != '\t')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*last == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pos = last; *pos; pos++)
|
||||||
|
{
|
||||||
|
if (*pos == ' ' || *pos == '\t')
|
||||||
|
{
|
||||||
|
c = *pos;
|
||||||
|
*pos = 0;
|
||||||
|
if (0 == ventoy_boot_opt_filter(last))
|
||||||
|
{
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(last);
|
||||||
|
}
|
||||||
|
*pos = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pos == 0)
|
||||||
|
{
|
||||||
|
if (0 == ventoy_boot_opt_filter(last))
|
||||||
|
{
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(last);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = pos + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (TmpIdx < argc)
|
||||||
|
{
|
||||||
|
if (ventoy_boot_opt_filter(argv[TmpIdx]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]);
|
||||||
|
TmpIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
ventoy_linux_args[count++] = grub_strdup("loglevel=7");
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_linux_argc = count;
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
grub_printf("========== bootoption ==========\n");
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
grub_printf("%s ", ventoy_linux_args[i]);
|
||||||
|
}
|
||||||
|
grub_printf("\n================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *vtdebug;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
|
||||||
|
ventoy_linux_argc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtdebug = grub_env_get("vtdebug_flag");
|
||||||
|
if (vtdebug && vtdebug[0])
|
||||||
|
{
|
||||||
|
ventoy_debug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
for (i = 0; i < LINUX_MAX_ARGC; i++)
|
||||||
|
{
|
||||||
|
if (ventoy_linux_args[i])
|
||||||
|
{
|
||||||
|
grub_free(ventoy_linux_args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_debug = 0;
|
||||||
|
ventoy_linux_argc = 0;
|
||||||
|
ventoy_initrd_called = 0;
|
||||||
|
grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int newclen = 0;
|
||||||
|
char *pos = NULL;
|
||||||
|
char *end = NULL;
|
||||||
|
char buf[256] = {0};
|
||||||
|
|
||||||
|
if (argc != 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pos = argv[0]; *pos; pos++)
|
||||||
|
{
|
||||||
|
if (*pos == '/')
|
||||||
|
{
|
||||||
|
end = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
/* grub2 newc bug workaround */
|
||||||
|
newclen = (int)grub_strlen(end + 1);
|
||||||
|
if ((110 + newclen) % 4 == 0)
|
||||||
|
{
|
||||||
|
grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_extra_initrd_num < 256)
|
||||||
|
{
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
for (i = 0; i < ventoy_extra_initrd_num; i++)
|
||||||
|
{
|
||||||
|
if (ventoy_extra_initrd_list[i])
|
||||||
|
{
|
||||||
|
grub_free(ventoy_extra_initrd_list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_boot (void)
|
||||||
|
{
|
||||||
|
ventoy_preboot();
|
||||||
|
|
||||||
|
if (finalize_params_linux () != GRUB_ERR_NONE)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
|
||||||
|
kernel_size, linux_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_unload (void)
|
||||||
|
{
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
loaded = 0;
|
||||||
|
if (initrd_start)
|
||||||
|
grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
|
||||||
|
GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
|
||||||
|
initrd_start = initrd_end = 0;
|
||||||
|
grub_free (linux_args);
|
||||||
|
if (kernel_addr)
|
||||||
|
grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||||
|
GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||||
|
grub_fdt_unload ();
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As per linux/Documentation/arm/Booting
|
||||||
|
* ARM initrd needs to be covered by kernel linear mapping,
|
||||||
|
* so place it in the first 512MB of DRAM.
|
||||||
|
*
|
||||||
|
* As per linux/Documentation/arm64/booting.txt
|
||||||
|
* ARM64 initrd needs to be contained entirely within a 1GB aligned window
|
||||||
|
* of up to 32GB of size that covers the kernel image as well.
|
||||||
|
* Since the EFI stub loader will attempt to load the kernel near start of
|
||||||
|
* RAM, place the buffer in the first 32GB of RAM.
|
||||||
|
*/
|
||||||
|
#ifdef __arm__
|
||||||
|
#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
|
||||||
|
#else /* __aarch64__ */
|
||||||
|
#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function returns a pointer to a legally allocated initrd buffer,
|
||||||
|
* or NULL if unsuccessful
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
allocate_initrd_mem (int initrd_pages)
|
||||||
|
{
|
||||||
|
grub_addr_t max_addr;
|
||||||
|
|
||||||
|
if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
||||||
|
|
||||||
|
return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||||
|
GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||||
|
GRUB_EFI_LOADER_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
||||||
|
int initrd_size, initrd_pages;
|
||||||
|
void *initrd_mem = NULL;
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loaded)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("you need to load the kernel first"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
initrd_size = grub_get_initrd_size (&initrd_ctx);
|
||||||
|
grub_dprintf ("linux", "Loading initrd\n");
|
||||||
|
|
||||||
|
initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
|
||||||
|
initrd_mem = allocate_initrd_mem (initrd_pages);
|
||||||
|
|
||||||
|
if (!initrd_mem)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
initrd_start = (grub_addr_t) initrd_mem;
|
||||||
|
initrd_end = initrd_start + initrd_size;
|
||||||
|
grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
|
||||||
|
(void *) initrd_start, initrd_size);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_initrd_close (&initrd_ctx);
|
||||||
|
if (initrd_mem && !initrd_start)
|
||||||
|
grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
grub_file_t file = 0;
|
||||||
|
struct linux_arch_kernel_header lh;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
|
||||||
|
if (!file)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
kernel_size = grub_file_size (file);
|
||||||
|
|
||||||
|
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_loader_unset();
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
|
||||||
|
kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||||
|
grub_dprintf ("linux", "kernel numpages: %lld\n",
|
||||||
|
(long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||||
|
if (!kernel_addr)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_file_seek (file, 0);
|
||||||
|
if (grub_file_read (file, kernel_addr, kernel_size)
|
||||||
|
< (grub_int64_t) kernel_size)
|
||||||
|
{
|
||||||
|
if (!grub_errno)
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||||
|
|
||||||
|
cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
||||||
|
linux_args = grub_malloc (cmdline_size);
|
||||||
|
if (!linux_args)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||||
|
|
||||||
|
if (ventoy_linux_argc)
|
||||||
|
{
|
||||||
|
ventoy_bootopt_hook(argc, argv);
|
||||||
|
err = grub_create_loader_cmdline (ventoy_linux_argc, ventoy_linux_args,
|
||||||
|
linux_args + sizeof (LINUX_IMAGE) - 1,
|
||||||
|
cmdline_size,
|
||||||
|
GRUB_VERIFY_KERNEL_CMDLINE); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = grub_create_loader_cmdline (argc, argv,
|
||||||
|
linux_args + sizeof (LINUX_IMAGE) - 1,
|
||||||
|
cmdline_size,
|
||||||
|
GRUB_VERIFY_KERNEL_CMDLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
|
||||||
|
loaded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
loaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linux_args && !loaded)
|
||||||
|
grub_free (linux_args);
|
||||||
|
|
||||||
|
if (kernel_addr && !loaded)
|
||||||
|
grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||||
|
GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *file;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc);
|
||||||
|
|
||||||
|
if (ventoy_linux_argc == 0)
|
||||||
|
{
|
||||||
|
return grub_cmd_initrd(cmd, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size"));
|
||||||
|
|
||||||
|
if (ventoy_debug) grub_printf("membuf=%s\n", buf);
|
||||||
|
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
|
||||||
|
|
||||||
|
file = grub_env_get("vtoy_img_part_file");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_initrd_called = 1;
|
||||||
|
|
||||||
|
if (ventoy_debug)
|
||||||
|
{
|
||||||
|
grub_printf("========== initrd list ==========\n");
|
||||||
|
for (i = 0; i < ventoy_extra_initrd_num; i++)
|
||||||
|
{
|
||||||
|
grub_printf("%s\n", ventoy_extra_initrd_list[i]);
|
||||||
|
}
|
||||||
|
grub_printf("=================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi;
|
||||||
|
static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset;
|
||||||
|
|
||||||
|
|
||||||
|
GRUB_MOD_INIT (linux)
|
||||||
|
{
|
||||||
|
cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||||
|
N_("Load Linux."));
|
||||||
|
cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, 0,
|
||||||
|
N_("Load initrd."));
|
||||||
|
|
||||||
|
cmd_linuxefi = grub_register_command ("linuxefi", grub_cmd_linux,
|
||||||
|
0, N_("Load Linux."));
|
||||||
|
cmd_initrdefi = grub_register_command ("initrdefi", ventoy_cmd_initrd,
|
||||||
|
0, N_("Load initrd."));
|
||||||
|
|
||||||
|
cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt"));
|
||||||
|
cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt"));
|
||||||
|
|
||||||
|
cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_(""));
|
||||||
|
cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_(""));
|
||||||
|
|
||||||
|
ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC);
|
||||||
|
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI (linux)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd_linux);
|
||||||
|
grub_unregister_command (cmd_initrd);
|
||||||
|
}
|
||||||
@@ -229,10 +229,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
|||||||
if (! file)
|
if (! file)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Get the root device's device path. */
|
dev = file->device;
|
||||||
dev = grub_device_open (0);
|
|
||||||
if (! dev)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (dev->disk)
|
if (dev->disk)
|
||||||
dev_handle = grub_efidisk_get_device_handle (dev->disk);
|
dev_handle = grub_efidisk_get_device_handle (dev->disk);
|
||||||
@@ -257,15 +254,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
|||||||
if (dev_handle)
|
if (dev_handle)
|
||||||
dp = grub_efi_get_device_path (dev_handle);
|
dp = grub_efi_get_device_path (dev_handle);
|
||||||
|
|
||||||
if (! dp)
|
if (dp != NULL)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_path = make_file_path (dp, filename);
|
file_path = make_file_path (dp, filename);
|
||||||
if (! file_path)
|
if (! file_path)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
//grub_printf ("file path: ");
|
//grub_printf ("file path: ");
|
||||||
//grub_efi_print_device_path (file_path);
|
//grub_efi_print_device_path (file_path);
|
||||||
@@ -390,16 +384,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
|||||||
}
|
}
|
||||||
|
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
grub_device_close (dev);
|
|
||||||
|
|
||||||
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (dev)
|
|
||||||
grub_device_close (dev);
|
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ static int ventoy_linux_argc = 0;
|
|||||||
static char **ventoy_linux_args = NULL;
|
static char **ventoy_linux_args = NULL;
|
||||||
static int ventoy_extra_initrd_num = 0;
|
static int ventoy_extra_initrd_num = 0;
|
||||||
static char *ventoy_extra_initrd_list[256];
|
static char *ventoy_extra_initrd_list[256];
|
||||||
|
static grub_command_func_t ventoy_linux16_func = NULL;
|
||||||
|
static grub_command_func_t ventoy_initrd16_func = NULL;
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]);
|
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]);
|
||||||
|
|
||||||
@@ -507,6 +508,13 @@ static int ventoy_boot_opt_filter(char *opt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(opt, "dm=", 3) == 0)
|
||||||
|
{
|
||||||
|
opt[0] = 'D';
|
||||||
|
opt[1] = 'M';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ventoy_debug)
|
if (ventoy_debug)
|
||||||
{
|
{
|
||||||
if (grub_strcmp(opt, "quiet") == 0)
|
if (grub_strcmp(opt, "quiet") == 0)
|
||||||
@@ -531,6 +539,7 @@ static int ventoy_boot_opt_filter(char *opt)
|
|||||||
static int ventoy_bootopt_hook(int argc, char *argv[])
|
static int ventoy_bootopt_hook(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int TmpIdx;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const char *env;
|
const char *env;
|
||||||
char c;
|
char c;
|
||||||
@@ -544,14 +553,20 @@ static int ventoy_bootopt_hook(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
/* To avoid --- parameter, we split two parts */
|
||||||
|
for (TmpIdx = 0; TmpIdx < argc; TmpIdx++)
|
||||||
{
|
{
|
||||||
if (ventoy_boot_opt_filter(argv[i]))
|
if (ventoy_boot_opt_filter(argv[TmpIdx]))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ventoy_linux_args[count++] = grub_strdup(argv[i]);
|
if (grub_strncmp(argv[TmpIdx], "--", 2) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ventoy_linux_argc; i++)
|
for (i = 0; i < ventoy_linux_argc; i++)
|
||||||
@@ -623,6 +638,17 @@ static int ventoy_bootopt_hook(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (TmpIdx < argc)
|
||||||
|
{
|
||||||
|
if (ventoy_boot_opt_filter(argv[TmpIdx]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]);
|
||||||
|
TmpIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
if (ventoy_debug)
|
if (ventoy_debug)
|
||||||
{
|
{
|
||||||
ventoy_linux_args[count++] = grub_strdup("loglevel=7");
|
ventoy_linux_args[count++] = grub_strdup("loglevel=7");
|
||||||
@@ -643,54 +669,6 @@ static int ventoy_bootopt_hook(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char *vtdebug;
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
{
|
|
||||||
ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
|
|
||||||
ventoy_linux_argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
vtdebug = grub_env_get("vtdebug_flag");
|
|
||||||
if (vtdebug && vtdebug[0])
|
|
||||||
{
|
|
||||||
ventoy_debug = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
|
|
||||||
for (i = 0; i < LINUX_MAX_ARGC; i++)
|
|
||||||
{
|
|
||||||
if (ventoy_linux_args[i])
|
|
||||||
{
|
|
||||||
grub_free(ventoy_linux_args[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ventoy_debug = 0;
|
|
||||||
ventoy_linux_argc = 0;
|
|
||||||
ventoy_initrd_called = 0;
|
|
||||||
grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@@ -1552,6 +1530,92 @@ ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||||||
return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
|
return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *vtdebug;
|
||||||
|
grub_command_t regcmd;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
|
||||||
|
ventoy_linux_argc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtdebug = grub_env_get("vtdebug_flag");
|
||||||
|
if (vtdebug && vtdebug[0])
|
||||||
|
{
|
||||||
|
ventoy_debug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
|
||||||
|
|
||||||
|
ventoy_linux16_func = ventoy_initrd16_func = NULL;
|
||||||
|
regcmd = grub_command_find("linux16");
|
||||||
|
if (regcmd)
|
||||||
|
{
|
||||||
|
ventoy_linux16_func = regcmd->func;
|
||||||
|
regcmd->func = grub_cmd_linux;
|
||||||
|
}
|
||||||
|
|
||||||
|
regcmd = grub_command_find("initrd16");
|
||||||
|
if (regcmd)
|
||||||
|
{
|
||||||
|
ventoy_initrd16_func = regcmd->func;
|
||||||
|
regcmd->func = ventoy_cmd_initrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
grub_command_t regcmd;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
for (i = 0; i < LINUX_MAX_ARGC; i++)
|
||||||
|
{
|
||||||
|
if (ventoy_linux_args[i])
|
||||||
|
{
|
||||||
|
grub_free(ventoy_linux_args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_debug = 0;
|
||||||
|
ventoy_linux_argc = 0;
|
||||||
|
ventoy_initrd_called = 0;
|
||||||
|
grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
|
||||||
|
|
||||||
|
if (ventoy_linux16_func)
|
||||||
|
{
|
||||||
|
regcmd = grub_command_find("linux16");
|
||||||
|
if (regcmd)
|
||||||
|
{
|
||||||
|
regcmd->func = ventoy_linux16_func;
|
||||||
|
}
|
||||||
|
ventoy_linux16_func = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ventoy_initrd16_func)
|
||||||
|
{
|
||||||
|
regcmd = grub_command_find("initrd16");
|
||||||
|
if (regcmd)
|
||||||
|
{
|
||||||
|
regcmd->func = ventoy_initrd16_func;
|
||||||
|
}
|
||||||
|
ventoy_initrd16_func = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi;
|
static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi;
|
||||||
static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset;
|
static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset;
|
||||||
|
|||||||
327
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c
Normal file
327
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/linux.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
|
||||||
|
struct newc_head
|
||||||
|
{
|
||||||
|
char magic[6];
|
||||||
|
char ino[8];
|
||||||
|
char mode[8];
|
||||||
|
char uid[8];
|
||||||
|
char gid[8];
|
||||||
|
char nlink[8];
|
||||||
|
char mtime[8];
|
||||||
|
char filesize[8];
|
||||||
|
char devmajor[8];
|
||||||
|
char devminor[8];
|
||||||
|
char rdevmajor[8];
|
||||||
|
char rdevminor[8];
|
||||||
|
char namesize[8];
|
||||||
|
char check[8];
|
||||||
|
} GRUB_PACKED;
|
||||||
|
|
||||||
|
struct grub_linux_initrd_component
|
||||||
|
{
|
||||||
|
grub_file_t file;
|
||||||
|
char *newc_name;
|
||||||
|
grub_off_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dir
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
struct dir *next;
|
||||||
|
struct dir *child;
|
||||||
|
};
|
||||||
|
|
||||||
|
static char
|
||||||
|
hex (grub_uint8_t val)
|
||||||
|
{
|
||||||
|
if (val < 10)
|
||||||
|
return '0' + val;
|
||||||
|
return 'a' + val - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_field (char *var, grub_uint32_t val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *ptr = var;
|
||||||
|
for (i = 28; i >= 0; i -= 4)
|
||||||
|
*ptr++ = hex((val >> i) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_uint8_t *
|
||||||
|
make_header (grub_uint8_t *ptr,
|
||||||
|
const char *name, grub_size_t len,
|
||||||
|
grub_uint32_t mode,
|
||||||
|
grub_off_t fsize)
|
||||||
|
{
|
||||||
|
struct newc_head *head = (struct newc_head *) ptr;
|
||||||
|
grub_uint8_t *optr;
|
||||||
|
grub_size_t oh = 0;
|
||||||
|
grub_memcpy (head->magic, "070701", 6);
|
||||||
|
set_field (head->ino, 0);
|
||||||
|
set_field (head->mode, mode);
|
||||||
|
set_field (head->uid, 0);
|
||||||
|
set_field (head->gid, 0);
|
||||||
|
set_field (head->nlink, 1);
|
||||||
|
set_field (head->mtime, 0);
|
||||||
|
set_field (head->filesize, fsize);
|
||||||
|
set_field (head->devmajor, 0);
|
||||||
|
set_field (head->devminor, 0);
|
||||||
|
set_field (head->rdevmajor, 0);
|
||||||
|
set_field (head->rdevminor, 0);
|
||||||
|
set_field (head->namesize, len);
|
||||||
|
set_field (head->check, 0);
|
||||||
|
optr = ptr;
|
||||||
|
ptr += sizeof (struct newc_head);
|
||||||
|
grub_memcpy (ptr, name, len);
|
||||||
|
ptr += len;
|
||||||
|
oh = ALIGN_UP_OVERHEAD (ptr - optr, 4);
|
||||||
|
grub_memset (ptr, 0, oh);
|
||||||
|
ptr += oh;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_dir (struct dir *root)
|
||||||
|
{
|
||||||
|
if (!root)
|
||||||
|
return;
|
||||||
|
free_dir (root->next);
|
||||||
|
free_dir (root->child);
|
||||||
|
grub_free (root->name);
|
||||||
|
grub_free (root);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_size_t
|
||||||
|
insert_dir (const char *name, struct dir **root,
|
||||||
|
grub_uint8_t *ptr)
|
||||||
|
{
|
||||||
|
struct dir *cur, **head = root;
|
||||||
|
const char *cb, *ce = name;
|
||||||
|
grub_size_t size = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
for (cb = ce; *cb == '/'; cb++);
|
||||||
|
for (ce = cb; *ce && *ce != '/'; ce++);
|
||||||
|
if (!*ce)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (cur = *root; cur; cur = cur->next)
|
||||||
|
if (grub_memcmp (cur->name, cb, ce - cb)
|
||||||
|
&& cur->name[ce - cb] == 0)
|
||||||
|
break;
|
||||||
|
if (!cur)
|
||||||
|
{
|
||||||
|
struct dir *n;
|
||||||
|
n = grub_zalloc (sizeof (*n));
|
||||||
|
if (!n)
|
||||||
|
return 0;
|
||||||
|
n->next = *head;
|
||||||
|
n->name = grub_strndup (cb, ce - cb);
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Create the substring with the trailing NUL byte
|
||||||
|
* to be included in the cpio header.
|
||||||
|
*/
|
||||||
|
char *tmp_name = grub_strndup (name, ce - name);
|
||||||
|
if (!tmp_name) {
|
||||||
|
grub_free (n->name);
|
||||||
|
grub_free (n);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce);
|
||||||
|
ptr = make_header (ptr, tmp_name, ce - name + 1,
|
||||||
|
040777, 0);
|
||||||
|
grub_free (tmp_name);
|
||||||
|
}
|
||||||
|
size += ALIGN_UP ((ce - (char *) name + 1)
|
||||||
|
+ sizeof (struct newc_head), 4);
|
||||||
|
*head = n;
|
||||||
|
cur = n;
|
||||||
|
}
|
||||||
|
root = &cur->next;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_initrd_init (int argc, char *argv[],
|
||||||
|
struct grub_linux_initrd_context *initrd_ctx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int newc = 0;
|
||||||
|
struct dir *root = 0;
|
||||||
|
|
||||||
|
initrd_ctx->nfiles = 0;
|
||||||
|
initrd_ctx->components = 0;
|
||||||
|
|
||||||
|
initrd_ctx->components = grub_zalloc (argc
|
||||||
|
* sizeof (initrd_ctx->components[0]));
|
||||||
|
if (!initrd_ctx->components)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
initrd_ctx->size = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
const char *fname = argv[i];
|
||||||
|
|
||||||
|
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||||
|
|
||||||
|
if (grub_memcmp (argv[i], "newc:", 5) == 0)
|
||||||
|
{
|
||||||
|
const char *ptr, *eptr;
|
||||||
|
ptr = argv[i] + 5;
|
||||||
|
while (*ptr == '/')
|
||||||
|
ptr++;
|
||||||
|
eptr = grub_strchr (ptr, ':');
|
||||||
|
if (eptr)
|
||||||
|
{
|
||||||
|
initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
|
||||||
|
if (!initrd_ctx->components[i].newc_name)
|
||||||
|
{
|
||||||
|
grub_initrd_close (initrd_ctx);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
initrd_ctx->size
|
||||||
|
+= ALIGN_UP (sizeof (struct newc_head)
|
||||||
|
+ grub_strlen (initrd_ctx->components[i].newc_name) + 1,
|
||||||
|
4);
|
||||||
|
initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
|
||||||
|
&root, 0);
|
||||||
|
newc = 1;
|
||||||
|
fname = eptr + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (newc)
|
||||||
|
{
|
||||||
|
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
||||||
|
+ sizeof ("TRAILER!!!"), 4);
|
||||||
|
free_dir (root);
|
||||||
|
root = 0;
|
||||||
|
newc = 0;
|
||||||
|
}
|
||||||
|
initrd_ctx->components[i].file = grub_file_open (fname,
|
||||||
|
GRUB_FILE_TYPE_LINUX_INITRD
|
||||||
|
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||||
|
if (!initrd_ctx->components[i].file)
|
||||||
|
{
|
||||||
|
grub_initrd_close (initrd_ctx);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
initrd_ctx->nfiles++;
|
||||||
|
initrd_ctx->components[i].size
|
||||||
|
= grub_file_size (initrd_ctx->components[i].file);
|
||||||
|
initrd_ctx->size += initrd_ctx->components[i].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newc)
|
||||||
|
{
|
||||||
|
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||||
|
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
||||||
|
+ sizeof ("TRAILER!!!"), 4);
|
||||||
|
free_dir (root);
|
||||||
|
root = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_size_t
|
||||||
|
grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx)
|
||||||
|
{
|
||||||
|
return initrd_ctx->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (!initrd_ctx->components)
|
||||||
|
return;
|
||||||
|
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||||
|
{
|
||||||
|
grub_free (initrd_ctx->components[i].newc_name);
|
||||||
|
grub_file_close (initrd_ctx->components[i].file);
|
||||||
|
}
|
||||||
|
grub_free (initrd_ctx->components);
|
||||||
|
initrd_ctx->components = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int ventoy_need_prompt_load_file(void);
|
||||||
|
extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size);
|
||||||
|
grub_err_t
|
||||||
|
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||||
|
char *argv[], void *target)
|
||||||
|
{
|
||||||
|
grub_uint8_t *ptr = target;
|
||||||
|
int i;
|
||||||
|
int newc = 0;
|
||||||
|
struct dir *root = 0;
|
||||||
|
grub_ssize_t cursize = 0;
|
||||||
|
grub_ssize_t readsize = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||||
|
{
|
||||||
|
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||||
|
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||||
|
|
||||||
|
if (initrd_ctx->components[i].newc_name)
|
||||||
|
{
|
||||||
|
ptr += insert_dir (initrd_ctx->components[i].newc_name,
|
||||||
|
&root, ptr);
|
||||||
|
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
|
||||||
|
grub_strlen (initrd_ctx->components[i].newc_name) + 1,
|
||||||
|
0100777,
|
||||||
|
initrd_ctx->components[i].size);
|
||||||
|
newc = 1;
|
||||||
|
}
|
||||||
|
else if (newc)
|
||||||
|
{
|
||||||
|
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"),
|
||||||
|
0, 0);
|
||||||
|
free_dir (root);
|
||||||
|
root = 0;
|
||||||
|
newc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursize = initrd_ctx->components[i].size;
|
||||||
|
if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name &&
|
||||||
|
grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0)
|
||||||
|
{
|
||||||
|
readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readsize != cursize)
|
||||||
|
{
|
||||||
|
if (!grub_errno)
|
||||||
|
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||||
|
argv[i]);
|
||||||
|
grub_initrd_close (initrd_ctx);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
ptr += cursize;
|
||||||
|
}
|
||||||
|
if (newc)
|
||||||
|
{
|
||||||
|
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||||
|
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||||
|
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0);
|
||||||
|
}
|
||||||
|
free_dir (root);
|
||||||
|
root = 0;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
1041
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c
Normal file
1041
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c
Normal file
File diff suppressed because it is too large
Load Diff
1352
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/charset.c
Normal file
1352
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/charset.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user