Compare commits
967 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8a6e0e710 | ||
|
|
cf2daa9807 | ||
|
|
167d909e13 | ||
|
|
b4ebd305bd | ||
|
|
f4bbb7c5bb | ||
|
|
390f5b11db | ||
|
|
8bc3393d55 | ||
|
|
81f436703a | ||
|
|
cee2d7d263 | ||
|
|
ab508a9eb5 | ||
|
|
16a73afe9d | ||
|
|
c4cc0b779a | ||
|
|
1844d5291a | ||
|
|
601547d9db | ||
|
|
2ec8f3654c | ||
|
|
a68b5d446e | ||
|
|
3ccb91be9f | ||
|
|
47020c7e56 | ||
|
|
3e010b781a | ||
|
|
dcd86a4272 | ||
|
|
c287e33aab | ||
|
|
95c1eb6897 | ||
|
|
fb183e437e | ||
|
|
efca3aaf6d | ||
|
|
7e5242349c | ||
|
|
46ec4215d7 | ||
|
|
cd40c45fa4 | ||
|
|
f44a142d01 | ||
|
|
62e4b267de | ||
|
|
b036a2aef2 | ||
|
|
a2c196f453 | ||
|
|
afb22a6321 | ||
|
|
5e21346aba | ||
|
|
fb938806a2 | ||
|
|
1bde43ca66 | ||
|
|
d890c54a1b | ||
|
|
d876d274d4 | ||
|
|
7f6b276a59 | ||
|
|
24d9ed7bb3 | ||
|
|
23ba1abd70 | ||
|
|
1d04d3f59f | ||
|
|
78f5455b69 | ||
|
|
81d72a0800 | ||
|
|
73ec652bd0 | ||
|
|
d53d454828 | ||
|
|
bbc9904b3e | ||
|
|
2bc754c9a1 | ||
|
|
f50bb9cc46 | ||
|
|
8de9970341 | ||
|
|
1245ca4f4a | ||
|
|
10a5a18abb | ||
|
|
51eea40ea7 | ||
|
|
2b13648cc4 | ||
|
|
6b315e08ad | ||
|
|
fe642ebec2 | ||
|
|
bc43cdaeb7 | ||
|
|
0966a2b783 | ||
|
|
4c5bfbe695 | ||
|
|
623271fc6c | ||
|
|
3df2339e63 | ||
|
|
323c266812 | ||
|
|
a5055dbaf4 | ||
|
|
d9c71d453a | ||
|
|
474b8bbe03 | ||
|
|
c45d52459d | ||
|
|
1ec1f7ffb9 | ||
|
|
3777d2c952 | ||
|
|
bd868c6142 | ||
|
|
62bf4259b9 | ||
|
|
bcc7a7f6c1 | ||
|
|
8f6a18f6dd | ||
|
|
d48a970cd8 | ||
|
|
39f119c123 | ||
|
|
cc429e4ea5 | ||
|
|
7da081d887 | ||
|
|
73e9eae212 | ||
|
|
e72a8586cf | ||
|
|
d9650981f7 | ||
|
|
4cced72bbb | ||
|
|
bbc7e9046d | ||
|
|
e512310055 | ||
|
|
d44f741887 | ||
|
|
f6e88b135b | ||
|
|
8e2794c1bf | ||
|
|
843fa0aa30 | ||
|
|
99bb6937eb | ||
|
|
7a5932fea5 | ||
|
|
ccfbd4c15c | ||
|
|
e7994e5cd2 | ||
|
|
3295073c99 | ||
|
|
b6c0b24b70 | ||
|
|
998bdceba7 | ||
|
|
ae0f6a30fe | ||
|
|
465b147960 | ||
|
|
a4da6be93b | ||
|
|
d6a5443593 | ||
|
|
4ba2e6baa6 | ||
|
|
962645bb9e | ||
|
|
6dfce5cc1b | ||
|
|
39b95a840a | ||
|
|
e3b850ecb0 | ||
|
|
fb9d67881d | ||
|
|
bf8d488eb9 | ||
|
|
877feba5cb | ||
|
|
bb8c74e9ac | ||
|
|
25dc3115b6 | ||
|
|
3cdc3c874c | ||
|
|
bce7d47e4a | ||
|
|
1d13466f83 | ||
|
|
ddd7e2ccef | ||
|
|
5b40850fe0 | ||
|
|
8810cd128d | ||
|
|
1c0f3a4c06 | ||
|
|
2594a8a599 | ||
|
|
138d683318 | ||
|
|
3f916ce79e | ||
|
|
96e0679adb | ||
|
|
293f266842 | ||
|
|
7ea1888c93 | ||
|
|
905131ae8e | ||
|
|
4d47d4dfb3 | ||
|
|
0f64c0ed80 | ||
|
|
56d9c038a4 | ||
|
|
91babd9162 | ||
|
|
a03f4fcada | ||
|
|
326c92acc5 | ||
|
|
4ddaaf7584 | ||
|
|
5c45588bf8 | ||
|
|
9e482783f0 | ||
|
|
290ef7e65a | ||
|
|
1830fa3220 | ||
|
|
fd7c7508b0 | ||
|
|
57a8b7ccb5 | ||
|
|
1fadffe0c7 | ||
|
|
678cc34e09 | ||
|
|
db5776871e | ||
|
|
f0d61394a0 | ||
|
|
2ab92748a1 | ||
|
|
65d18c8792 | ||
|
|
4250b5341b | ||
|
|
e03df2dbab | ||
|
|
064c9fe84b | ||
|
|
8dcf836a69 | ||
|
|
dc80125b75 | ||
|
|
120e70c3b0 | ||
|
|
dba67f8d42 | ||
|
|
a5aaa8bf6e | ||
|
|
7bc8857fb0 | ||
|
|
103c99d291 | ||
|
|
d285ed08d0 | ||
|
|
f14b7e3308 | ||
|
|
043401f478 | ||
|
|
440b84be18 | ||
|
|
8fac73a1d7 | ||
|
|
44316e5083 | ||
|
|
cb3611b88a | ||
|
|
07112560e4 | ||
|
|
ff4298c305 | ||
|
|
1462a53e6a | ||
|
|
94c1c901c2 | ||
|
|
2fbfef5178 | ||
|
|
c72a0fd713 | ||
|
|
d92244ff77 | ||
|
|
0c7a1a3c75 | ||
|
|
132245fe80 | ||
|
|
2395316403 | ||
|
|
6327553181 | ||
|
|
ab9c19968b | ||
|
|
9448e3f298 | ||
|
|
8a1ea9bd53 | ||
|
|
dee1244b7d | ||
|
|
2b2ded937c | ||
|
|
1cec4f728f | ||
|
|
04990a0fb8 | ||
|
|
831538f7f9 | ||
|
|
3066ce8cac | ||
|
|
c701d2e0c6 | ||
|
|
f3f2a0bce5 | ||
|
|
efc4a116a2 | ||
|
|
c1bdea0e57 | ||
|
|
4c9b3d353c | ||
|
|
fd08eef485 | ||
|
|
508d5b2962 | ||
|
|
0b6a20fda0 | ||
|
|
7f666e643e | ||
|
|
eab68b37ee | ||
|
|
270ecd019e | ||
|
|
34c4adb14d | ||
|
|
90df8f1848 | ||
|
|
c1299a469d | ||
|
|
76730b1063 | ||
|
|
e42305bc48 | ||
|
|
62f01f4e1b | ||
|
|
d9b3367a8a | ||
|
|
b9860d0adf | ||
|
|
7285be06cb | ||
|
|
def8fa1799 | ||
|
|
41ac923127 | ||
|
|
100526b0b0 | ||
|
|
46f2e6d576 | ||
|
|
93c039b7c2 | ||
|
|
ee7200e189 | ||
|
|
b4ede7e2c4 | ||
|
|
d299f0b6b6 | ||
|
|
16c6e677c2 | ||
|
|
802b28587c | ||
|
|
786f6fc49b | ||
|
|
11cbf15da1 | ||
|
|
20d65f42e9 | ||
|
|
430f31edcc | ||
|
|
2729ea0f43 | ||
|
|
acdcd2c63c | ||
|
|
8ccf7d39fd | ||
|
|
3ef298098b | ||
|
|
9234501099 | ||
|
|
561482b14a | ||
|
|
686b894e91 | ||
|
|
9ee2b6cc23 | ||
|
|
63d3816464 | ||
|
|
7e595e828c | ||
|
|
748eed9e1f | ||
|
|
250e809fe2 | ||
|
|
812a5d95f1 | ||
|
|
73aa58b38b | ||
|
|
9d3293f91a | ||
|
|
51ffa84ffb | ||
|
|
f507020948 | ||
|
|
4343d7fd94 | ||
|
|
b436eed058 | ||
|
|
091f0aa722 | ||
|
|
5b917907ca | ||
|
|
36ecfa5ca2 | ||
|
|
f6a7c0729e | ||
|
|
3429d54d51 | ||
|
|
d9c9042099 | ||
|
|
54d5ba40dd | ||
|
|
028b30c24e | ||
|
|
29a5a54f7e | ||
|
|
97431a6a3b | ||
|
|
bd0e53bb7f | ||
|
|
74d88856f7 | ||
|
|
747b0fca36 | ||
|
|
261fbae2af | ||
|
|
949ab7fe2e | ||
|
|
3fba97c0c9 | ||
|
|
9842d5de61 | ||
|
|
84e63a1ac8 | ||
|
|
5f6b18a216 | ||
|
|
3911aab34b | ||
|
|
e461f25cf7 | ||
|
|
bf7c53bc4d | ||
|
|
98c5a6ed95 | ||
|
|
4193c5e867 | ||
|
|
53520f89fd | ||
|
|
3e659f4745 | ||
|
|
70c198c157 | ||
|
|
0faa83d778 | ||
|
|
b7cd95454a | ||
|
|
d3bf99a0b3 | ||
|
|
7f03145d85 | ||
|
|
dcc9dd73d1 | ||
|
|
52c499866c | ||
|
|
2b30628d4c | ||
|
|
5d1801cfcd | ||
|
|
65f5ebc371 | ||
|
|
f9911d15fc | ||
|
|
ca8e8eba0e | ||
|
|
5f6fe509b7 | ||
|
|
9fbf06d4eb | ||
|
|
a8e3728088 | ||
|
|
f6926e686c | ||
|
|
19a6d05786 | ||
|
|
4cf514f97d | ||
|
|
ac38020ce7 | ||
|
|
5d9022e916 | ||
|
|
eb48f87f3a | ||
|
|
45f5b80850 | ||
|
|
e9819fee80 | ||
|
|
8d3479a524 | ||
|
|
0526fc732a | ||
|
|
60f9bcf768 | ||
|
|
e339aad9e2 | ||
|
|
b953d57c54 | ||
|
|
fcddafcdf7 | ||
|
|
c5967c3646 | ||
|
|
d0e85c0202 | ||
|
|
a7cb8a4a5f | ||
|
|
874d14b948 | ||
|
|
87e9682a1e | ||
|
|
567dca7f8d | ||
|
|
3c38310164 | ||
|
|
0775acd417 | ||
|
|
7ca13eaf89 | ||
|
|
d0cbc386af | ||
|
|
d6e7da9af8 | ||
|
|
e085595bf6 | ||
|
|
a759b65cb5 | ||
|
|
bf2c728c6d | ||
|
|
bf792503b6 | ||
|
|
f530b22232 | ||
|
|
862b812a7d | ||
|
|
a0fb758acb | ||
|
|
4c81cfdedd | ||
|
|
8608b0695c | ||
|
|
7684075e86 | ||
|
|
863ca11c16 | ||
|
|
f77a3b851c | ||
|
|
9425e0773f | ||
|
|
8c8a282dc4 | ||
|
|
814fda8991 | ||
|
|
ac792bedba | ||
|
|
ff2b282a09 | ||
|
|
ffe51043d4 | ||
|
|
9e34bc70f3 | ||
|
|
9f2485ad00 | ||
|
|
d6609e191c | ||
|
|
7d7d719e2d | ||
|
|
0595c78aa2 | ||
|
|
1a81e2d204 | ||
|
|
9a15f8208d | ||
|
|
b612c541ab | ||
|
|
4542fd4ff9 | ||
|
|
82e403e69c | ||
|
|
5e7e62b9d5 | ||
|
|
b524a95ea6 | ||
|
|
cc5ecd61c5 | ||
|
|
23187955dc | ||
|
|
37bef42f65 | ||
|
|
0b337ad600 | ||
|
|
3a455c57ff | ||
|
|
f6abf4d9c0 | ||
|
|
ed37720151 | ||
|
|
271fb2e6e8 | ||
|
|
3d67eea1b2 | ||
|
|
96326a3272 | ||
|
|
ce386c049c | ||
|
|
0423c1611e | ||
|
|
d58d1f5b0c | ||
|
|
daec6b60fd | ||
|
|
18f42509ae | ||
|
|
1e1b41b1d9 | ||
|
|
38558d4452 | ||
|
|
646d7cef38 | ||
|
|
8949e723d3 | ||
|
|
5d05cdff10 | ||
|
|
8f4a9b698e | ||
|
|
5daa656d46 | ||
|
|
7d9f7817af | ||
|
|
934b9e8fba | ||
|
|
0c27c8d5a8 | ||
|
|
09148a05d3 | ||
|
|
0b229c3fe9 | ||
|
|
b46767e423 | ||
|
|
f568b62685 | ||
|
|
668c38f833 | ||
|
|
9c52d811ed | ||
|
|
84f33ed659 | ||
|
|
f8f8950799 | ||
|
|
b991c9d7f7 | ||
|
|
d053c824e2 | ||
|
|
91e895ac9f | ||
|
|
a8834e0c1c | ||
|
|
c0a28c3efe | ||
|
|
19e5d34378 | ||
|
|
f10ceade71 | ||
|
|
06f4e05de4 | ||
|
|
eb74f7bfed | ||
|
|
345fc9a106 | ||
|
|
9b99315c02 | ||
|
|
2bd5354f75 | ||
|
|
0f3c6c4092 | ||
|
|
2b4f06496e | ||
|
|
40cb99762c | ||
|
|
6124e562c5 | ||
|
|
149db87a0c | ||
|
|
6640aa1f52 | ||
|
|
8e0eebf817 | ||
|
|
4dd6a0b6bc | ||
|
|
b36aafd7e4 | ||
|
|
b30456aa91 | ||
|
|
bfae54a8b5 | ||
|
|
3d9c6043bf | ||
|
|
519026cf2d | ||
|
|
68a996c776 | ||
|
|
7eff59a8cf | ||
|
|
03f5ce953e | ||
|
|
14925c2cf5 | ||
|
|
41d9b805bf | ||
|
|
c7d29e79ba | ||
|
|
4f981aea94 | ||
|
|
8f5a1042a9 | ||
|
|
d2f4bcf7d7 | ||
|
|
e8b7e4ca28 | ||
|
|
72ac648ad2 | ||
|
|
26fba39441 | ||
|
|
e9dc78b35d | ||
|
|
77806ea713 | ||
|
|
bdf28ff2a8 | ||
|
|
cce41aa9d4 | ||
|
|
1cb8bf76f1 | ||
|
|
abac77944a | ||
|
|
2947e57497 | ||
|
|
23d56ece85 | ||
|
|
f0de26f9b0 | ||
|
|
fa1f8e8420 | ||
|
|
0fecccf852 | ||
|
|
5d35673184 | ||
|
|
63d2573f2c | ||
|
|
498da3d502 | ||
|
|
147acc3f57 | ||
|
|
1ddad28dea | ||
|
|
2bfced0ca8 | ||
|
|
b04c40c23c | ||
|
|
90065f509f | ||
|
|
cbb55ac160 | ||
|
|
b09f30f399 | ||
|
|
e07b053226 | ||
|
|
3d2874b2be | ||
|
|
8a9c7d44b7 | ||
|
|
45001d77c3 | ||
|
|
f4bc5be100 | ||
|
|
8c81d06b7c | ||
|
|
a8e0a80349 | ||
|
|
50ec2de0b6 | ||
|
|
374c165ee1 | ||
|
|
4f0f912de7 | ||
|
|
afcd73a659 | ||
|
|
f1ee8042dd | ||
|
|
88e4a250db | ||
|
|
145adabcaf | ||
|
|
d605e58e74 | ||
|
|
138148ddb4 | ||
|
|
0f83e1b786 | ||
|
|
14a2c97d84 | ||
|
|
ca78453816 | ||
|
|
7c9811229e | ||
|
|
0b7baa07de | ||
|
|
0b74f57dab | ||
|
|
6dc5823706 | ||
|
|
72bb5133e6 | ||
|
|
b0d370ee30 | ||
|
|
5e10296de9 | ||
|
|
ca1c372d43 | ||
|
|
4c64123cc2 | ||
|
|
3a29084e6e | ||
|
|
74e7294491 | ||
|
|
48c66303af | ||
|
|
7dddfe463c | ||
|
|
4162d718ae | ||
|
|
a9452afe2c | ||
|
|
2242c9d8d2 | ||
|
|
19528cb453 | ||
|
|
a20a00e420 | ||
|
|
94c1174771 | ||
|
|
987f499ad7 | ||
|
|
71ed24972a | ||
|
|
5c309ee4f0 | ||
|
|
9f6ec3e219 | ||
|
|
ed099257e7 | ||
|
|
bb89a21b17 | ||
|
|
f27324c152 | ||
|
|
a12d7726bb | ||
|
|
6180f1a933 | ||
|
|
73a72774cd | ||
|
|
1d582d8e0c | ||
|
|
e4307368f4 | ||
|
|
019fb71253 | ||
|
|
e883a0b43f | ||
|
|
c288e229fb | ||
|
|
248aafbd11 | ||
|
|
ae7318a883 | ||
|
|
89746196ee | ||
|
|
5aadfd792b | ||
|
|
68ca715f7a | ||
|
|
3a28bf0ee9 | ||
|
|
9574727c71 | ||
|
|
6dc044aec0 | ||
|
|
03bc810fa0 | ||
|
|
7015dbe2e1 | ||
|
|
afa15a1615 | ||
|
|
326c6d0985 | ||
|
|
542c5a1017 | ||
|
|
58a46bf753 | ||
|
|
c3592c3756 | ||
|
|
61dd7f0d7c | ||
|
|
935f77255f | ||
|
|
0855c5b218 | ||
|
|
0524f92c73 | ||
|
|
bd8e23f125 | ||
|
|
d513e63c59 | ||
|
|
2049102139 | ||
|
|
6faa0a6632 | ||
|
|
b58cfa5ae1 | ||
|
|
1ab6d16be3 | ||
|
|
544f14589f | ||
|
|
c2ce4b4677 | ||
|
|
9cbd12a7dc | ||
|
|
928fc825aa | ||
|
|
8de7f55b28 | ||
|
|
e523a66522 | ||
|
|
a5a55b6269 | ||
|
|
9193cd7c40 | ||
|
|
cd20c3bba0 | ||
|
|
9467bd1431 | ||
|
|
f385460425 | ||
|
|
91b26d3556 | ||
|
|
7fc268188f | ||
|
|
4978a1727d | ||
|
|
ce8148ab3e | ||
|
|
0171dcd9ee | ||
|
|
63d8125895 | ||
|
|
0529e65181 | ||
|
|
2f0f429dfa | ||
|
|
354f92dd91 | ||
|
|
04369acb50 | ||
|
|
2f49981d01 | ||
|
|
4695813e50 | ||
|
|
aa714f49c4 | ||
|
|
41dd869f0c | ||
|
|
1626103849 | ||
|
|
4d7512c53f | ||
|
|
fd0a9810f3 | ||
|
|
128c3e7ec2 | ||
|
|
045352d5f7 | ||
|
|
38f1318b8f | ||
|
|
bd75ecab30 | ||
|
|
48169de420 | ||
|
|
462bf9396c | ||
|
|
3957bfeb13 | ||
|
|
39764a5ccf | ||
|
|
de69d60290 | ||
|
|
0a2ddad16a | ||
|
|
5ba0d0d673 | ||
|
|
56d2fba4dd | ||
|
|
e8bd33d383 | ||
|
|
a87d70e3d8 | ||
|
|
d663e00df7 | ||
|
|
b3e5e16f5b | ||
|
|
8f991cec67 | ||
|
|
f422a83c08 | ||
|
|
82b787c223 | ||
|
|
5f301893ea | ||
|
|
536d18a946 | ||
|
|
e802789da8 | ||
|
|
ea9c7526d2 | ||
|
|
4ad6f52ed9 | ||
|
|
27d82d58cf | ||
|
|
91a94b2824 | ||
|
|
9bfe65de07 | ||
|
|
fd7a433d10 | ||
|
|
c799f465a9 | ||
|
|
8f0cab1764 | ||
|
|
bee4a5d24b | ||
|
|
baf76f4fc8 | ||
|
|
7c1118cf1b | ||
|
|
1cd953b82f | ||
|
|
bf5ed142bc | ||
|
|
575cc9e40f | ||
|
|
4d4a5fd980 | ||
|
|
db6e493a2d | ||
|
|
e186af796d | ||
|
|
f01316934f | ||
|
|
1469146291 | ||
|
|
8be8973f16 | ||
|
|
ccafa47ad7 | ||
|
|
356b470690 | ||
|
|
79a5e46306 | ||
|
|
fedd090fd4 | ||
|
|
834abaf73f | ||
|
|
1d0dae281b | ||
|
|
359d0ae806 | ||
|
|
6209273d10 | ||
|
|
17ac74309e | ||
|
|
306c7f8c41 | ||
|
|
9f3928ecfd | ||
|
|
4bbbebd3c9 | ||
|
|
351b75eceb | ||
|
|
c1aa1b23b2 | ||
|
|
491531f19c | ||
|
|
01dbfe92dc | ||
|
|
82066f3267 | ||
|
|
e1fa72058e | ||
|
|
52a409a846 | ||
|
|
8d8454ebd4 | ||
|
|
9980ac3f6c | ||
|
|
b76ee77ad0 | ||
|
|
cbb9df360e | ||
|
|
f936e463c9 | ||
|
|
c0fe877adc | ||
|
|
60c38fa781 | ||
|
|
50bee6f3c7 | ||
|
|
d97b820cd6 | ||
|
|
42d9d6be5f | ||
|
|
79391ac86c | ||
|
|
3f9e351132 | ||
|
|
4e31dda1de | ||
|
|
f519c386a1 | ||
|
|
9a14abbab6 | ||
|
|
875376902e | ||
|
|
a47bdc1ba7 | ||
|
|
948ca437c0 | ||
|
|
cab97f130f | ||
|
|
eb6336e49c | ||
|
|
878dc47783 | ||
|
|
67a4046d8f | ||
|
|
bb4dfec3fa | ||
|
|
e5a9516f73 | ||
|
|
e2fca9a2f3 | ||
|
|
233f7cc1d7 | ||
|
|
a326a3b733 | ||
|
|
4939ea332a | ||
|
|
bd9a33056f | ||
|
|
10ccbfb342 | ||
|
|
07a8376ffa | ||
|
|
401d46d923 | ||
|
|
b424d25fe1 | ||
|
|
b116610e48 | ||
|
|
1bd2c75265 | ||
|
|
bd2540d740 | ||
|
|
477a3d335b | ||
|
|
243dbac376 | ||
|
|
fd2d2ca939 | ||
|
|
8f0943fb82 | ||
|
|
edd58ac378 | ||
|
|
609248c519 | ||
|
|
35ade9f672 | ||
|
|
3480529b39 | ||
|
|
46f750bab2 | ||
|
|
a3bf814b26 | ||
|
|
2c5c8e4684 | ||
|
|
b1cecfc19c | ||
|
|
462ba91d4f | ||
|
|
ecf9bc8f74 | ||
|
|
5377eb0e72 | ||
|
|
2d8a1ba006 | ||
|
|
76be9c05fb | ||
|
|
2adcef7e40 | ||
|
|
6adb83f253 | ||
|
|
2c1bab8602 | ||
|
|
7f5ca9ac43 | ||
|
|
74939772bb | ||
|
|
b0405f5030 | ||
|
|
88ce78bbde | ||
|
|
e1f8c285a7 | ||
|
|
cedbc1393e | ||
|
|
b36b2880ba | ||
|
|
db0c69520e | ||
|
|
f2117fe5bb | ||
|
|
1aedb8eaae | ||
|
|
f4ee86857a | ||
|
|
8c21ad284d | ||
|
|
72e3f0ab63 | ||
|
|
7d8c17c09d | ||
|
|
f604c2ded5 | ||
|
|
2162990007 | ||
|
|
13db1340f2 | ||
|
|
3f14098ac3 | ||
|
|
89c895c868 | ||
|
|
15eea1e4e6 | ||
|
|
caa6007555 | ||
|
|
362ad1b8f7 | ||
|
|
25500dfbc5 | ||
|
|
b8e6648ea9 | ||
|
|
b4f45592e0 | ||
|
|
bd4737eb6a | ||
|
|
aa2ffbd249 | ||
|
|
62ff3b402e | ||
|
|
5b6d06a850 | ||
|
|
e07005de67 | ||
|
|
3453046c67 | ||
|
|
81152b4a79 | ||
|
|
023280fb64 | ||
|
|
0cf81cb232 | ||
|
|
c764bb7d3d | ||
|
|
f2c808891c | ||
|
|
cc0dc3ad8b | ||
|
|
ccbdf7e243 | ||
|
|
8adeb6cc30 | ||
|
|
a3fe5a7b41 | ||
|
|
32fe78d1ab | ||
|
|
b247348f3c | ||
|
|
330a555147 | ||
|
|
97bfea622a | ||
|
|
a050a3703c | ||
|
|
647b627dc0 | ||
|
|
a91fc93154 | ||
|
|
1591b1c681 | ||
|
|
9ecf811587 | ||
|
|
3e6a7c5070 | ||
|
|
5a0d6bb3f9 | ||
|
|
7afdc5a752 | ||
|
|
57af810bcc | ||
|
|
067c2d4f71 | ||
|
|
a666cffcfd | ||
|
|
fa106cca9a | ||
|
|
5b4e7079c4 | ||
|
|
de61794a07 | ||
|
|
da227b258d | ||
|
|
ba06df22ea | ||
|
|
f9b0d8c29d | ||
|
|
3d3509e023 | ||
|
|
464bee51e0 | ||
|
|
550a966b6b | ||
|
|
f81a84106c | ||
|
|
e507b66033 | ||
|
|
0eaeae5b20 | ||
|
|
18c7782477 | ||
|
|
50c34f4d20 | ||
|
|
811746c927 | ||
|
|
7c0305aa37 | ||
|
|
bbc667f3a6 | ||
|
|
292b319730 | ||
|
|
f999ad2821 | ||
|
|
430a2bd00c | ||
|
|
de12fa6282 | ||
|
|
03b85b2474 | ||
|
|
0ca5c7cdc1 | ||
|
|
3614986677 | ||
|
|
4dece9d9b0 | ||
|
|
686a5d225d | ||
|
|
43f536a3f9 | ||
|
|
e89d87086a | ||
|
|
d3843f2b31 | ||
|
|
1a1afb9abf | ||
|
|
02877c7793 | ||
|
|
684f23d72f | ||
|
|
f01a38f003 | ||
|
|
75e70c9fbb | ||
|
|
2751771b75 | ||
|
|
784bd4f181 | ||
|
|
acf242b3a9 | ||
|
|
0fe9e2a405 | ||
|
|
2921bee62c | ||
|
|
4613992098 | ||
|
|
7f0efa4b6d | ||
|
|
a8241128df | ||
|
|
db81cb490b | ||
|
|
ad1b0d2d1f | ||
|
|
286acb6821 | ||
|
|
3e826561ae | ||
|
|
95df71ad10 | ||
|
|
b9e478292a | ||
|
|
db85294724 | ||
|
|
055b37d2e3 | ||
|
|
76e248f02d | ||
|
|
b7bc607e0e | ||
|
|
9bf7e375ee | ||
|
|
cd762d8d0f | ||
|
|
f8cbc01cb9 | ||
|
|
0aa31b59ad | ||
|
|
71391e3b8d | ||
|
|
d340f3eeaf | ||
|
|
f086ec46ab | ||
|
|
8f32bb70df | ||
|
|
54f59c71f4 | ||
|
|
552dce6431 | ||
|
|
5c99aa2215 | ||
|
|
d745df0978 | ||
|
|
a2b34bd3cd | ||
|
|
113cd2c92e | ||
|
|
53caba0c78 | ||
|
|
e2c90b8481 | ||
|
|
dca32f571f | ||
|
|
0e39205b4f | ||
|
|
f4fae21a81 | ||
|
|
f1887e2fc8 | ||
|
|
b3c806bcd8 | ||
|
|
e51d914a54 | ||
|
|
1084cee1c5 | ||
|
|
e31cb6f5c2 | ||
|
|
6a11610cc8 | ||
|
|
ae5b44048b | ||
|
|
cda52a9037 | ||
|
|
3b01bb3f9d | ||
|
|
74aa8b93a5 | ||
|
|
ba36dc36a1 | ||
|
|
7db988dccc | ||
|
|
1e973001db | ||
|
|
4ad9eb98bf | ||
|
|
24a7deb0b9 | ||
|
|
ff53f97758 | ||
|
|
2ebf53c908 | ||
|
|
6d0295a1cf | ||
|
|
d344504a93 | ||
|
|
18a64e56e2 | ||
|
|
97737d4d61 | ||
|
|
20830376c4 | ||
|
|
25aa24cd6f | ||
|
|
6aad4217f4 | ||
|
|
dfec5ba547 | ||
|
|
b45a0415af | ||
|
|
5417b7d548 | ||
|
|
3512512e28 | ||
|
|
eca0296c36 | ||
|
|
12cc832a9d | ||
|
|
77cd61685e | ||
|
|
6eaff7eb36 | ||
|
|
219948858b | ||
|
|
aae3eaba2c | ||
|
|
9e6a45d579 | ||
|
|
a80655a76b | ||
|
|
fc45cc84cb | ||
|
|
51239adb22 | ||
|
|
0491b9e9c9 | ||
|
|
34c78ce3c3 | ||
|
|
374282b7b5 | ||
|
|
08c1100be5 | ||
|
|
21bbfb5ff2 | ||
|
|
7a7d2b2f22 | ||
|
|
f660cf6131 | ||
|
|
f5ebbf9704 | ||
|
|
808c081325 | ||
|
|
48bd9bd482 | ||
|
|
5c4b8a8bc5 | ||
|
|
b6b47184c1 | ||
|
|
b1338e33b6 | ||
|
|
371859f58d | ||
|
|
ea6e6fcb08 | ||
|
|
ab7b9f4bcf | ||
|
|
5bd85c8b75 | ||
|
|
73b63dd007 | ||
|
|
b25b88a9ae | ||
|
|
0de2efedfa | ||
|
|
15949d773f | ||
|
|
cdabe50e0c | ||
|
|
53f2568481 | ||
|
|
a191f1e2c1 | ||
|
|
3a55ac1e3a | ||
|
|
75d064cc3f | ||
|
|
5cde4b31e8 | ||
|
|
92bd4a0e97 | ||
|
|
9171f0fa24 | ||
|
|
92d687342a | ||
|
|
78320aae48 | ||
|
|
5f7a1c266e | ||
|
|
e34e609fcb | ||
|
|
8daeb9109d | ||
|
|
938dcd6d79 | ||
|
|
92f78fa136 | ||
|
|
4a994f12c7 | ||
|
|
16927d976c | ||
|
|
edb3d3b914 | ||
|
|
5ac955e180 | ||
|
|
db1fb53315 | ||
|
|
11e2d6963a | ||
|
|
8dde6a899a | ||
|
|
89ef80dfbe | ||
|
|
e7efdfe7af | ||
|
|
6dd8903f56 | ||
|
|
ed52265c7b | ||
|
|
ead8c64845 | ||
|
|
b42ac77a0a | ||
|
|
6201d138a7 | ||
|
|
1d5b9b96ba | ||
|
|
47d6ffbbd1 | ||
|
|
ecb7ff0a9e | ||
|
|
b987551571 | ||
|
|
18b9dd6344 | ||
|
|
e55c0be066 | ||
|
|
0886ba597d | ||
|
|
838621dc59 | ||
|
|
d51add1678 | ||
|
|
c2beb03142 | ||
|
|
2fc01c19df | ||
|
|
d50c968a95 | ||
|
|
185381aff6 | ||
|
|
93aaf3a7a0 | ||
|
|
b19060ca06 | ||
|
|
06d2fd2028 | ||
|
|
94a5d42b75 | ||
|
|
b5dedb25f7 | ||
|
|
5c3e6c0aec | ||
|
|
fb128a3670 | ||
|
|
09b774e747 | ||
|
|
d70893a39d | ||
|
|
da1cad5b1e | ||
|
|
50cab8772c | ||
|
|
9f4ffae0bc | ||
|
|
c775348c94 | ||
|
|
468214ec1c | ||
|
|
5af45debaa | ||
|
|
befc733604 | ||
|
|
a4180c932b | ||
|
|
68b50d0976 | ||
|
|
01dc990d1d | ||
|
|
612c57c398 | ||
|
|
ef2eca888b | ||
|
|
ecca04e370 | ||
|
|
1f08170527 | ||
|
|
7074702d90 | ||
|
|
e6e500a808 | ||
|
|
49e33844f3 | ||
|
|
1982fbe303 | ||
|
|
afabf12c4f | ||
|
|
d943b622f8 | ||
|
|
dfc2455a57 | ||
|
|
948531e59c | ||
|
|
cdefd4a21f | ||
|
|
961a4c305a | ||
|
|
8d8b7d9c71 | ||
|
|
5371a94ce1 | ||
|
|
3eab707174 | ||
|
|
9ebc67f6a4 | ||
|
|
d4afc257d5 | ||
|
|
7b7410bcc1 | ||
|
|
32d31a0b6a | ||
|
|
2bee3621b9 | ||
|
|
73386cd78f | ||
|
|
43cd830acd | ||
|
|
bf946f3fdd | ||
|
|
ecb0657a6c | ||
|
|
49ef96ad24 | ||
|
|
ec875616c0 | ||
|
|
e60572326e | ||
|
|
a28a1a80a2 | ||
|
|
e4b10cd719 | ||
|
|
0dfb6fcfa6 | ||
|
|
bc257b20f5 | ||
|
|
df566e5d17 | ||
|
|
c3e88061d1 | ||
|
|
67368b670f | ||
|
|
e02dc20084 | ||
|
|
7ac41b5e57 | ||
|
|
bd25dc6704 | ||
|
|
210a48cbfd | ||
|
|
fdec4b606d | ||
|
|
2b93eb8ff2 | ||
|
|
f7db7cfb27 | ||
|
|
cc9d6fa074 | ||
|
|
93341702cd | ||
|
|
a7703ff9e3 | ||
|
|
57691cc035 | ||
|
|
f16e8d7078 | ||
|
|
de18c41bf2 | ||
|
|
fae50da982 | ||
|
|
a982084f63 | ||
|
|
39174a0304 | ||
|
|
7bd80d8e47 | ||
|
|
0331738af9 | ||
|
|
3b93527d9b | ||
|
|
ab40ee4e8e | ||
|
|
e72d424103 | ||
|
|
7809449e8d | ||
|
|
78c8f6c0fd | ||
|
|
dd985dd069 | ||
|
|
e7b8c8f25a | ||
|
|
ecf2a4fa81 | ||
|
|
ac6c3f8503 | ||
|
|
13a03925cc | ||
|
|
7d64765ced | ||
|
|
504c4821a8 | ||
|
|
8ad6496cfa | ||
|
|
df739d364b | ||
|
|
a3c4b480e7 | ||
|
|
6711f2a202 | ||
|
|
9698a8757c | ||
|
|
828d1c2ad7 | ||
|
|
8cafe04730 | ||
|
|
ecd82e1c04 | ||
|
|
c39316ef5e | ||
|
|
31293a6fc8 | ||
|
|
38c2f24a87 | ||
|
|
ad7c736afc | ||
|
|
408959e974 | ||
|
|
b55ed1f888 | ||
|
|
f1c342df85 | ||
|
|
3dcc744dcd |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1,3 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: AuxXxilium
|
||||
buy_me_a_coffee: auxxxilium
|
||||
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a Bug Report
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the Bug**
|
||||
First read Wiki to find a Solution. If you can't find a Solution, provide a clear and concise description of what the bug is.
|
||||
|
||||
**Screenshots**
|
||||
Actual Screenshot from Systeminfo (Config Mode - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT
|
||||
|
||||
**Hardware**
|
||||
Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ...
|
||||
8
.github/ISSUE_TEMPLATE/custom_build.md
vendored
Normal file
8
.github/ISSUE_TEMPLATE/custom_build.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Custom Build
|
||||
about: Create a Customized Build
|
||||
title: ''
|
||||
labels: 'custom'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your Feature request related to a Problem? Please describe.**
|
||||
A clear and concise Description of what the Problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Additional Context**
|
||||
Add any other Context or Screenshots about the Feature request here.
|
||||
256
.github/workflows/autobuild.yml
vendored
Normal file
256
.github/workflows/autobuild.yml
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
#
|
||||
# Copyright (C) 2024 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
name: Build Arc Image Development
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
runs:
|
||||
description: "runs-on"
|
||||
type: choice
|
||||
options:
|
||||
- ubuntu-latest
|
||||
- self-hosted
|
||||
version:
|
||||
description: "version (1.0.0)"
|
||||
required: true
|
||||
type: string
|
||||
next:
|
||||
description: "next"
|
||||
default: true
|
||||
type: boolean
|
||||
stable:
|
||||
description: "stable"
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.runs }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@main
|
||||
|
||||
# Install Dependencies
|
||||
- name: Install Dependencies
|
||||
if: ${{ inputs.runs == 'ubuntu-latest' }}
|
||||
run: |
|
||||
git config --global user.email "info@auxxxilium.tech"
|
||||
git config --global user.name "AuxXxilium"
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y jq gawk cpio gettext libelf-dev qemu-utils busybox dialog curl sed
|
||||
sudo snap install yq
|
||||
|
||||
df -h
|
||||
|
||||
# Get extractor, LKM, Addons, Modules, Theme and Configs
|
||||
- name: Get Buildroot
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
echo "Get Dependencies"
|
||||
getAddons "files/p3/addons"
|
||||
getModules "files/p3/modules"
|
||||
getConfigs "files/p3/configs"
|
||||
getPatches "files/p3/patches"
|
||||
getCustom "files/p3/custom"
|
||||
getOffline "files/p3/configs"
|
||||
getLKMs "files/p3/lkms"
|
||||
getTheme "files/p1/boot/grub"
|
||||
getBuildrootx "brx"
|
||||
getBuildroots "brs"
|
||||
|
||||
# Export Dependencies Version to env
|
||||
echo "ADDONTAG=${ADDONTAG}" >> $GITHUB_ENV
|
||||
echo "MODULETAG=${MODULETAG}" >> $GITHUB_ENV
|
||||
echo "CONFIGTAG=${CONFIGTAG}" >> $GITHUB_ENV
|
||||
echo "PATCHTAG=${PATCHTAG}" >> $GITHUB_ENV
|
||||
echo "CUSTOMTAG=${CUSTOMTAG}" >> $GITHUB_ENV
|
||||
echo "LKMTAG=${LKMTAG}" >> $GITHUB_ENV
|
||||
echo "THEMETAG=${THEMETAG}" >> $GITHUB_ENV
|
||||
echo "BRXTAG=${BRXTAG}" >> $GITHUB_ENV
|
||||
echo "BRSTAG=${BRSTAG}" >> $GITHUB_ENV
|
||||
echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M')" >> $GITHUB_ENV
|
||||
|
||||
echo "OK"
|
||||
|
||||
# Build incremental
|
||||
- name: Build Next Image
|
||||
if: ${{ inputs.next == true }}
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
# Modify Source File
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="${{ inputs.version }}-dev"
|
||||
ARC_BRANCH="next"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
|
||||
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
|
||||
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
|
||||
|
||||
echo "Create Arc Image"
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[ ! -f "brx/bzImage-arc" ] || [ ! -f "brx/initrd-arc" ] && return 1
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brx/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brx/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brx/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sudo sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
echo "Image Converter"
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic arc-dyn.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vhdx -o subformat=dynamic arc.vhdx
|
||||
|
||||
# Zip image and generate checksum
|
||||
- name: Pack Next Image
|
||||
if: ${{ inputs.next == true }}
|
||||
run: |
|
||||
if [ -n "${{ env.ARC_VERSION }}" ]; then
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhdx.zip" arc.vhdx
|
||||
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
- name: Cleanup
|
||||
run: |
|
||||
rm -rf "arc.img" "arc.vmdk" "arc-dyn.vmdk" "arc.vhdx" "arc-flat.vmdk"
|
||||
|
||||
# Build incremental
|
||||
- name: Build Stable Image
|
||||
if: ${{ inputs.stable }}
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
# Modify Source File
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="${{ inputs.version }}-dev"
|
||||
ARC_BRANCH="stable"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
|
||||
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
|
||||
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
|
||||
|
||||
echo "Create Arc Image"
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[ ! -f "brs/bzImage-arc" ] || [ ! -f "brs/initrd-arc" ] && return 1
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brs/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brs/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brs/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sudo sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
echo "Image Converter"
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic arc-dyn.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vhdx -o subformat=dynamic arc.vhdx
|
||||
|
||||
# Zip image and generate checksum
|
||||
- name: Pack Stable Image
|
||||
if: ${{ inputs.stable }}
|
||||
run: |
|
||||
if [ -n "${{ env.ARC_VERSION }}" ]; then
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhdx.zip" arc.vhdx
|
||||
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
|
||||
fi
|
||||
|
||||
# Publish a release if is a tag
|
||||
- name: Release
|
||||
if: success() && env.ARC_VERSION != ''
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ env.ARC_VERSION }}
|
||||
prerelease: true
|
||||
makeLatest: false
|
||||
allowUpdates: true
|
||||
body: |
|
||||
### Note:
|
||||
- Development Build
|
||||
|
||||
### Information:
|
||||
- Full Changelog is available in my Discord
|
||||
- Discord Account for Arc Patch needed
|
||||
|
||||
### Dependencies:
|
||||
- Addons: ${{ env.ADDONTAG }}
|
||||
- Modules: ${{ env.MODULETAG }}
|
||||
- Configs: ${{ env.CONFIGTAG }}
|
||||
- Patches: ${{ env.PATCHTAG }}
|
||||
- Custom: ${{ env.CUSTOMTAG }}
|
||||
- LKMs: ${{ env.LKMTAG }}
|
||||
- Buildroot Stable: ${{ env.BRSTAG }}
|
||||
- Buildroot Next: ${{ env.BRXTAG }}
|
||||
|
||||
### Release
|
||||
- ${{ env.BUILD_TIME }}
|
||||
artifacts: |
|
||||
arc-*.zip
|
||||
update-*.zip
|
||||
294
.github/workflows/build.yml
vendored
Normal file
294
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
#
|
||||
# Copyright (C) 2024 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
name: Build Arc Image
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
runs:
|
||||
description: "runs-on"
|
||||
type: choice
|
||||
options:
|
||||
- ubuntu-latest
|
||||
- self-hosted
|
||||
version:
|
||||
description: "version (1.0.0)"
|
||||
required: true
|
||||
type: string
|
||||
notice:
|
||||
description: "Notice here"
|
||||
required: false
|
||||
type: string
|
||||
latest:
|
||||
description: "latest"
|
||||
default: true
|
||||
type: boolean
|
||||
prerelease:
|
||||
description: "pre release"
|
||||
default: false
|
||||
type: boolean
|
||||
next:
|
||||
description: "next"
|
||||
default: true
|
||||
type: boolean
|
||||
stable:
|
||||
description: "stable"
|
||||
default: true
|
||||
type: boolean
|
||||
clean:
|
||||
description: "clean"
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.runs }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@main
|
||||
|
||||
- name: Delete releases and workflows runs
|
||||
if: ${{ inputs.clean == true }}
|
||||
uses: ophub/delete-releases-workflows@main
|
||||
with:
|
||||
delete_releases: true
|
||||
releases_keep_latest: 1
|
||||
delete_workflows: false
|
||||
delete_tags: true
|
||||
gh_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Install Dependencies
|
||||
- name: Install Dependencies
|
||||
if: ${{ inputs.runs == 'ubuntu-latest' }}
|
||||
run: |
|
||||
git config --global user.email "info@auxxxilium.tech"
|
||||
git config --global user.name "AuxXxilium"
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y jq gawk cpio gettext libelf-dev qemu-utils busybox dialog curl sed
|
||||
sudo snap install yq
|
||||
|
||||
df -h
|
||||
|
||||
# Get extractor, LKM, Addons, Modules, Theme and Configs
|
||||
- name: Get Dependencies for all Image
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
echo "Get Dependencies"
|
||||
getAddons "files/p3/addons"
|
||||
getModules "files/p3/modules"
|
||||
getConfigs "files/p3/configs"
|
||||
getPatches "files/p3/patches"
|
||||
getCustom "files/p3/custom"
|
||||
getOffline "files/p3/configs"
|
||||
getLKMs "files/p3/lkms"
|
||||
getTheme "files/p1/boot/grub"
|
||||
getBuildrootx "brx"
|
||||
getBuildroots "brs"
|
||||
|
||||
# Export Dependencies Version to env
|
||||
echo "ADDONTAG=${ADDONTAG}" >> $GITHUB_ENV
|
||||
echo "MODULETAG=${MODULETAG}" >> $GITHUB_ENV
|
||||
echo "CONFIGTAG=${CONFIGTAG}" >> $GITHUB_ENV
|
||||
echo "PATCHTAG=${PATCHTAG}" >> $GITHUB_ENV
|
||||
echo "CUSTOMTAG=${CUSTOMTAG}" >> $GITHUB_ENV
|
||||
echo "LKMTAG=${LKMTAG}" >> $GITHUB_ENV
|
||||
echo "THEMETAG=${THEMETAG}" >> $GITHUB_ENV
|
||||
echo "BRXTAG=${BRXTAG}" >> $GITHUB_ENV
|
||||
echo "BRSTAG=${BRSTAG}" >> $GITHUB_ENV
|
||||
echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M')" >> $GITHUB_ENV
|
||||
|
||||
echo "OK"
|
||||
|
||||
# Build incremental
|
||||
- name: Build Next Image
|
||||
if: ${{ inputs.next == true }}
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
# Modify Source File
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="${{ inputs.version }}"
|
||||
ARC_BRANCH="next"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
|
||||
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
|
||||
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
|
||||
|
||||
echo "Create Arc Image"
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[ ! -f "brx/bzImage-arc" ] || [ ! -f "brx/initrd-arc" ] && return 1
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brx/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brx/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brx/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sudo sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
echo "Image Converter"
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic arc-dyn.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vhdx -o subformat=dynamic arc.vhdx
|
||||
|
||||
echo "Create Arc ova"
|
||||
convertova "${IMAGE_FILE}" "arc.ova"
|
||||
|
||||
# Zip image and generate checksum
|
||||
- name: Pack Next Image
|
||||
if: ${{ inputs.next == true }}
|
||||
run: |
|
||||
if [ -n "${{ env.ARC_VERSION }}" ]; then
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhdx.zip" arc.vhdx
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.ova.zip" arc.ova
|
||||
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
- name: Cleanup
|
||||
run: |
|
||||
rm -rf "arc.img" "arc.ova" "arc.vmdk" "arc-dyn.vmdk" "arc.vhdx" "arc-flat.vmdk"
|
||||
|
||||
# Build incremental
|
||||
- name: Build Stable Image
|
||||
if: ${{ inputs.stable == true }}
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
# Modify Source File
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="${{ inputs.version }}"
|
||||
ARC_BRANCH="stable"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
|
||||
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
|
||||
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
|
||||
|
||||
echo "Create Arc Image"
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[ ! -f "brs/bzImage-arc" ] || [ ! -f "brs/initrd-arc" ] && return 1
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brs/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brs/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brs/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sudo sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
echo "Image Converter"
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic arc-dyn.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
qemu-img convert ${IMAGE_FILE} -O vhdx -o subformat=dynamic arc.vhdx
|
||||
|
||||
echo "Create Arc ova"
|
||||
convertova "${IMAGE_FILE}" "arc.ova"
|
||||
|
||||
# Zip image and generate checksum
|
||||
- name: Pack Stable Image
|
||||
if: ${{ inputs.stable == true }}
|
||||
run: |
|
||||
if [ -n "${{ env.ARC_VERSION }}" ]; then
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhdx.zip" arc.vhdx
|
||||
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.ova.zip" arc.ova
|
||||
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
|
||||
fi
|
||||
|
||||
# Publish a release if is a tag
|
||||
- name: Release
|
||||
if: success() && env.ARC_VERSION != ''
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ env.ARC_VERSION }}
|
||||
prerelease: ${{ inputs.prerelease }}
|
||||
makeLatest: ${{ inputs.latest }}
|
||||
allowUpdates: true
|
||||
body: |
|
||||
### Note:
|
||||
- ${{ inputs.notice }}
|
||||
|
||||
### Information:
|
||||
- Full Changelog is available in my Discord
|
||||
- Discord Account for Arc Patch needed
|
||||
|
||||
### Versions:
|
||||
- stable: Stable Image (Full Image, all dependencies are included, less hardware support)
|
||||
- next: Next Image (Full Image, all dependencies are included, more hardware support, new features to test)
|
||||
|
||||
### Dependencies:
|
||||
- Addons: ${{ env.ADDONTAG }}
|
||||
- Modules: ${{ env.MODULETAG }}
|
||||
- Configs: ${{ env.CONFIGTAG }}
|
||||
- Patches: ${{ env.PATCHTAG }}
|
||||
- Custom: ${{ env.CUSTOMTAG }}
|
||||
- LKMs: ${{ env.LKMTAG }}
|
||||
- Buildroot Stable: ${{ env.BRSTAG }}
|
||||
- Buildroot Next: ${{ env.BRXTAG }}
|
||||
|
||||
### Release
|
||||
- ${{ env.BUILD_TIME }}
|
||||
artifacts: |
|
||||
arc-*.zip
|
||||
update-*.zip
|
||||
318
.github/workflows/custom.yml
vendored
Normal file
318
.github/workflows/custom.yml
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
#
|
||||
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
name: Custom Build
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.event.label.name == 'custom'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@main
|
||||
|
||||
- name: Init Env
|
||||
run: |
|
||||
git config --global user.email "info@auxxxilium.tech"
|
||||
git config --global user.name "AuxXxilium"
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
- name: Check Custom
|
||||
shell: python
|
||||
run: |
|
||||
# -*- coding: utf-8 -*-
|
||||
import json, subprocess
|
||||
def set_output(name, value):
|
||||
subprocess.call(["echo '{}={}' >> $GITHUB_ENV".format(name, value)], shell=True)
|
||||
|
||||
issuetitle = ${{ toJSON(github.event.issue.title) }};
|
||||
issuebody = ${{ toJSON(github.event.issue.body) }};
|
||||
|
||||
MODEL = ''
|
||||
PRODUCTVER = ''
|
||||
ADDONS = ''
|
||||
KERNEL = ''
|
||||
FORMAT = ''
|
||||
BRANCH = ''
|
||||
try:
|
||||
jsonbody = json.loads(issuebody)
|
||||
MODEL = jsonbody.get('model', '')
|
||||
PRODUCTVER = jsonbody.get('version', '')
|
||||
ADDONS = jsonbody.get('addons', '')
|
||||
KERNEL = jsonbody.get('kernel', '')
|
||||
FORMAT = jsonbody.get('format', '')
|
||||
BRANCH = jsonbody.get('branch', '')
|
||||
except ValueError as e:
|
||||
pass
|
||||
|
||||
set_output("MODEL", MODEL)
|
||||
set_output("PRODUCTVER", PRODUCTVER)
|
||||
set_output("ADDONS", ADDONS)
|
||||
set_output("KERNEL", KERNEL)
|
||||
set_output("FORMAT", FORMAT)
|
||||
set_output("BRANCH", BRANCH)
|
||||
|
||||
# calculates the version number and push
|
||||
- name: Calculate Version
|
||||
run: |
|
||||
# Calculate Version
|
||||
VERSION="`date +'%y.%-m.%-d'`-custom"
|
||||
|
||||
echo "Version: ${VERSION}"
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
|
||||
- name: Update Comment Building
|
||||
id: comment
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.event.issue.user.login }}.
|
||||
building arc-${{ env.MODEL }}-${{ env.VERSION }}, it will be uploaded here and sent to your email later..
|
||||
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
----
|
||||
|
||||
# Install dependencies
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y jq gawk cpio gettext libelf-dev qemu-utils busybox dialog curl sed
|
||||
sudo pip install -r scripts/requirements.txt
|
||||
sudo snap install yq
|
||||
|
||||
# Build incremental
|
||||
- name: Build image
|
||||
run: |
|
||||
. scripts/func.sh
|
||||
|
||||
function writeConfigKey() {
|
||||
[ "${2}" = "{}" ] && sudo yq eval '.'${1}' = {}' --inplace "${3}" 2>/dev/null || sudo yq eval '.'${1}' = "'"${2}"'"' --inplace "${3}" 2>/dev/null
|
||||
}
|
||||
|
||||
TAG="$(curl -m 5 -kL https://api.github.com/repos/AuxXxilium/arc/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')"
|
||||
curl -kL "https://github.com/AuxXxilium/arc/releases/download/${TAG}/arc-${TAG}-${{ env.BRANCH }}.img.zip" -o "/tmp/arc.img.zip"
|
||||
unzip -o "/tmp/arc.img.zip" -d "/tmp"
|
||||
|
||||
echo "Modify Arc Image"
|
||||
IMAGE_FILE="/tmp/arc.img"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting image file"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
echo "Set Custom Config"
|
||||
PRESET_CONFIG_FILE="/tmp/p1/user-config.yml"
|
||||
sudo touch "${PRESET_CONFIG_FILE}"
|
||||
MODEL="${{ env.MODEL }}"
|
||||
writeConfigKey "model" "${MODEL}" "${PRESET_CONFIG_FILE}"
|
||||
PRODUCTVER="${{ env.PRODUCTVER }}"
|
||||
PJ="$(python scripts/functions.py getpats4mv -m "${MODEL}" -v "${PRODUCTVER:0:3}")"
|
||||
PAT_URL=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".url")
|
||||
PAT_HASH=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".sum")
|
||||
writeConfigKey "productver" "${PRODUCTVER:0:3}" "${PRESET_CONFIG_FILE}"
|
||||
writeConfigKey "paturl" "${PAT_URL}" "${PRESET_CONFIG_FILE}"
|
||||
writeConfigKey "pathash" "${PAT_HASH}" "${PRESET_CONFIG_FILE}"
|
||||
if [ "${{ env.MODEL }}" = "SA6400" ]; then
|
||||
writeConfigKey "kernel" "${{ env.KERNEL }}" "${PRESET_CONFIG_FILE}"
|
||||
fi
|
||||
writeConfigKey "addons" "{}" "${PRESET_CONFIG_FILE}"
|
||||
if [ -n "${{ env.ADDONS }}" ]; then
|
||||
for A in $(echo "${{ env.ADDONS }}" | tr ',' ' ' | sed 's/\[//g' | sed 's/\]//g'); do
|
||||
VALUE=""
|
||||
writeConfigKey "addons.\"${A}\"" "${VALUE}" "${PRESET_CONFIG_FILE}"
|
||||
done
|
||||
fi
|
||||
writeConfigKey "automated" "true" "${PRESET_CONFIG_FILE}"
|
||||
echo "$(cat "${PRESET_CONFIG_FILE}")"
|
||||
sudo echo "arc-${MODEL}-${PRODUCTVER:0:3}-${TAG}" >"/tmp/automated"
|
||||
sudo mv -f "/tmp/automated" "/tmp/p3/automated"
|
||||
DSM_FILE="${PAT_HASH}.tar"
|
||||
DSM_URL="https://raw.githubusercontent.com/AuxXxilium/arc-dsm/main/files/${MODEL/+/%2B}/${PRODUCTVER:0:3}/${PAT_HASH}.tar"
|
||||
sudo curl -skL "${DSM_URL}" -o "/tmp/${DSM_FILE}"
|
||||
[ -f "/tmp/${DSM_FILE}" ] && echo "dsm: download successful" || exit 1
|
||||
sudo mkdir -p "/tmp/p3/users"
|
||||
sudo mv -f "/tmp/${DSM_FILE}" "/tmp/p3/users/${DSM_FILE}"
|
||||
echo "Syncing files"
|
||||
sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
cp -f "${IMAGE_FILE}" "arc.img"
|
||||
|
||||
if [ "${{ env.FORMAT }}" = "dyn" ]; then
|
||||
echo "Image Converter -> dyn"
|
||||
qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,compat6 arc-dyn.vmdk
|
||||
elif [ "${{ env.FORMAT }}" = "flat" ]; then
|
||||
echo "Image Converter -> flat"
|
||||
qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat,compat6 arc.vmdk
|
||||
elif [ "${{ env.FORMAT }}" = "vhdx" ]; then
|
||||
echo "Image Converter -> vhdx"
|
||||
qemu-img convert arc.img -O vhdx -o subformat=dynamic arc.vhdx
|
||||
elif [ "${{ env.FORMAT }}" = "ova" ]; then
|
||||
echo "Image Converter -> ova"
|
||||
convertova "arc.img" "arc.ova"
|
||||
fi
|
||||
|
||||
# Zip image and generate checksum
|
||||
- name: Pack
|
||||
run: |
|
||||
if [ "${{ env.FORMAT }}" = "img" ]; then
|
||||
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.img.zip" arc.img
|
||||
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.img.zip" "https://file.io")"
|
||||
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${{ env.FORMAT }}" = "dyn" ]; then
|
||||
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-dyn.zip" arc-dyn.vmdk
|
||||
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-dyn.zip" "https://file.io")"
|
||||
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${{ env.FORMAT }}" = "flat" ]; then
|
||||
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
|
||||
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-flat.zip" "https://file.io")"
|
||||
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${{ env.FORMAT }}" = "vhdx" ]; then
|
||||
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vhdx.zip" arc.vhdx
|
||||
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vhdx.zip" "https://file.io")"
|
||||
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${{ env.FORMAT }}" = "ova" ]; then
|
||||
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.ova.zip" arc.ova
|
||||
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.ova.zip" "https://file.io")"
|
||||
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
EMAIL=$(curl -s -H "Authorization: token ${{ secrets.ACTION }}" "https://api.github.com/users/${{ github.event.issue.user.login }}" | jq -r '.email')
|
||||
FIOURL="$(echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+')"
|
||||
echo "EMAIL=${EMAIL}" >> $GITHUB_ENV
|
||||
echo "FIOURL=${FIOURL}" >> $GITHUB_ENV
|
||||
|
||||
- name: Send mail
|
||||
if: success() && env.EMAIL != 'null'
|
||||
uses: dawidd6/action-send-mail@v3
|
||||
with:
|
||||
server_address: smtp.gmail.com
|
||||
server_port: 587
|
||||
username: ${{ secrets.MAIL_USERNAME }}
|
||||
password: ${{ secrets.MAIL_PASSWORD }}
|
||||
subject: arc-${{ env.model }}-${{ env.VERSION }}
|
||||
to: ${{ env.EMAIL }}
|
||||
from: ${{ secrets.MAIL_USERNAME }}
|
||||
body: |
|
||||
${{ env.FIOURL }}
|
||||
|
||||
- name: Update Comment Success
|
||||
if: success()
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'update-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
comment-id: ${{ steps.comment.outputs.comment-id }}
|
||||
update-mode: replace
|
||||
body: |
|
||||
Hi @${{ github.event.issue.user.login }}.
|
||||
arc-${{ env.MODEL }}-${{ env.VERSION }} is ready to download: ${{ env.FIOURL }}
|
||||
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
If this will not work, do not use customized Versions!
|
||||
----
|
||||
|
||||
- name: Update Comment Fail
|
||||
if: failure()
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'update-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
comment-id: ${{ steps.comment.outputs.comment-id }}
|
||||
update-mode: replace
|
||||
body: |
|
||||
Hi @${{ github.event.issue.user.login }}.
|
||||
arc-${{ env.MODEL }}-${{ env.PRODUCTVER }}-${{ env.VERSION }} failed to build and package, please try again.
|
||||
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
If this will not work, do not use customized Versions!
|
||||
----
|
||||
|
||||
- name: Close Issues
|
||||
if: success()
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'close-issue'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
|
||||
comment:
|
||||
if: github.event.label.name == 'bug'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Init Env
|
||||
run: |
|
||||
git config --global user.email "info@auxxxilium.tech"
|
||||
git config --global user.name "AuxXxilium"
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
- name: Check Issues
|
||||
run: |
|
||||
if echo "${{ github.event.issue.body }}" | grep -q "Screenshots"; then
|
||||
echo "FALG=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "FALG=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Create Issues comment
|
||||
if: env.FALG == 'false'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: "create-comment"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
**Describe the Bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Screenshots**
|
||||
Screenshot the Systeminfo (Arc - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT
|
||||
|
||||
**Hardware**
|
||||
Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ...
|
||||
|
||||
- name: Close Issues
|
||||
if: env.FALG == 'false'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'close-issue'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
49
.github/workflows/data.yml
vendored
49
.github/workflows/data.yml
vendored
@@ -34,16 +34,11 @@ jobs:
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev busybox dialog curl xz-utils cpio sed qemu-utils
|
||||
sudo apt install -y build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev # kmodule dependencies
|
||||
|
||||
YQ=$(command -v yq)
|
||||
if [ -z "${YQ}" ] || ! ${YQ} --version 2>/dev/null | grep -q "v4."; then
|
||||
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O "${YQ:-"/usr/bin/yq"}" && chmod +x "${YQ:-"/usr/bin/yq"}"
|
||||
fi
|
||||
|
||||
- name: Get Addon Data for Arc
|
||||
- name: Get Release Data for Arc
|
||||
run: |
|
||||
REPO="https://github.com/AuxXxilium/arc-addons"
|
||||
REPO="${{ github.server_url }}/${{ github.repository }}"
|
||||
PRERELEASE="true"
|
||||
|
||||
TAG=""
|
||||
@@ -54,46 +49,28 @@ jobs:
|
||||
TAG="${LATESTURL##*/}"
|
||||
fi
|
||||
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
|
||||
rm -f addons.zip
|
||||
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/addons-${TAG}.zip" -o "addons.zip")
|
||||
rm -f arc-${TAG}.img.zip
|
||||
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/arc-${TAG}.img.zip" -o "arc-${TAG}.img.zip")
|
||||
if [ $? -ne 0 -o ${STATUS:-0} -ne 200 ]; then
|
||||
echo "Download failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "mnt/p3/addons"
|
||||
unzip addons.zip -d "mnt/p3/addons"
|
||||
for i in $(find "mnt/p3/addons" -type f -name "*.addon"); do
|
||||
if [ -f "${i}" ]; then
|
||||
mkdir -p "mnt/p3/addons/$(basename "${i}" .addon)"
|
||||
tar -xaf "${i}" -C "mnt/p3/addons/$(basename "${i}" .addon)"
|
||||
fi
|
||||
done
|
||||
rm -f addons.zip
|
||||
unzip arc-${TAG}.img.zip -d "arc"
|
||||
|
||||
- name: Get Config Data for Arc
|
||||
run: |
|
||||
REPO="https://github.com/AuxXxilium/arc-configs"
|
||||
LATESTURL="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest")"
|
||||
TAG="${LATESTURL##*/}"
|
||||
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
|
||||
rm -f configs.zip
|
||||
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/configs-${TAG}.zip" -o "configs.zip")
|
||||
if [ $? -ne 0 -o ${STATUS:-0} -ne 200 ]; then
|
||||
echo "Download failed"
|
||||
sudo ./localbuild.sh create arc/ws arc/arc.img
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "create failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "mnt/p3/configs"
|
||||
unzip configs.zip -d "mnt/p3/configs"
|
||||
rm -f configs.zip
|
||||
|
||||
- name: Get data
|
||||
run: |
|
||||
pip install -r scripts/requirements.txt
|
||||
python scripts/functions.py getmodels -w "." -j "docs/models.json"
|
||||
python scripts/functions.py getaddons -w "." -j "docs/addons.json"
|
||||
python scripts/functions.py getpats -w "." -j "docs/pats.json"
|
||||
python scripts/func.py getmodels -w "arc/ws" -j "docs/models.json"
|
||||
python scripts/func.py getaddons -w "arc/ws" -j "docs/addons.json"
|
||||
python scripts/func.py getmodules -w "arc/ws" -j "docs/modules.json"
|
||||
python scripts/func.py getpats -w "arc/ws" -j "docs/pats.json"
|
||||
|
||||
- name: Upload to Artifacts
|
||||
if: success()
|
||||
|
||||
55
.github/workflows/grub.yml
vendored
Normal file
55
.github/workflows/grub.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
name: Grub
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
push:
|
||||
description: "push"
|
||||
default: false
|
||||
type: boolean
|
||||
jobs:
|
||||
grub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@main
|
||||
|
||||
- name: Initialization environment
|
||||
run : |
|
||||
git config --global user.email "info@auxxxilium.tech"
|
||||
git config --global user.name "AuxXxilium"
|
||||
sudo timedatectl set-timezone "Europe/Berlin"
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y autoconf automake autopoint gettext build-essential bison flex libtool dosfstools e2fsprogs
|
||||
sudo apt install -y libfreetype6-dev unifont fonts-dejavu libfuse-dev liblzma-dev libzfslinux-dev
|
||||
|
||||
- name: Make Grub
|
||||
run: |
|
||||
. scripts/grub.sh "grub-2.12" "i386-pc i386-efi x86_64-efi"
|
||||
|
||||
- name: Check and Push
|
||||
if: success() && inputs.push == true
|
||||
run: |
|
||||
if [ -f "grub.img.gz" ]; then
|
||||
echo "Copy img ..."
|
||||
mv -f grub.img.gz files/initrd/opt/arc/grub.img.gz
|
||||
|
||||
echo "Git push ..."
|
||||
git pull
|
||||
status=$(git status -s | grep -E 'grub.img.gz' | awk '{printf " %s", $2}')
|
||||
if [ -n "${status}" ]; then
|
||||
git add ${status}
|
||||
git commit -m "grub: update $(date +%Y-%m-%d" "%H:%M:%S)"
|
||||
git push -f
|
||||
fi
|
||||
else
|
||||
echo "No change ..."
|
||||
fi
|
||||
10
README.md
10
README.md
@@ -1,6 +1,6 @@
|
||||
<center><img width="845" alt="arc_loader" src="https://github.com/AuxXxilium/AuxXxilium/assets/67025065/ef975a36-9f3e-4cfb-813c-402db69611e7"></center>
|
||||
|
||||
Arc is a customized Redpill Loader for DSM 7.x (Xpenology) with enhanced Hardwaresupport, Addons, Extensions, guided(semi-automated) Installation and more. Multiple customization options are built-in. It is modified to run on different Hardware (see Wiki for more Informations).
|
||||
The Arc Loader is a customized Redpill Loader for DSM 7.x (Xpenology) with enhanced Hardwaresupport, Addons, guided(semi-automated) Installation and more. Multiple customization options are built-in. It is modified to run on different Hardware (see Wiki for more Informations).
|
||||
|
||||
- Commercial use is not permitted and strictly forbidden!!!
|
||||
- DSM and all Parts are under Copyright / Ownership or Registered Trademark by Synology Inc.
|
||||
@@ -17,7 +17,11 @@ Arc is a customized Redpill Loader for DSM 7.x (Xpenology) with enhanced Hardwar
|
||||
- <a href="https://github.com/AuxXxilium">Overview</a>
|
||||
- <a href="https://auxxxilium.tech/wiki">FAQ & Wiki</a>
|
||||
- <a href="https://github.com/AuxXxilium/arc/releases?q=prerelease%3Afalse&expanded=true">Download latest Build</a>
|
||||
- <a href="https://auxxxilium.github.io/arc">Customized Build with automated Config</a>
|
||||
|
||||
### Developer
|
||||
|
||||
- <a href="https://github.com/AuxXxilium">AuxXxilium</a>
|
||||
- <a href="https://github.com/FulcrumCode">Fulcrum</a>
|
||||
|
||||
### Thanks
|
||||
For code and ideas based on the work of TTG, pocopico, jumkey, fbelavenuto, wjz304 and others involved in continuing TTG's original redpill-load project.
|
||||
Code is based on the work of TTG, pocopico, jumkey, fbelavenuto, wjz304 and others involved in continuing TTG's original redpill-load project.
|
||||
|
||||
20
Taskfile.yaml
Normal file
20
Taskfile.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
# https://taskfile.dev
|
||||
|
||||
version: "3"
|
||||
|
||||
tasks:
|
||||
build-img-n:
|
||||
cmds:
|
||||
- git pull
|
||||
- ./img-gen-n.sh
|
||||
|
||||
build-img-s:
|
||||
cmds:
|
||||
- git pull
|
||||
- ./img-gen-s.sh
|
||||
|
||||
compile-kpatch:
|
||||
dir: kpatch
|
||||
cmds:
|
||||
- make clean all
|
||||
- mv kpatch ../files/p3/system/
|
||||
178
docs/addons.json
178
docs/addons.json
@@ -1,178 +0,0 @@
|
||||
{
|
||||
"acpid": {
|
||||
"system": false,
|
||||
"description": "Daemon for delivering ACPI events (Powerbutton, etc.)"
|
||||
},
|
||||
"addincards": {
|
||||
"system": false,
|
||||
"description": "Remove the Modelrestrictions for official Addin Cards"
|
||||
},
|
||||
"allowdowngrade": {
|
||||
"system": false,
|
||||
"description": "Allow Downgrade for AME, MediaServer, SynoPhotos, SS and VideoStation on DSM 7.2.2"
|
||||
},
|
||||
"amepatch": {
|
||||
"system": false,
|
||||
"description": "Dynamic Licensepatch for AME - Force download HEVC Codec (Don't use with codecpatch)"
|
||||
},
|
||||
"arcdns": {
|
||||
"system": false,
|
||||
"description": "Dynamic DNS client for arcdns.tech - Modify in DSM DynDNS Settings"
|
||||
},
|
||||
"beep": {
|
||||
"system": false,
|
||||
"description": "Beep at startup and shutdown (requires motherboard with buzzer)"
|
||||
},
|
||||
"bootwait": {
|
||||
"system": false,
|
||||
"description": "Boot process waits until boot device (`/dev/synoboot`) and PCIe Device are available"
|
||||
},
|
||||
"codecpatch": {
|
||||
"system": false,
|
||||
"description": "Enables transcoding for DSM - Force download AAC + HEVC Codec (Don't use with amepatch)"
|
||||
},
|
||||
"cpufreqscaling": {
|
||||
"system": false,
|
||||
"description": "Enable CPU Freqscaling for DSM - Modify in Arc DSM Options"
|
||||
},
|
||||
"cpuinfo": {
|
||||
"system": false,
|
||||
"description": "Add real CPU Information to DSM System"
|
||||
},
|
||||
"dbgutils": {
|
||||
"system": false,
|
||||
"description": "Binaries to facilitate debug in the junior mode"
|
||||
},
|
||||
"deduplication": {
|
||||
"system": false,
|
||||
"description": "Force enable Deduplication (Only for SSD)"
|
||||
},
|
||||
"disks": {
|
||||
"system": true,
|
||||
"description": "Config disks related setting"
|
||||
},
|
||||
"dsmconfigbackup": {
|
||||
"system": false,
|
||||
"description": "Automatically backup Systemconfig Settings to the Bootloader Disk(/mnt/p1/dsmbackup) at Shutdown"
|
||||
},
|
||||
"eudev": {
|
||||
"system": true,
|
||||
"description": "eudev + kmod will assist with auto module loading"
|
||||
},
|
||||
"expands": {
|
||||
"system": false,
|
||||
"description": "Expanded miscellaneous, updated usb.map, ca-certificates.crt and more"
|
||||
},
|
||||
"hdddb": {
|
||||
"system": false,
|
||||
"description": "Add Disks to DSM compatibility DiskDB and bypass Memory Limitation"
|
||||
},
|
||||
"i915": {
|
||||
"system": false,
|
||||
"description": "Automatically replace the device ID of i915 module. (Intel 2nd - 9th Gen)"
|
||||
},
|
||||
"ledcontrol": {
|
||||
"system": false,
|
||||
"description": "Add Ugreen Ledcontrol to DSM (Need sensors Addon)"
|
||||
},
|
||||
"localrss": {
|
||||
"system": true,
|
||||
"description": "rss for bootloader pat"
|
||||
},
|
||||
"lsiutil": {
|
||||
"system": false,
|
||||
"description": "A tool for working with some LSI RAID controllers"
|
||||
},
|
||||
"misc": {
|
||||
"system": true,
|
||||
"description": "Miscellaneous functions"
|
||||
},
|
||||
"mountloader": {
|
||||
"system": true,
|
||||
"description": "Add a script to mount/unmount loader disk in the DSM scheduled task"
|
||||
},
|
||||
"notify": {
|
||||
"system": true,
|
||||
"description": "Add Arc Notification System"
|
||||
},
|
||||
"nvmecache": {
|
||||
"system": false,
|
||||
"description": "Enable M.2 as Cache (for DS918+ RS1619xs+ DS1019+ DS1621xs+)"
|
||||
},
|
||||
"nvmesystem": {
|
||||
"system": false,
|
||||
"description": "Enable DSM installation to NVMe M.2 SSDs. (Only use if you have only NVMe M.2 SSDs installed)"
|
||||
},
|
||||
"nvmevolume": {
|
||||
"system": false,
|
||||
"description": "Enable M.2 as Volume (for non supported Models)"
|
||||
},
|
||||
"optional": {
|
||||
"system": false,
|
||||
"description": "Disable some DSM logs and help with Disk hibernation"
|
||||
},
|
||||
"photosfacepatch": {
|
||||
"system": false,
|
||||
"description": "Face Detection Patch for Syno Photos (Best with iGPU)"
|
||||
},
|
||||
"powersched": {
|
||||
"system": false,
|
||||
"description": "Utility to configure RTC according to DSM power schedule (If supported)"
|
||||
},
|
||||
"reboottoloader": {
|
||||
"system": false,
|
||||
"description": "Add ability to reboot to Loader from Inside DSM"
|
||||
},
|
||||
"redpill": {
|
||||
"system": true,
|
||||
"description": "Delay redpill for epyc7002"
|
||||
},
|
||||
"remotefs": {
|
||||
"system": false,
|
||||
"description": "Allow remote NFS/CIFS shared folder be used in VideoStation, AudioStation and PhotoStation"
|
||||
},
|
||||
"revert": {
|
||||
"system": true,
|
||||
"description": "Revert all Modifications"
|
||||
},
|
||||
"sensors": {
|
||||
"system": false,
|
||||
"description": "Install sensors package to monitor temperature of CPU and other components"
|
||||
},
|
||||
"sequentialio": {
|
||||
"system": false,
|
||||
"description": "Enables sequential I/O for SSD caches (Can cause overheating) - Modify in Arc DSM Options"
|
||||
},
|
||||
"setrootpw": {
|
||||
"system": false,
|
||||
"description": "Set root password and enable ssh/sftp. Please modify PW=\"\" to the desired password in DSM Task Scheduler and run the task"
|
||||
},
|
||||
"smartctl": {
|
||||
"system": false,
|
||||
"description": "Fix SMART information for HBA devices. @Phachd"
|
||||
},
|
||||
"sortnetif": {
|
||||
"system": false,
|
||||
"description": "Sort network interface names: sorted by busid"
|
||||
},
|
||||
"sspatch": {
|
||||
"system": false,
|
||||
"description": "Dynamic License Patch for SS 9.2.x (Not for DVA 3219)"
|
||||
},
|
||||
"storagepanel": {
|
||||
"system": false,
|
||||
"description": "Automated Storagepanel selection - Modify in Arc DSM Options"
|
||||
},
|
||||
"updatenotify": {
|
||||
"system": false,
|
||||
"description": "Arc Loader Update Notifications in DSM"
|
||||
},
|
||||
"ups": {
|
||||
"system": false,
|
||||
"description": "Force UPS to shut down in Standby mode"
|
||||
},
|
||||
"wol": {
|
||||
"system": true,
|
||||
"description": "Force enable the Wake-on-lan on all nic"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
360
docs/custom.html
360
docs/custom.html
@@ -1,360 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
|
||||
data-a11y-animated-images="system">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="dns-prefetch" href="https://github.githubassets.com" />
|
||||
<link rel="dns-prefetch" href="https://avatars.githubusercontent.com" />
|
||||
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com" />
|
||||
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/" />
|
||||
<link rel="preconnect" href="https://github.githubassets.com" crossorigin />
|
||||
<link rel="preconnect" href="https://avatars.githubusercontent.com" />
|
||||
|
||||
<link crossorigin="anonymous" media="all" rel="stylesheet"
|
||||
href="https://github.githubassets.com/assets/light-0eace2597ca3.css" />
|
||||
<link crossorigin="anonymous" media="all" rel="stylesheet"
|
||||
href="https://github.githubassets.com/assets/dark-a167e256da9c.css" />
|
||||
|
||||
<link crossorigin="anonymous" media="all" rel="stylesheet"
|
||||
href="https://github.githubassets.com/assets/primer-711f412bb361.css" />
|
||||
<link crossorigin="anonymous" media="all" rel="stylesheet"
|
||||
href="https://github.githubassets.com/assets/global-78704364aaba.css" />
|
||||
<style>
|
||||
select,
|
||||
.input-style {
|
||||
width: 100%;
|
||||
}
|
||||
.textarea-style {
|
||||
width: 100%;
|
||||
}
|
||||
a {
|
||||
color: #ff0000;
|
||||
text-decoration: none;
|
||||
}
|
||||
.State--merged {
|
||||
background-color: #ff0000;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #333333;
|
||||
}
|
||||
.btn-primary:disabled {
|
||||
background-color: #111111;
|
||||
}
|
||||
.btn:disabled {
|
||||
background-color: #111111;
|
||||
}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
|
||||
<!-- <script src="https://fastly.jsdelivr.net/npm/marked/marked.min.js"></script> -->
|
||||
<script type="application/javascript">
|
||||
|
||||
var repo = "AuxXxilium/arc"
|
||||
|
||||
var _models = {};
|
||||
var _addons = {};
|
||||
var _pats = {};
|
||||
|
||||
function httpGetAsync(theUrl, callback) {
|
||||
let xmlHttpReq = new XMLHttpRequest();
|
||||
xmlHttpReq.onreadystatechange = function () {
|
||||
if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200)
|
||||
callback(xmlHttpReq.responseText);
|
||||
};
|
||||
xmlHttpReq.open("GET", theUrl, true); // true for asynchronous
|
||||
xmlHttpReq.send(null);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
init();
|
||||
}
|
||||
|
||||
function init() {
|
||||
httpGetAsync("https://raw.githubusercontent.com/AuxXxilium/arc/page/docs/models.json", function (result) {
|
||||
_models = JSON.parse(result);
|
||||
httpGetAsync("https://raw.githubusercontent.com/AuxXxilium/arc/page/docs/pats.json", function (result) {
|
||||
_pats = JSON.parse(result);
|
||||
httpGetAsync("https://raw.githubusercontent.com/AuxXxilium/arc/page/docs/addons.json", function (result) {
|
||||
_addons = JSON.parse(result);
|
||||
$("#model").on("change", changeModel);
|
||||
$("#version").on("change", changeVersion);
|
||||
$("#kernel").on("change", changeKernel);
|
||||
$('#addons').val("acpid,cpuinfo,powersched");
|
||||
setModels();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setModels() {
|
||||
var models = [];
|
||||
for (var P in _models) {
|
||||
models = models.concat(_models[P]["models"]);
|
||||
}
|
||||
$("#model")[0].options.length = 0;
|
||||
for (var i = 0; i < models.length; i++) {
|
||||
var model = models[i];
|
||||
$("#model").append(`<option value="${model}">${model}</option>`);
|
||||
}
|
||||
changeModel();
|
||||
}
|
||||
function changeModel() {
|
||||
model = $("#model").val();
|
||||
var versions = [];
|
||||
if (model in _pats) {
|
||||
versions = Object.keys(_pats[model]);
|
||||
versions.sort((a, b) => b.localeCompare(a))
|
||||
}
|
||||
$("#version")[0].options.length = 0;
|
||||
for (var i = 0; i < versions.length; i++) {
|
||||
var version = versions[i];
|
||||
$("#version").append(`<option value="${version}">${version}</option>`);
|
||||
}
|
||||
changeproductsimage();
|
||||
changeVersion();
|
||||
}
|
||||
|
||||
function changeproductsimage() {
|
||||
//var model = $("#model").val().replace("#","").replace("+","plus");
|
||||
//$('#products').html(`<img src="https://www.synology.cn/img/products/detail/${model}/heading.png" width="20%">`);
|
||||
var model = $("#model").val().replace("#", "").replace("+", "%2B");
|
||||
$('#products').html(`<img src="https://www.synology.com/api/products/getPhoto?product=${model}&type=img_s&sort=0" width="30%">`);
|
||||
}
|
||||
|
||||
function changeVersion() {
|
||||
createAddonsBtn();
|
||||
changeKernel();
|
||||
}
|
||||
|
||||
function createAddonsBtn() {
|
||||
var extstr = $('#addons').val().split(",");
|
||||
var idx = 1;
|
||||
var html = `<div class="form-group-body" id="addons_btns">`;
|
||||
var selectedModel = $("#model").val();
|
||||
var platform = null;
|
||||
|
||||
// Parse models.json to get the platform for the selected model
|
||||
$.getJSON('models.json', function(modelsData) {
|
||||
for (var key in modelsData) {
|
||||
if (modelsData[key].models.includes(selectedModel)) {
|
||||
platform = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse addons.json to generate buttons
|
||||
$.getJSON('addons.json', function(addonsData) {
|
||||
for (var ext in addonsData) {
|
||||
// Skip system addons
|
||||
if (addonsData[ext]["system"] == true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var dispar = "";
|
||||
if (!addonsData[ext][platform]) {
|
||||
dispar = "disabled";
|
||||
}
|
||||
var par = "";
|
||||
if (extstr.includes(ext)) {
|
||||
par = "btn-danger";
|
||||
}
|
||||
html += `<button type="button" class="btn btn-primary btn-sm mt-2 ${par}" id="btn_${ext}" ${par} ${dispar} onclick="return onclickext('addons', '${ext}')" autofocus="" title="${addonsData[ext]["description"]}">${ext}</button> `;
|
||||
}
|
||||
html += `</div>`;
|
||||
$('#addons_btns').html(html);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function changeKernel() {
|
||||
var model = $("#model").val();
|
||||
var version = $("#version").val().split(".").slice(0, 2).join(".");
|
||||
var kernel = $("#kernel").val();
|
||||
if (model == "SA6400" && version == "7.2") {
|
||||
$("#kernel_item").show();
|
||||
} else {
|
||||
$("#kernel_item").hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onclickext(type, ext) {
|
||||
var btnobj = $("#btn_" + ext);
|
||||
var extstr = $('#' + type).val().split(",");
|
||||
if (btnobj.hasClass("btn-danger")) {
|
||||
extstr.map((val, i) => {
|
||||
if (val === ext) {
|
||||
extstr.splice(i, 1);
|
||||
}
|
||||
});
|
||||
btnobj.removeClass("btn-danger");
|
||||
} else {
|
||||
btnobj.addClass("btn-danger");
|
||||
extstr.push(ext);
|
||||
}
|
||||
extstr.map((val, i) => {
|
||||
if (val === "") {
|
||||
extstr.splice(i, 1);
|
||||
}
|
||||
});
|
||||
$('#' + type).val(extstr.join(","));
|
||||
}
|
||||
|
||||
function createIssues() {
|
||||
var form = document.getElementById("inputs");
|
||||
let formData = new FormData(form);
|
||||
var title = "custom";
|
||||
var body = {};
|
||||
var _parameters = ["title", "branch", "format", "model", "version", "kernel", "addons"];
|
||||
for (var key in _parameters) {
|
||||
var name = _parameters[key];
|
||||
if ($("#" + name).is(":hidden")) { continue; }
|
||||
if (name == "title") {
|
||||
if ($("#" + name).val()) {
|
||||
title += " " + $("#" + name).val();
|
||||
} else {
|
||||
title += " " + new Date().toISOString().substr(0, 10);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($("#" + name).val()) {
|
||||
body[name] = $("#" + name).val();
|
||||
}
|
||||
}
|
||||
|
||||
body = JSON.stringify(body).replace(/\+/g, "%2b");
|
||||
window.location.href = `https://github.com/${repo}/issues/new?assignees=&labels=custom&projects=&template=custom_build.md&title=${title}&body=${body}`;
|
||||
|
||||
}
|
||||
</script>
|
||||
<title>Arc Loader - Custom</title>
|
||||
</head>
|
||||
|
||||
<body class="logged-in env-production page-responsive" style="word-wrap: break-word">
|
||||
<div class="application-main left-0 text-left p-3 mx-auto container-xl px-3 px-md-4 px-lg-5 mt-4">
|
||||
<pre id="logo">
|
||||
<img src="https://raw.githubusercontent.com/AuxXxilium/arc/page/docs/arc_loader.png" width="60%" style="margin-left: 100px; margin-right: 100px;">
|
||||
</pre>
|
||||
<div class="image" id="products" style="height: 70px; margin-left: 35%;">
|
||||
<img src="https://www.synology.com/img/products/detail/SA6400/heading.png" width="30%">
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2 ">
|
||||
<div class="form-group-header">
|
||||
<p> </p>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<p> </p>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2 ">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f4">Build is based on <img alt="GitHub Release" src="https://img.shields.io/github/v/release/AuxXxilium/arc?display_name=release&style=flat-square"></label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<label class="color-fg-default text-mono f4">You should only use custom Builds, if you don't have physical access or online connection for destination device.<br />
|
||||
Custom builds are not stable everytime, have limited features and there will no Arc Patch be available!!!<br />
|
||||
To get full features and options, use <a href="https://github.com/AuxXxilium/arc">Arc Loader</a>! Check the <a href="https://auxxxilium.tech/wiki" target="_blank">Wiki</a> before you start a build.</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="title_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Title:</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<input class="form-control input-contrast input-sm" type="text" id="title" name="inputs[title]"
|
||||
value="" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="format_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Branch:</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<select class="form-select form-control select-sm input-contrast" id="branch" name="inputs[branch]"
|
||||
value="">
|
||||
<option selected="selected" value="evo">evolution</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="format_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Format:</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<select class="form-select form-control select-sm input-contrast" id="format" name="inputs[format]"
|
||||
value="">
|
||||
<option selected="selected" value="img">img</option>
|
||||
<option value="dyn">vmdk-dyn</option>
|
||||
<option value="flat">vmdk-flat</option>
|
||||
<option value="vhdx">vhdx</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="model_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Model: <a href="https://auxxxilium.tech/wiki/arc-loader-arc-loader/modell-plattform-auswaehlen/" target="_blank">More Information</a></label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<select class="form-select form-control select-sm input-contrast" id="model" name="inputs[model]"
|
||||
value="">
|
||||
<option selected="selected" value="SA6400">SA6400</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="version_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Version:</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<select class="form-select form-control select-sm input-contrast" id="version" name="inputs[version]"
|
||||
value="">
|
||||
<option selected="selected" value="7.2">7.2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="kernel_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Kernel: (only for SA6400)</label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<select class="form-select form-control select-sm input-contrast" id="kernel" name="inputs[kernel]"
|
||||
value="">
|
||||
<option selected="selected" value="official">official</option>
|
||||
<option value="custom">custom</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-1 mb-2" id="addons_item">
|
||||
<div class="form-group-header">
|
||||
<label class="color-fg-default text-mono f5">Addons: <a href="https://auxxxilium.tech/wiki/arc-loader-arc-loader/addons/" target="_blank">More Information</a></label>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<textarea class="textarea-style input-contrast input-sm" type="text" id="addons" name="inputs[addons]"
|
||||
disabled></textarea>
|
||||
<div class="form-group-body" id="addons_btns">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group-body">
|
||||
<p> </p>
|
||||
</div>
|
||||
<div class="workflow-dispatch">
|
||||
<form id="inputs"><button type="button" class="btn State--merged" onclick="return createIssues()" autofocus="">Start Build</button></form>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer width-full container-xl mt-3 text-center color-fg-muted">
|
||||
<a aria-label="AuxXxilium" title="GitHub" class="footer-octicon mr-2" href="https://github.com/AuxXxilium">
|
||||
<img class="avatar rounded-2 avatar-user" src="https://avatars.githubusercontent.com/u/67025065?v=4"
|
||||
width="40" height="40" alt="AuxXxilium" />
|
||||
</a>
|
||||
<span>Copyright © 2024 by <a href="https://github.com/AuxXxilium">AuxXxilium</a><br> </span>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,6 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<script language="javascript"> location.replace("./custom.html")</script>
|
||||
</head>
|
||||
</html>
|
||||
171
docs/models.json
171
docs/models.json
@@ -1,171 +0,0 @@
|
||||
{
|
||||
"apollolake": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1019+",
|
||||
"DS620slim",
|
||||
"DS218+",
|
||||
"DS418play",
|
||||
"DS718+",
|
||||
"DS918+"
|
||||
]
|
||||
},
|
||||
"broadwell": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"FS3400",
|
||||
"RS3618xs",
|
||||
"DS3617xs",
|
||||
"DS3617xsII",
|
||||
"FS2017",
|
||||
"RS18017xs+",
|
||||
"RS3617RPxs",
|
||||
"RS3617xs+",
|
||||
"RS4017xs+"
|
||||
]
|
||||
},
|
||||
"broadwellnk": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1621xs+",
|
||||
"DS3622xs+",
|
||||
"FS3600",
|
||||
"RS1619xs+",
|
||||
"RS3621RPxs",
|
||||
"RS3621xs+",
|
||||
"RS4021xs+",
|
||||
"SA3400",
|
||||
"SA3600",
|
||||
"DS3018xs",
|
||||
"FS1018"
|
||||
]
|
||||
},
|
||||
"broadwellnkv2": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"FS3410",
|
||||
"SA3410",
|
||||
"SA3610"
|
||||
]
|
||||
},
|
||||
"broadwellntbap": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"SA3200D",
|
||||
"SA3400D"
|
||||
]
|
||||
},
|
||||
"denverton": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1819+",
|
||||
"DS2419+",
|
||||
"DS2419+II",
|
||||
"DVA3219",
|
||||
"DVA3221",
|
||||
"RS820+",
|
||||
"RS820RP+",
|
||||
"DS1618+",
|
||||
"RS2418+",
|
||||
"RS2418RP+",
|
||||
"RS2818RP+"
|
||||
]
|
||||
},
|
||||
"geminilake": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1520+",
|
||||
"DS220+",
|
||||
"DS224+",
|
||||
"DS420+",
|
||||
"DS423+",
|
||||
"DS720+",
|
||||
"DS920+",
|
||||
"DVA1622"
|
||||
]
|
||||
},
|
||||
"purley": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"FS6400",
|
||||
"HD6500"
|
||||
]
|
||||
},
|
||||
"r1000": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1522+",
|
||||
"DS723+",
|
||||
"DS923+",
|
||||
"RS422+"
|
||||
]
|
||||
},
|
||||
"v1000": {
|
||||
"productvers": {
|
||||
"7.0": "4.4.180",
|
||||
"7.1": "4.4.180",
|
||||
"7.2": "4.4.302"
|
||||
},
|
||||
"models": [
|
||||
"DS1621+",
|
||||
"DS1821+",
|
||||
"DS1823xs+",
|
||||
"DS2422+",
|
||||
"FS2500",
|
||||
"RS1221+",
|
||||
"RS1221RP+",
|
||||
"RS2421+",
|
||||
"RS2421RP+",
|
||||
"RS2423+",
|
||||
"RS2423RP+",
|
||||
"RS2821RP+",
|
||||
"RS822+",
|
||||
"RS822RP+"
|
||||
]
|
||||
},
|
||||
"epyc7002": {
|
||||
"productvers": {
|
||||
"7.1": "7.1-5.10.55",
|
||||
"7.2": "7.2-5.10.55"
|
||||
},
|
||||
"models": [
|
||||
"SA6400"
|
||||
]
|
||||
}
|
||||
}
|
||||
2084
docs/pats.json
2084
docs/pats.json
File diff suppressed because it is too large
Load Diff
2344
files/initrd/opt/arc/arc-functions.sh
Executable file
2344
files/initrd/opt/arc/arc-functions.sh
Executable file
File diff suppressed because it is too large
Load Diff
1117
files/initrd/opt/arc/arc.sh
Executable file
1117
files/initrd/opt/arc/arc.sh
Executable file
File diff suppressed because it is too large
Load Diff
330
files/initrd/opt/arc/boot.sh
Executable file
330
files/initrd/opt/arc/boot.sh
Executable file
@@ -0,0 +1,330 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/functions.sh
|
||||
|
||||
# Clear logs for dbgutils addons
|
||||
rm -rf "${PART1_PATH}/logs" >/dev/null 2>&1 || true
|
||||
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
[ "${BUILDDONE}" == "false" ] && die "Loader build not completed!"
|
||||
ARC_BRANCH="$(readConfigKey "arc.branch" "${USER_CONFIG_FILE}")"
|
||||
|
||||
# Get Loader Disk Bus
|
||||
[ -z "${LOADER_DISK}" ] && die "Loader Disk not found!"
|
||||
BUS=$(getBus "${LOADER_DISK}")
|
||||
# Check if machine has EFI
|
||||
[ -d /sys/firmware/efi ] && EFI=1 || EFI=0
|
||||
|
||||
# Print Title centralized
|
||||
clear
|
||||
COLUMNS=${COLUMNS:-50}
|
||||
BANNER="$(figlet -c -w "$(((${COLUMNS})))" "Arc Loader")"
|
||||
TITLE="Version:"
|
||||
TITLE+=" ${ARC_VERSION} (${ARC_BUILD})"
|
||||
[ -n "${ARC_BRANCH}" ] && TITLE+=" | Branch: ${ARC_BRANCH}"
|
||||
printf "\033[1;30m%*s\n" ${COLUMNS} ""
|
||||
printf "\033[1;30m%*s\033[A\n" ${COLUMNS} ""
|
||||
printf "\033[1;34m%*s\033[0m\n" ${COLUMNS} "${BANNER}"
|
||||
printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}"
|
||||
TITLE="Boot:"
|
||||
[ ${EFI} -eq 1 ] && TITLE+=" [UEFI]" || TITLE+=" [BIOS]"
|
||||
TITLE+=" [${BUS}]"
|
||||
printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}"
|
||||
# Check if DSM zImage/Ramdisk is changed, patch it if necessary, update Files if necessary
|
||||
ZIMAGE_HASH="$(readConfigKey "zimage-hash" "${USER_CONFIG_FILE}")"
|
||||
ZIMAGE_HASH_CUR="$(sha256sum "${ORI_ZIMAGE_FILE}" | awk '{print $1}')"
|
||||
RAMDISK_HASH="$(readConfigKey "ramdisk-hash" "${USER_CONFIG_FILE}")"
|
||||
RAMDISK_HASH_CUR="$(sha256sum "${ORI_RDGZ_FILE}" | awk '{print $1}')"
|
||||
if [ "${ZIMAGE_HASH_CUR}" != "${ZIMAGE_HASH}" ] || [ "${RAMDISK_HASH_CUR}" != "${RAMDISK_HASH}" ]; then
|
||||
echo -e "\033[1;31mDSM zImage/Ramdisk changed!\033[0m"
|
||||
livepatch
|
||||
echo
|
||||
fi
|
||||
|
||||
# Read model/system variables
|
||||
PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
|
||||
MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")"
|
||||
MODELID="$(readConfigKey "modelid" "${USER_CONFIG_FILE}")"
|
||||
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
BUILDNUM="$(readConfigKey "buildnum" "${USER_CONFIG_FILE}")"
|
||||
SMALLNUM="$(readConfigKey "smallnum" "${USER_CONFIG_FILE}")"
|
||||
LKM="$(readConfigKey "lkm" "${USER_CONFIG_FILE}")"
|
||||
CPU="$(echo $(cat /proc/cpuinfo 2>/dev/null | grep 'model name' | uniq | awk -F':' '{print $2}'))"
|
||||
RAMTOTAL="$(awk '/MemTotal:/ {printf "%.0f\n", $2 / 1024 / 1024 + 0.5}' /proc/meminfo 2>/dev/null)"
|
||||
VENDOR="$(dmesg 2>/dev/null | grep -i "DMI:" | head -1 | sed 's/\[.*\] DMI: //i')"
|
||||
DSMINFO="$(readConfigKey "boot.dsminfo" "${USER_CONFIG_FILE}")"
|
||||
SYSTEMINFO="$(readConfigKey "boot.systeminfo" "${USER_CONFIG_FILE}")"
|
||||
DISKINFO="$(readConfigKey "boot.diskinfo" "${USER_CONFIG_FILE}")"
|
||||
|
||||
if [ "${DSMINFO}" == "true" ]; then
|
||||
echo -e "\033[1;37mDSM:\033[0m"
|
||||
echo -e "Model: \033[1;37m${MODELID:-${MODEL}}\033[0m"
|
||||
echo -e "Platform: \033[1;37m${PLATFORM}\033[0m"
|
||||
echo -e "Version: \033[1;37m${PRODUCTVER} (${BUILDNUM}$([ ${SMALLNUM:-0} -ne 0 ] && echo "u${SMALLNUM}"))\033[0m"
|
||||
echo -e "LKM: \033[1;37m${LKM}\033[0m"
|
||||
echo
|
||||
fi
|
||||
if [ "${SYSTEMINFO}" == "true" ]; then
|
||||
echo -e "\033[1;37mSystem:\033[0m"
|
||||
echo -e "Vendor: \033[1;37m${VENDOR}\033[0m"
|
||||
echo -e "CPU: \033[1;37m${CPU}\033[0m"
|
||||
echo -e "Memory: \033[1;37m${RAMTOTAL}GB\033[0m"
|
||||
echo
|
||||
fi
|
||||
if [ "${DISKINFO}" == "true" ]; then
|
||||
echo -e "\033[1;37mDisks:\033[0m"
|
||||
echo -e "Disks: \033[1;37m$(lsblk -dpno NAME | grep -v "${LOADER_DISK}" | wc -l)\033[0m"
|
||||
fi
|
||||
|
||||
if ! readConfigMap "addons" "${USER_CONFIG_FILE}" | grep -q nvmesystem; then
|
||||
HASATA=0
|
||||
for D in $(lsblk -dpno NAME); do
|
||||
[ "${D}" == "${LOADER_DISK}" ] && continue
|
||||
if echo "sata sas scsi" | grep -qw "$(getBus "${D}")"; then
|
||||
HASATA=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ ${HASATA} -eq 0 ] && echo -e "\033[1;31m*** Please insert at least one Sata/SAS/SCSI Disk for System installation, except for the Bootloader Disk. ***\033[0m"
|
||||
fi
|
||||
|
||||
# Read necessary variables
|
||||
VID="$(readConfigKey "vid" "${USER_CONFIG_FILE}")"
|
||||
PID="$(readConfigKey "pid" "${USER_CONFIG_FILE}")"
|
||||
SN="$(readConfigKey "sn" "${USER_CONFIG_FILE}")"
|
||||
KERNELPANIC="$(readConfigKey "kernelpanic" "${USER_CONFIG_FILE}")"
|
||||
DT="$(readConfigKey "platforms.${PLATFORM}.dt" "${P_FILE}")"
|
||||
KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")"
|
||||
EMMCBOOT="$(readConfigKey "emmcboot" "${USER_CONFIG_FILE}")"
|
||||
MODBLACKLIST="$(readConfigKey "modblacklist" "${USER_CONFIG_FILE}")"
|
||||
ARCPATCH="$(readConfigKey "arc.patch" "${USER_CONFIG_FILE}")"
|
||||
|
||||
declare -A CMDLINE
|
||||
|
||||
# Automated Cmdline
|
||||
CMDLINE['syno_hw_version']="${MODELID:-${MODEL}}"
|
||||
CMDLINE['vid']="${VID:-"0x46f4"}" # Sanity check
|
||||
CMDLINE['pid']="${PID:-"0x0001"}" # Sanity check
|
||||
CMDLINE['sn']="${SN}"
|
||||
|
||||
# Boot Cmdline
|
||||
if grep -q "force_junior" /proc/cmdline; then
|
||||
CMDLINE['force_junior']=""
|
||||
fi
|
||||
if grep -q "recovery" /proc/cmdline; then
|
||||
CMDLINE['force_junior']=""
|
||||
CMDLINE['recovery']=""
|
||||
fi
|
||||
if [ ${EFI} -eq 1 ]; then
|
||||
CMDLINE['withefi']=""
|
||||
else
|
||||
CMDLINE['noefi']=""
|
||||
fi
|
||||
|
||||
# DSM Cmdline
|
||||
if [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 5 ]; then
|
||||
if [ "${BUS}" != "usb" ]; then
|
||||
SZ=$(blockdev --getsz ${LOADER_DISK} 2>/dev/null) # SZ=$(cat /sys/block/${LOADER_DISK/\/dev\//}/size)
|
||||
SS=$(blockdev --getss ${LOADER_DISK} 2>/dev/null) # SS=$(cat /sys/block/${LOADER_DISK/\/dev\//}/queue/hw_sector_size)
|
||||
SIZE=$((${SZ:-0} * ${SS:-0} / 1024 / 1024 + 10))
|
||||
# Read SATADoM type
|
||||
SATADOM="$(readConfigKey "satadom" "${USER_CONFIG_FILE}")"
|
||||
CMDLINE['synoboot_satadom']="${SATADOM:-2}"
|
||||
CMDLINE['dom_szmax']="${SIZE}"
|
||||
fi
|
||||
CMDLINE["elevator"]="elevator"
|
||||
else
|
||||
CMDLINE["split_lock_detect"]="off"
|
||||
fi
|
||||
if [ "${DT}" == "true" ]; then
|
||||
CMDLINE["syno_ttyS0"]="serial,0x3f8"
|
||||
CMDLINE["syno_ttyS1"]="serial,0x2f8"
|
||||
else
|
||||
CMDLINE["SMBusHddDynamicPower"]="1"
|
||||
CMDLINE["syno_hdd_detect"]="0"
|
||||
CMDLINE["syno_hdd_powerup_seq"]="0"
|
||||
fi
|
||||
CMDLINE["HddHotplug"]="1"
|
||||
CMDLINE["vender_format_version"]="2"
|
||||
CMDLINE['skip_vender_mac_interfaces']="0,1,2,3,4,5,6,7"
|
||||
|
||||
CMDLINE['earlyprintk']=""
|
||||
CMDLINE['earlycon']="uart8250,io,0x3f8,115200n8"
|
||||
CMDLINE['console']="ttyS0,115200n8"
|
||||
CMDLINE['consoleblank']="600"
|
||||
# CMDLINE['no_console_suspend']="1"
|
||||
CMDLINE['root']="/dev/md0"
|
||||
CMDLINE['rootwait']=""
|
||||
CMDLINE['loglevel']="15"
|
||||
CMDLINE['log_buf_len']="32M"
|
||||
CMDLINE['panic']="${KERNELPANIC:-0}"
|
||||
CMDLINE['pcie_aspm']="off"
|
||||
CMDLINE['modprobe.blacklist']="${MODBLACKLIST}"
|
||||
#[ $(cat /proc/cpuinfo | grep Intel | wc -l) -gt 0 ] && CMDLINE["intel_pstate"]="disable"
|
||||
|
||||
#if [ -n "$(ls /dev/mmcblk* 2>/dev/null)" ] && [ "${BUS}" != "mmc" ] && [ "${EMMCBOOT}" != "true" ]; then
|
||||
# if ! echo "${CMDLINE['modprobe.blacklist']}" | grep -q "sdhci"; then
|
||||
# [ ! "${CMDLINE['modprobe.blacklist']}" == "" ] && CMDLINE['modprobe.blacklist']+=","
|
||||
# CMDLINE['modprobe.blacklist']+="sdhci,sdhci_pci,sdhci_acpi"
|
||||
# fi
|
||||
# fi
|
||||
if [ "${DT}" == "true" ] && ! echo "epyc7002 purley broadwellnkv2" | grep -wq "${PLATFORM}"; then
|
||||
if ! echo "${CMDLINE['modprobe.blacklist']}" | grep -q "mpt3sas"; then
|
||||
[ ! "${CMDLINE['modprobe.blacklist']}" == "" ] && CMDLINE['modprobe.blacklist']+=","
|
||||
CMDLINE['modprobe.blacklist']+="mpt3sas"
|
||||
fi
|
||||
fi
|
||||
# CMDLINE['kvm.ignore_msrs']="1"
|
||||
# CMDLINE['kvm.report_ignored_msrs']="0"
|
||||
if echo "apollolake geminilake" | grep -wq "${PLATFORM}"; then
|
||||
CMDLINE["intel_iommu"]="igfx_off"
|
||||
fi
|
||||
if echo "purley broadwellnkv2" | grep -wq "${PLATFORM}"; then
|
||||
CMDLINE["SASmodel"]="1"
|
||||
fi
|
||||
|
||||
# Cmdline NIC Settings
|
||||
ETHX=$(ip -o link show | awk -F': ' '{print $2}' | grep eth)
|
||||
ETHM=$(readConfigKey "${MODEL}.ports" "${S_FILE}" 2>/dev/null)
|
||||
ETHN=$(echo ${ETHX} | wc -w)
|
||||
[ -z "${ETHM}" ] && ETHM=${ETHN}
|
||||
NIC=0
|
||||
for N in ${ETHX}; do
|
||||
MAC="$(readConfigKey "${N}" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${MAC}" ] && MAC="$(cat /sys/class/net/${N}/address 2>/dev/null | tr '[:lower:]' '[:upper:]')" || NIC=$((${NIC} + 1))
|
||||
[ ${NIC} -le ${ETHM} ] && CMDLINE["mac${NIC}"]="${MAC}"
|
||||
[ ${NIC} -ge ${ETHM} ] && break
|
||||
done
|
||||
CMDLINE['netif_num']="${NIC}"
|
||||
|
||||
# Read user network settings
|
||||
while IFS=': ' read -r KEY VALUE; do
|
||||
[ -n "${KEY}" ] && CMDLINE["network.${KEY}"]="${VALUE}"
|
||||
done < <(readConfigMap "network" "${USER_CONFIG_FILE}")
|
||||
|
||||
# Read user cmdline
|
||||
while IFS=': ' read -r KEY VALUE; do
|
||||
[ -n "${KEY}" ] && CMDLINE["${KEY}"]="${VALUE}"
|
||||
done < <(readConfigMap "cmdline" "${USER_CONFIG_FILE}")
|
||||
|
||||
# Prepare command line
|
||||
CMDLINE_LINE=""
|
||||
for KEY in ${!CMDLINE[@]}; do
|
||||
VALUE="${CMDLINE[${KEY}]}"
|
||||
CMDLINE_LINE+=" ${KEY}"
|
||||
[ -n "${VALUE}" ] && CMDLINE_LINE+="=${VALUE}"
|
||||
done
|
||||
CMDLINE_LINE=$(echo "${CMDLINE_LINE}" | sed 's/^ //') # Remove leading space
|
||||
echo "${CMDLINE_LINE}" >"${PART1_PATH}/cmdline.yml"
|
||||
|
||||
function _bootwait() {
|
||||
# Exec Bootwait to check SSH/Web connection
|
||||
BOOTWAIT=5
|
||||
busybox w 2>/dev/null | awk '{print $1" "$2" "$4" "$5" "$6}' >WB
|
||||
MSG=""
|
||||
while test ${BOOTWAIT} -ge 0; do
|
||||
MSG="\033[1;33mAccess SSH/Web will interrupt boot...\033[0m"
|
||||
echo -en "\r${MSG}"
|
||||
busybox w 2>/dev/null | awk '{print $1" "$2" "$4" "$5" "$6}' >WC
|
||||
if ! diff WB WC >/dev/null 2>&1; then
|
||||
echo -en "\r\033[1;33mAccess SSH/Web detected and boot is interrupted.\033[0m\n"
|
||||
rm -f WB WC
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
BOOTWAIT=$((BOOTWAIT - 1))
|
||||
done
|
||||
rm -f WB WC
|
||||
echo -en "\r$(printf "%$((${#MSG} * 2))s" " ")\n"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Boot
|
||||
DIRECTBOOT="$(readConfigKey "directboot" "${USER_CONFIG_FILE}")"
|
||||
if [ "${DIRECTBOOT}" == "true" ]; then
|
||||
CMDLINE_DIRECT=$(echo ${CMDLINE_LINE} | sed 's/>/\\\\>/g') # Escape special chars
|
||||
grub-editenv ${USER_GRUBENVFILE} set dsm_cmdline="${CMDLINE_DIRECT}"
|
||||
grub-editenv ${USER_GRUBENVFILE} set next_entry="direct"
|
||||
_bootwait || true
|
||||
echo -e "\033[1;34mReboot with Directboot\033[0m"
|
||||
reboot
|
||||
exit 0
|
||||
elif [ "${DIRECTBOOT}" == "false" ]; then
|
||||
grub-editenv ${USER_GRUBENVFILE} unset dsm_cmdline
|
||||
grub-editenv ${USER_GRUBENVFILE} unset next_entry
|
||||
KERNELLOAD="$(readConfigKey "kernelload" "${USER_CONFIG_FILE}")"
|
||||
BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30
|
||||
IPCON=""
|
||||
if [ "${ARCPATCH}" == "true" ]; then
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC\033[0m | \033[1;34mUsing ${NIC} NIC for Arc Patch:\033[0m"
|
||||
else
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m"
|
||||
fi
|
||||
echo
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S41dhcpcd restart >/dev/null 2>&1 || true
|
||||
sleep 3
|
||||
for N in ${ETHX}; do
|
||||
COUNT=0
|
||||
DRIVER=$(ls -ld /sys/class/net/${N}/device/driver 2>/dev/null | awk -F '/' '{print $NF}')
|
||||
while true; do
|
||||
if [ "0" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mNOT CONNECTED\033[0m"
|
||||
break
|
||||
fi
|
||||
COUNT=$((${COUNT} + 1))
|
||||
IP="$(getIP ${N})"
|
||||
if [ -n "${IP}" ]; then
|
||||
SPEED=$(ethtool ${N} 2>/dev/null | grep "Speed:" | awk '{print $2}')
|
||||
if [[ "${IP}" =~ ^169\.254\..* ]]; then
|
||||
echo -e "\r${DRIVER} (${SPEED}): \033[1;37mLINK LOCAL (No DHCP server found.)\033[0m"
|
||||
else
|
||||
echo -e "\r${DRIVER} (${SPEED}): \033[1;37m${IP}\033[0m"
|
||||
[ -z "${IPCON}" ] && IPCON="${IP}"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
if [ -z "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mDOWN\033[0m"
|
||||
break
|
||||
fi
|
||||
if [ ${COUNT} -ge ${BOOTIPWAIT} ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mTIMEOUT\033[0m"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
done
|
||||
_bootwait || true
|
||||
|
||||
DSMLOGO="$(readConfigKey "boot.dsmlogo" "${USER_CONFIG_FILE}")"
|
||||
if [ "${DSMLOGO}" == "true" ] && [ -c "/dev/fb0" ]; then
|
||||
[[ "${IPCON}" =~ ^169\.254\..* ]] && IPCON=""
|
||||
[ -n "${IPCON}" ] && URL="http://${IPCON}:5000" || URL="http://find.synology.com/"
|
||||
python ${ARC_PATH}/include/functions.py makeqr -d "${URL}" -l "6" -o "${TMP_PATH}/qrcode_boot.png"
|
||||
[ -f "${TMP_PATH}/qrcode_boot.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_boot.png" >/dev/null 2>/dev/null || true
|
||||
fi
|
||||
|
||||
for T in $(w 2>/dev/null | grep -v 'TTY' | awk '{print $2}'); do
|
||||
if [ -w "/dev/${T}" ]; then
|
||||
[ -n "${IPCON}" ] && echo -e "Use \033[1;34mhttp://${IPCON}:5000\033[0m or try \033[1;34mhttp://find.synology.com/ \033[0mto find DSM and proceed.\n\n\033[1;37mThis interface will not be operational. Wait a few minutes.\033[0m\n" >"/dev/${T}" 2>/dev/null || echo -e "Try \033[1;34mhttp://find.synology.com/ \033[0mto find DSM and proceed.\n\n\033[1;37mThis interface will not be operational. Wait a few minutes.\nNo IP found.\033[0m\n" >"/dev/${T}" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "\033[1;37mLoading DSM Kernel...\033[0m"
|
||||
# Executes DSM kernel via KEXEC
|
||||
KEXECARGS="-a"
|
||||
if [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 4 ] && [ ${EFI} -eq 1 ]; then
|
||||
echo -e "\033[1;33mWarning, running kexec with --noefi param, strange things will happen!!\033[0m"
|
||||
KEXECARGS+=" --noefi"
|
||||
fi
|
||||
kexec ${KEXECARGS} -l "${MOD_ZIMAGE_FILE}" --initrd "${MOD_RDGZ_FILE}" --command-line="${CMDLINE_LINE}" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
|
||||
echo -e "\033[1;37mBooting DSM...\033[0m"
|
||||
# Boot to DSM
|
||||
[ "${KERNELLOAD}" == "kexec" ] && kexec -e || poweroff
|
||||
exit 0
|
||||
fi
|
||||
BIN
files/initrd/opt/arc/bzImage-template-v4.gz
Executable file
BIN
files/initrd/opt/arc/bzImage-template-v4.gz
Executable file
Binary file not shown.
BIN
files/initrd/opt/arc/bzImage-template-v5.gz
Executable file
BIN
files/initrd/opt/arc/bzImage-template-v5.gz
Executable file
Binary file not shown.
16
files/initrd/opt/arc/bzImage-to-vmlinux.sh
Executable file
16
files/initrd/opt/arc/bzImage-to-vmlinux.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
read_u8() {
|
||||
dd if=$1 bs=1 skip=$(($2)) count=1 2>/dev/null | od -An -tu1 | grep -Eo '[0-9]+'
|
||||
}
|
||||
read_u32() {
|
||||
dd if=$1 bs=1 skip=$(($2)) count=4 2>/dev/null | od -An -tu4 | grep -Eo '[0-9]+'
|
||||
}
|
||||
|
||||
set -x
|
||||
setup_size=$(read_u8 $1 0x1f1)
|
||||
payload_offset=$(read_u32 $1 0x248)
|
||||
payload_length=$(read_u32 $1 0x24c)
|
||||
inner_pos=$((($setup_size + 1) * 512))
|
||||
|
||||
tail -c+$(($inner_pos + 1)) $1 | tail -c+$(($payload_offset + 1)) | head -c $(($payload_length)) | head -c $(($payload_length - 4)) | unlzma >$2
|
||||
42
files/initrd/opt/arc/calc_run_size.sh
Executable file
42
files/initrd/opt/arc/calc_run_size.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Calculate the amount of space needed to run the kernel, including room for
|
||||
# the .bss and .brk sections.
|
||||
#
|
||||
# Usage:
|
||||
# objdump -h a.out | sh calc_run_size.sh
|
||||
|
||||
NUM='\([0-9a-fA-F]*[ \t]*\)'
|
||||
OUT=$(sed -n 's/^[ \t0-9]*.b[sr][sk][ \t]*'"${NUM}${NUM}${NUM}${NUM}"'.*/\1\4/p')
|
||||
if [ -z "$OUT" ]; then
|
||||
echo "Never found .bss or .brk file offset" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUT=$(echo ${OUT# })
|
||||
sizeA=$(printf "%d" 0x${OUT%% *})
|
||||
OUT=${OUT#* }
|
||||
offsetA=$(printf "%d" 0x${OUT%% *})
|
||||
OUT=${OUT#* }
|
||||
sizeB=$(printf "%d" 0x${OUT%% *})
|
||||
OUT=${OUT#* }
|
||||
offsetB=$(printf "%d" 0x${OUT%% *})
|
||||
|
||||
run_size=$((${offsetA} + ${sizeA} + ${sizeB}))
|
||||
|
||||
# BFD linker shows the same file offset in ELF.
|
||||
if [ "${offsetA}" -ne "${offsetB}" ]; then
|
||||
# Gold linker shows them as consecutive.
|
||||
endB=$((${offsetB} + ${sizeB}))
|
||||
if [ "$endB" != "$run_size" ]; then
|
||||
printf "sizeA: 0x%x\n" ${sizeA} >&2
|
||||
printf "offsetA: 0x%x\n" ${offsetA} >&2
|
||||
printf "sizeB: 0x%x\n" ${sizeB} >&2
|
||||
printf "offsetB: 0x%x\n" ${offsetB} >&2
|
||||
echo ".bss and .brk are non-contiguous" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "%d\n" ${run_size}
|
||||
exit 0
|
||||
64
files/initrd/opt/arc/extract-vmlinux
Executable file
64
files/initrd/opt/arc/extract-vmlinux
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# ----------------------------------------------------------------------
|
||||
# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
|
||||
#
|
||||
# Inspired from extract-ikconfig
|
||||
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
|
||||
#
|
||||
# (c) 2011 Corentin Chary <corentin.chary@gmail.com>
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
check_vmlinux()
|
||||
{
|
||||
# Use readelf to check if it's a valid ELF
|
||||
# TODO: find a better to way to check that it's really vmlinux
|
||||
# and not just an elf
|
||||
readelf -h $1 > /dev/null 2>&1 || return 1
|
||||
|
||||
cat $1
|
||||
exit 0
|
||||
}
|
||||
|
||||
try_decompress()
|
||||
{
|
||||
# The obscure use of the "tr" filter is to work around older versions of
|
||||
# "grep" that report the byte offset of the line instead of the pattern.
|
||||
|
||||
# Try to find the header ($1) and decompress from here
|
||||
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
|
||||
do
|
||||
pos=${pos%%:*}
|
||||
tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
|
||||
check_vmlinux $tmp
|
||||
done
|
||||
}
|
||||
|
||||
# Check invocation:
|
||||
me=${0##*/}
|
||||
img=$1
|
||||
if [ $# -ne 1 -o ! -s "$img" ]
|
||||
then
|
||||
echo "Usage: $me <kernel-image>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Prepare temp files:
|
||||
tmp=$(mktemp /tmp/vmlinux-XXX)
|
||||
trap "rm -f $tmp" 0
|
||||
|
||||
# That didn't work, so retry after decompression.
|
||||
try_decompress '\037\213\010' xy gunzip
|
||||
try_decompress '\3757zXZ\000' abcde unxz
|
||||
try_decompress 'BZh' xy bunzip2
|
||||
try_decompress '\135\0\0\0' xxx unlzma
|
||||
try_decompress '\211\114\132' xy 'lzop -d'
|
||||
try_decompress '\002!L\030' xxx 'lz4 -d'
|
||||
try_decompress '(\265/\375' xxx unzstd
|
||||
|
||||
# Finally check for uncompressed images or objects:
|
||||
check_vmlinux $img
|
||||
|
||||
# Bail out:
|
||||
echo "$me: Cannot find vmlinux." >&2
|
||||
BIN
files/initrd/opt/arc/grub.img.gz
Normal file
BIN
files/initrd/opt/arc/grub.img.gz
Normal file
Binary file not shown.
109
files/initrd/opt/arc/include/addons.sh
Executable file
109
files/initrd/opt/arc/include/addons.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
###############################################################################
|
||||
# Return list of available addons
|
||||
# 1 - Platform
|
||||
function availableAddons() {
|
||||
if [ -z "${1}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
local ARCOFFLINE="$(readConfigKey "arc.offline" "${USER_CONFIG_FILE}")"
|
||||
local ARCCONF="$(readConfigKey "${MODEL}.serial" "${S_FILE}")"
|
||||
for D in $(find "${ADDONS_PATH}" -maxdepth 1 -type d 2>/dev/null | sort); do
|
||||
[ ! -f "${D}/manifest.yml" ] && continue
|
||||
local ADDON=$(basename ${D})
|
||||
local AVAILABLE="$(readConfigKey "${1}" "${D}/manifest.yml")"
|
||||
[ "${AVAILABLE}" = false ] && continue
|
||||
local SYSTEM=$(readConfigKey "system" "${D}/manifest.yml")
|
||||
[ "${SYSTEM}" = true ] && continue
|
||||
if [[ "${ARCOFFLINE}" == "true" || -z "${ARCCONF}" ]] && [[ "${ADDON}" == "amepatch" || "${ADDON}" == "arcdns" ]]; then
|
||||
continue
|
||||
fi
|
||||
if [ "${MACHINE}" != "Native" ] && [ "${ADDON}" == "cpufreqscaling" ]; then
|
||||
continue
|
||||
fi
|
||||
local DESC="$(readConfigKey "description" "${D}/manifest.yml")"
|
||||
local BETA="$(readConfigKey "beta" "${D}/manifest.yml")"
|
||||
local TARGET="$(readConfigKey "target" "${D}/manifest.yml")"
|
||||
[ "${BETA}" = true ] && BETA="(Beta) " || BETA=""
|
||||
if [ "${TARGET}" == "app" ]; then
|
||||
[ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t\Z4${BETA}${DESC}\Zn"
|
||||
elif [ "${TARGET}" == "system" ]; then
|
||||
[ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t\Z1${BETA}${DESC}\Zn"
|
||||
else
|
||||
[ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t${BETA}${DESC}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check if addon exist
|
||||
# 1 - Addon id
|
||||
# 2 - Platform
|
||||
# Return ERROR if not exists
|
||||
function checkAddonExist() {
|
||||
if [ -z "${1}" ] || [ -z "${2}" ]; then
|
||||
return 1 # ERROR
|
||||
fi
|
||||
# First check generic files
|
||||
if [ -f "${ADDONS_PATH}/${1}/all.tgz" ]; then
|
||||
return 0 # OK
|
||||
fi
|
||||
return 1 # ERROR
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Install Addon into ramdisk image
|
||||
# 1 - Addon id
|
||||
# Return ERROR if not installed
|
||||
function installAddon() {
|
||||
if [ -z "${1}" ]; then
|
||||
return 1
|
||||
fi
|
||||
local ADDON="${1}"
|
||||
mkdir -p "${TMP_PATH}/${ADDON}"
|
||||
local HAS_FILES=0
|
||||
# First check generic files
|
||||
if [ -f "${ADDONS_PATH}/${ADDON}/all.tgz" ]; then
|
||||
tar -zxf "${ADDONS_PATH}/${ADDON}/all.tgz" -C "${TMP_PATH}/${ADDON}"
|
||||
HAS_FILES=1
|
||||
fi
|
||||
# If has files to copy, copy it, else return error
|
||||
[ ${HAS_FILES} -ne 1 ] && return 1
|
||||
cp -f "${TMP_PATH}/${ADDON}/install.sh" "${RAMDISK_PATH}/addons/${ADDON}.sh" 2>"${LOG_FILE}"
|
||||
chmod +x "${RAMDISK_PATH}/addons/${ADDON}.sh"
|
||||
[ -d ${TMP_PATH}/${ADDON}/root ] && (cp -rnf "${TMP_PATH}/${ADDON}/root/"* "${RAMDISK_PATH}/" 2>"${LOG_FILE}")
|
||||
rm -rf "${TMP_PATH}/${ADDON}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Untar an addon to correct path
|
||||
# 1 - Addon file path
|
||||
# Return name of addon on sucess or empty on error
|
||||
function untarAddon() {
|
||||
if [ -z "${1}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
rm -rf "${TMP_PATH}/addon"
|
||||
mkdir -p "${TMP_PATH}/addon"
|
||||
tar -xaf "${1}" -C "${TMP_PATH}/addon" || return
|
||||
local ADDON=$(readConfigKey "name" "${TMP_PATH}/addon/manifest.yml")
|
||||
[ -z "${ADDON}" ] && return
|
||||
rm -rf "${ADDONS_PATH}/${ADDON}"
|
||||
mv -f "${TMP_PATH}/addon" "${ADDONS_PATH}/${ADDON}"
|
||||
echo "${ADDON}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Detect if has new local plugins to install/reinstall
|
||||
function updateAddon() {
|
||||
for F in $(ls ${ADDONS_PATH}/*.addon 2>/dev/null); do
|
||||
local ADDON=$(basename "${F}" | sed 's|.addon||')
|
||||
rm -rf "${ADDONS_PATH}/${ADDON}"
|
||||
mkdir -p "${ADDONS_PATH}/${ADDON}"
|
||||
echo "Installing ${F} to ${ADDONS_PATH}/${ADDON}"
|
||||
tar -xaf "${F}" -C "${ADDONS_PATH}/${ADDON}"
|
||||
rm -f "${F}"
|
||||
done
|
||||
}
|
||||
1
files/initrd/opt/arc/include/compat.sh
Executable file
1
files/initrd/opt/arc/include/compat.sh
Executable file
@@ -0,0 +1 @@
|
||||
###############################################################################
|
||||
71
files/initrd/opt/arc/include/configFile.sh
Executable file
71
files/initrd/opt/arc/include/configFile.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
|
||||
###############################################################################
|
||||
# Delete a key in config file
|
||||
# 1 - Path of Key
|
||||
# 2 - Path of yaml config file
|
||||
function deleteConfigKey() {
|
||||
yq eval 'del(.'${1}')' --inplace "${2}" 2>/dev/null
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Write to yaml config file
|
||||
# 1 - Path of Key
|
||||
# 2 - Value
|
||||
# 3 - Path of yaml config file
|
||||
function writeConfigKey() {
|
||||
[ "${2}" = "{}" ] && yq eval '.'${1}' = {}' --inplace "${3}" 2>/dev/null || yq eval '.'${1}' = "'"${2}"'"' --inplace "${3}" 2>/dev/null
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Read key value from yaml config file
|
||||
# 1 - Path of key
|
||||
# 2 - Path of yaml config file
|
||||
# Return Value
|
||||
function readConfigKey() {
|
||||
RESULT=$(yq eval '.'${1}' | explode(.)' "${2}" 2>/dev/null)
|
||||
[ "${RESULT}" == "null" ] && echo "" || echo "${RESULT}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Write to yaml config file if key not exists
|
||||
# 1 - Path of Key
|
||||
# 2 - Value
|
||||
# 3 - Path of yaml config file
|
||||
function initConfigKey() {
|
||||
[ -z "$(readConfigKey "${1}" "${3}")" ] && writeConfigKey "${1}" "${2}" "${3}" || true
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Read Entries as map(key=value) from yaml config file
|
||||
# 1 - Path of key
|
||||
# 2 - Path of yaml config file
|
||||
# Returns map of values
|
||||
function readConfigMap() {
|
||||
yq eval '.'${1}' | explode(.) | to_entries | map([.key, .value] | join(": ")) | .[]' "${2}" 2>/dev/null
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Read an array from yaml config file
|
||||
# 1 - Path of key
|
||||
# 2 - Path of yaml config file
|
||||
# Returns array/map of values
|
||||
function readConfigArray() {
|
||||
yq eval '.'${1}'[]' "${2}" 2>/dev/null
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Read Entries as array from yaml config file
|
||||
# 1 - Path of key
|
||||
# 2 - Path of yaml config file
|
||||
# Returns array of values
|
||||
function readConfigEntriesArray() {
|
||||
yq eval '.'${1}' | explode(.) | to_entries | map([.key])[] | .[]' "${2}" 2>/dev/null
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check yaml config file
|
||||
# 1 - Path of yaml config file
|
||||
# Returns error information
|
||||
function checkConfigFile() {
|
||||
yq eval "${1}" 2>&1
|
||||
}
|
||||
50
files/initrd/opt/arc/include/consts.sh
Executable file
50
files/initrd/opt/arc/include/consts.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
# Define paths
|
||||
PART1_PATH="/mnt/p1"
|
||||
PART2_PATH="/mnt/p2"
|
||||
PART3_PATH="/mnt/p3"
|
||||
TMP_PATH="/tmp"
|
||||
|
||||
[ -f "${PART1_PATH}/ARC-BRANCH" ] && ARC_BRANCH=$(cat "${PART1_PATH}/ARC-BRANCH") || ARC_BRANCH="null"
|
||||
[ -f "${PART1_PATH}/ARC-VERSION" ] && ARC_VERSION=$(cat "${PART1_PATH}/ARC-VERSION") || ARC_VERSION="null"
|
||||
[ -f "${PART1_PATH}/ARC-BUILD" ] && ARC_BUILD=$(cat "${PART1_PATH}/ARC-BUILD") || ARC_BUILD="null"
|
||||
ARC_TITLE="Arc ${ARC_VERSION}"
|
||||
|
||||
RAMDISK_PATH="${TMP_PATH}/ramdisk"
|
||||
LOG_FILE="${TMP_PATH}/log.txt"
|
||||
TMP_UP_PATH="${TMP_PATH}/upload"
|
||||
|
||||
USER_GRUB_CONFIG="${PART1_PATH}/boot/grub/grub.cfg"
|
||||
USER_GRUBENVFILE="${PART1_PATH}/boot/grub/grubenv"
|
||||
USER_CONFIG_FILE="${PART1_PATH}/user-config.yml"
|
||||
GRUB_PATH="${PART1_PATH}/boot/grub"
|
||||
|
||||
ORI_ZIMAGE_FILE="${PART2_PATH}/zImage"
|
||||
ORI_RDGZ_FILE="${PART2_PATH}/rd.gz"
|
||||
ARC_BZIMAGE_FILE="${PART3_PATH}/bzImage-arc"
|
||||
ARC_RAMDISK_FILE="${PART3_PATH}/initrd-arc"
|
||||
ARC_RAMDISK_USER_FILE="${PART3_PATH}/initrd-user"
|
||||
MOD_ZIMAGE_FILE="${PART3_PATH}/zImage-dsm"
|
||||
MOD_RDGZ_FILE="${PART3_PATH}/initrd-dsm"
|
||||
|
||||
ADDONS_PATH="${PART3_PATH}/addons"
|
||||
MODULES_PATH="${PART3_PATH}/modules"
|
||||
MODEL_CONFIG_PATH="${PART3_PATH}/configs"
|
||||
PATCH_PATH="${PART3_PATH}/patches"
|
||||
LKMS_PATH="${PART3_PATH}/lkms"
|
||||
CUSTOM_PATH="${PART3_PATH}/custom"
|
||||
USER_UP_PATH="${PART3_PATH}/users"
|
||||
UNTAR_PAT_PATH="${PART3_PATH}/DSM"
|
||||
|
||||
S_FILE="${MODEL_CONFIG_PATH}/serials.yml"
|
||||
P_FILE="${MODEL_CONFIG_PATH}/platforms.yml"
|
||||
D_FILE="${MODEL_CONFIG_PATH}/data.yml"
|
||||
|
||||
EXTRACTOR_PATH="${PART3_PATH}/extractor"
|
||||
EXTRACTOR_BIN="syno_extract_system_patch"
|
||||
|
||||
HTTPPORT=$(grep -i '^HTTP_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2)
|
||||
[ -z "${HTTPPORT}" ] && HTTPPORT=7080 || true
|
||||
DUFSPORT=$(grep -i '^DUFS_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2)
|
||||
[ -z "${DUFSPORT}" ] && DUFSPORT=7304 || true
|
||||
TTYDPORT=$(grep -i '^TTYD_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2)
|
||||
[ -z "${TTYDPORT}" ] && TTYDPORT=7681 || true
|
||||
112
files/initrd/opt/arc/include/functions.py
Executable file
112
files/initrd/opt/arc/include/functions.py
Executable file
@@ -0,0 +1,112 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium> and Ing <https://github.com/wjz304>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
import os, click
|
||||
|
||||
WORK_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
"""
|
||||
The CLI is a commands to Arc.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def mutually_exclusive_options(ctx, param, value):
|
||||
other_option = "file" if param.name == "data" else "data"
|
||||
if value is not None and ctx.params.get(other_option) is not None:
|
||||
raise click.UsageError(f"Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_required_param(ctx, param, value):
|
||||
if not value and "file" not in ctx.params and "data" not in ctx.params:
|
||||
raise click.MissingParameter(param_decls=[param.name])
|
||||
return value
|
||||
|
||||
def __fullversion(ver):
|
||||
out = ver
|
||||
arr = ver.split('-')
|
||||
if len(arr) > 0:
|
||||
a = arr[0].split('.')[0] if len(arr[0].split('.')) > 0 else '0'
|
||||
b = arr[0].split('.')[1] if len(arr[0].split('.')) > 1 else '0'
|
||||
c = arr[0].split('.')[2] if len(arr[0].split('.')) > 2 else '0'
|
||||
d = arr[1] if len(arr) > 1 else '00000'
|
||||
e = arr[2] if len(arr) > 2 else '0'
|
||||
out = '{}.{}.{}-{}-{}'.format(a,b,c,d,e)
|
||||
return out
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-d", "--data", type=str, callback=mutually_exclusive_options, is_eager=True, help="The data of QRCode.")
|
||||
@click.option("-f", "--file", type=str, callback=mutually_exclusive_options, is_eager=True, help="The file of QRCode.")
|
||||
@click.option("--validate", is_flag=True, callback=validate_required_param, expose_value=False, is_eager=True)
|
||||
@click.option("-l", "--location", type=click.IntRange(0, 7), required=True, help="The location of QRCode. (range 0<=x<=7)")
|
||||
@click.option("-o", "--output", type=str, required=True, help="The output file of QRCode.")
|
||||
def makeqr(data, file, location, output):
|
||||
"""
|
||||
Generate a QRCode.
|
||||
"""
|
||||
try:
|
||||
import fcntl, struct
|
||||
import qrcode
|
||||
from PIL import Image
|
||||
|
||||
FBIOGET_VSCREENINFO = 0x4600
|
||||
FBIOPUT_VSCREENINFO = 0x4601
|
||||
FBIOGET_FSCREENINFO = 0x4602
|
||||
FBDEV = "/dev/fb0"
|
||||
if data is not None:
|
||||
qr = qrcode.QRCode(version=1, box_size=10, error_correction=qrcode.constants.ERROR_CORRECT_H, border=4,)
|
||||
qr.add_data(data)
|
||||
qr.make(fit=True)
|
||||
img = qr.make_image(fill_color="grey", back_color="black")
|
||||
img = img.convert("RGBA")
|
||||
pixels = img.load()
|
||||
for i in range(img.size[0]):
|
||||
for j in range(img.size[1]):
|
||||
if pixels[i, j] == (255, 255, 255, 255):
|
||||
pixels[i, j] = (255, 255, 255, 0)
|
||||
|
||||
if os.path.exists(os.path.join(WORK_PATH, "logo.png")):
|
||||
icon = Image.open(os.path.join(WORK_PATH, "logo.png"))
|
||||
icon = icon.convert("RGBA")
|
||||
img.paste(icon.resize((int(img.size[0] / 5), int(img.size[1] / 5))), (int((img.size[0] - int(img.size[0] / 5)) / 2), int((img.size[1] - int(img.size[1] / 5)) / 2),),)
|
||||
|
||||
if file is not None:
|
||||
img = Image.open(file)
|
||||
# img = img.convert("RGBA")
|
||||
# pixels = img.load()
|
||||
# for i in range(img.size[0]):
|
||||
# for j in range(img.size[1]):
|
||||
# if pixels[i, j] == (255, 255, 255, 255):
|
||||
# pixels[i, j] = (255, 255, 255, 0)
|
||||
|
||||
(xres, yres) = (1920, 1080)
|
||||
with open(FBDEV, "rb") as fb:
|
||||
vi = fcntl.ioctl(fb, FBIOGET_VSCREENINFO, bytes(160))
|
||||
res = struct.unpack("I" * 40, vi)
|
||||
if res[0] != 0 and res[1] != 0:
|
||||
(xres, yres) = (res[0], res[1])
|
||||
xqr, yqr = (int(xres / 8), int(xres / 8))
|
||||
img = img.resize((xqr, yqr))
|
||||
|
||||
alpha = Image.new("RGBA", (xres, yres), (0, 0, 0, 0))
|
||||
if int(location) not in range(0, 8):
|
||||
location = 0
|
||||
loc = (img.size[0] * int(location), alpha.size[1] - img.size[1])
|
||||
alpha.paste(img, loc)
|
||||
alpha.save(output)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
583
files/initrd/opt/arc/include/functions.sh
Executable file
583
files/initrd/opt/arc/include/functions.sh
Executable file
@@ -0,0 +1,583 @@
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/consts.sh
|
||||
. ${ARC_PATH}/include/configFile.sh
|
||||
. ${ARC_PATH}/include/addons.sh
|
||||
|
||||
###############################################################################
|
||||
# Check loader disk
|
||||
function checkBootLoader() {
|
||||
while read KNAME RO; do
|
||||
[ -z "${KNAME}" ] && continue
|
||||
[ "${RO}" == "0" ] && continue
|
||||
hdparm -r0 "${KNAME}" >/dev/null 2>&1 || true
|
||||
done <<<$(lsblk -pno KNAME,RO 2>/dev/null)
|
||||
[ ! -w "${PART1_PATH}" ] && return 1
|
||||
[ ! -w "${PART2_PATH}" ] && return 1
|
||||
[ ! -w "${PART3_PATH}" ] && return 1
|
||||
command -v awk >/dev/null 2>&1 || return 1
|
||||
command -v cut >/dev/null 2>&1 || return 1
|
||||
command -v sed >/dev/null 2>&1 || return 1
|
||||
command -v tar >/dev/null 2>&1 || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Just show error message and dies
|
||||
function die() {
|
||||
echo -e "\033[1;41m$@\033[0m"
|
||||
exit 1
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Show error message with log content and dies
|
||||
function dieLog() {
|
||||
echo -en "\n\033[1;41mUNRECOVERY ERROR: "
|
||||
cat "${LOG_FILE}"
|
||||
echo -e "\033[0m"
|
||||
sleep 3
|
||||
exit 1
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check if a item exists into array
|
||||
# 1 - Item
|
||||
# 2.. - Array
|
||||
# Return 0 if exists
|
||||
function arrayExistItem() {
|
||||
EXISTS=1
|
||||
ITEM="${1}"
|
||||
shift
|
||||
for i in "$@"; do
|
||||
[ "${i}" == "${ITEM}" ] || continue
|
||||
EXISTS=0
|
||||
break
|
||||
done
|
||||
return ${EXISTS}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a number with 6 digits from 1 to 30000
|
||||
function random() {
|
||||
printf "%06d" $((${RANDOM} % 30000 + 1))
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a hexa number from 0x00 to 0xFF
|
||||
function randomhex() {
|
||||
printf "&02X" "$((${RANDOM} % 255 + 1))"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a random letter
|
||||
function genRandomLetter() {
|
||||
for i in A B C D E F G H J K L M N P Q R S T V W X Y Z; do
|
||||
echo ${i}
|
||||
done | sort -R | tail -1
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a random digit (0-9A-Z)
|
||||
function genRandomValue() {
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R S T V W X Y Z; do
|
||||
echo ${i}
|
||||
done | sort -R | tail -1
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a random serial number for a model
|
||||
# 1 - Model
|
||||
# 2 - Arc
|
||||
# Returns serial number
|
||||
function generateSerial() {
|
||||
PREFIX="$(readConfigArray "${1}.prefix" "${S_FILE}" 2>/dev/null | sort -R | tail -1)"
|
||||
MIDDLE="$(readConfigArray "${1}.middle" "${S_FILE}" 2>/dev/null | sort -R | tail -1)"
|
||||
if [ "${2}" == "true" ]; then
|
||||
SUFFIX="arc"
|
||||
else
|
||||
SUFFIX="$(readConfigKey "${1}.suffix" "${S_FILE}" 2>/dev/null)"
|
||||
fi
|
||||
|
||||
local SERIAL="${PREFIX:-"0000"}${MIDDLE:-"XXX"}"
|
||||
case "${SUFFIX:-"alpha"}" in
|
||||
numeric)
|
||||
SERIAL+="$(random)"
|
||||
;;
|
||||
alpha)
|
||||
SERIAL+="$(genRandomLetter)$(genRandomValue)$(genRandomValue)$(genRandomValue)$(genRandomValue)$(genRandomValue)"
|
||||
;;
|
||||
arc)
|
||||
SERIAL+="$(readConfigKey "${1}.serial" "${S_FILE}" 2>/dev/null)"
|
||||
;;
|
||||
esac
|
||||
|
||||
SERIAL="$(echo "${SERIAL}" | tr '[:lower:]' '[:upper:]')"
|
||||
echo "${SERIAL}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate a MAC address for a model
|
||||
# 1 - Model
|
||||
# 2 - Amount of MACs to generate
|
||||
# 3 - Arc MAC
|
||||
# Returns serial number
|
||||
function generateMacAddress() {
|
||||
MACPRE="$(readConfigKey "${1}.macpre" "${S_FILE}")"
|
||||
if [ "${3}" == "true" ]; then
|
||||
MACSUF="$(readConfigKey "${1}.mac" "${S_FILE}" 2>/dev/null)"
|
||||
else
|
||||
MACSUF="$(printf '%02x%02x%02x' $((${RANDOM} % 256)) $((${RANDOM} % 256)) $((${RANDOM} % 256)))"
|
||||
fi
|
||||
NUM=${2:-1}
|
||||
local MACS=""
|
||||
for I in $(seq 1 ${NUM}); do
|
||||
MACS+="$(printf '%06x%06x' $((0x${MACPRE:-"001132"})) $(($((0x${MACSUF})) + ${I})))"
|
||||
[ ${I} -lt ${NUM} ] && MACS+=" "
|
||||
done
|
||||
|
||||
MACS="$(echo "${MACS}" | tr '[:lower:]' '[:upper:]')"
|
||||
echo "${MACS}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Validate a serial number for a model
|
||||
# 1 - Model
|
||||
# 2 - Serial number to test
|
||||
# Returns 1 if serial number is invalid
|
||||
function validateSerial() {
|
||||
PREFIX="$(readConfigArray "${1}.prefix" "${S_FILE}" 2>/dev/null)"
|
||||
MIDDLE="$(readConfigArray "${1}.middle" "${S_FILE}" 2>/dev/null)"
|
||||
SUFFIX="$(readConfigKey "${1}.suffix" "${S_FILE}" 2>/dev/null)"
|
||||
P=${2:0:4}
|
||||
M=${2:4:3}
|
||||
S=${2:7}
|
||||
L=${#2}
|
||||
if [ ${L} -ne 13 ]; then
|
||||
return 1
|
||||
fi
|
||||
if ! arrayExistItem ${P} ${PREFIX}; then
|
||||
return 1
|
||||
fi
|
||||
if ! arrayExistItem ${M} ${MIDDLE}; then
|
||||
return 1
|
||||
fi
|
||||
case "${SUFFIX:-"alpha"}" in
|
||||
numeric)
|
||||
if ! echo "${S}" | grep -q "^[0-9]\{6\}$"; then
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
alpha)
|
||||
if ! echo "${S}" | grep -q "^[A-Z][0-9][0-9][0-9][0-9][A-Z]$"; then
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check if a item exists into array
|
||||
# 1 - Item
|
||||
# 2.. - Array
|
||||
# Return 0 if exists
|
||||
function arrayExistItem() {
|
||||
EXISTS=1
|
||||
ITEM="${1}"
|
||||
shift
|
||||
for i in "$@"; do
|
||||
[ "${i}" == "${ITEM}" ] || continue
|
||||
EXISTS=0
|
||||
break
|
||||
done
|
||||
return ${EXISTS}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Get values in .conf K=V file
|
||||
# 1 - key
|
||||
# 2 - file
|
||||
function _get_conf_kv() {
|
||||
grep "${1}" "${2}" | sed "s|^${1}=\"\(.*\)\"$|\1|g"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Replace/remove/add values in .conf K=V file
|
||||
# 1 - name
|
||||
# 2 - new_val
|
||||
# 3 - path
|
||||
function _set_conf_kv() {
|
||||
# Delete
|
||||
if [ -z "${2}" ]; then
|
||||
sed -i "${3}" -e "s/^${1}=.*$//"
|
||||
return $?;
|
||||
fi
|
||||
|
||||
# Replace
|
||||
if grep -q "^${1}=" "${3}"; then
|
||||
sed -i "${3}" -e "s\"^${1}=.*\"${1}=\\\"${2}\\\"\""
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Add if doesn't exist
|
||||
echo "${1}=\"${2}\"" >>"${3}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# sort netif busid
|
||||
function _sort_netif() {
|
||||
local ETHLIST=""
|
||||
local ETHX=$(ip -o link show | awk -F': ' '{print $2}' | grep eth)
|
||||
for N in ${ETHX}; do
|
||||
local MAC="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g; s/.*/\L&/')"
|
||||
local BUS="$(ethtool -i ${N} 2>/dev/null | grep bus-info | cut -d' ' -f2)"
|
||||
ETHLIST="${ETHLIST}${BUS} ${MAC} ${N}\n"
|
||||
done
|
||||
local ETHLISTTMPB="$(echo -e "${ETHLIST}" | sort)"
|
||||
local ETHLIST="$(echo -e "${ETHLISTTMPB}" | grep -v '^$')"
|
||||
local ETHSEQ="$(echo -e "${ETHLIST}" | awk '{print $3}' | sed 's/eth//g')"
|
||||
local ETHNUM="$(echo -e "${ETHLIST}" | wc -l)"
|
||||
|
||||
# sort
|
||||
if [ ! "${ETHSEQ}" = "$(seq 0 $((${ETHNUM:0} - 1)))" ]; then
|
||||
/etc/init.d/S41dhcpcd stop >/dev/null 2>&1
|
||||
/etc/init.d/S40network stop >/dev/null 2>&1
|
||||
for i in $(seq 0 $((${ETHNUM:0} - 1))); do
|
||||
ip link set dev eth${i} name tmp${i}
|
||||
done
|
||||
I=0
|
||||
for i in ${ETHSEQ}; do
|
||||
ip link set dev tmp${i} name eth${I}
|
||||
I=$((${I} + 1))
|
||||
done
|
||||
/etc/init.d/S40network start >/dev/null 2>&1
|
||||
/etc/init.d/S41dhcpcd start >/dev/null 2>&1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get bus of disk
|
||||
# 1 - device path
|
||||
function getBus() {
|
||||
local BUS=""
|
||||
# usb/ata(ide)/sata/sas/spi(scsi)/virtio/mmc/nvme
|
||||
[ -z "${BUS}" ] && BUS=$(lsblk -dpno KNAME,TRAN 2>/dev/null | grep "${1} " | awk '{print $2}' | sed 's/^ata$/ide/' | sed 's/^spi$/scsi/') #Spaces are intentional
|
||||
# usb/scsi(ide/sata/sas)/virtio/mmc/nvme/vmbus/xen(xvd)
|
||||
[ -z "${BUS}" ] && BUS=$(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep "${1} " | awk '{print $2}' | awk -F':' '{print $(NF-1)}' | sed 's/_host//' | sed 's/^.*xen.*$/xen/') # Spaces are intentional
|
||||
[ -z "${BUS}" ] && BUS="unknown"
|
||||
echo "${BUS}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get IP
|
||||
# 1 - ethN
|
||||
function getIP() {
|
||||
local IP=""
|
||||
MACR="$(cat /sys/class/net/${1}/address 2>/dev/null | sed 's/://g' | tr '[:lower:]' '[:upper:]')"
|
||||
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
|
||||
if [ -n "${IPR}" ]; then
|
||||
IFS='/' read -r -a IPRA <<<"${IPR}"
|
||||
IP=${IPRA[0]}
|
||||
else
|
||||
if [ -n "${1}" ] && [ -d "/sys/class/net/${1}" ]; then
|
||||
IP=$(ip route show dev ${1} 2>/dev/null | sed -n 's/.* via .* src \(.*\) metric .*/\1/p')
|
||||
[ -z "${IP}" ] && IP=$(ip addr show ${1} scope global 2>/dev/null | grep -E "inet .* eth" | awk '{print $2}' | cut -f1 -d'/' | head -1)
|
||||
else
|
||||
IP=$(ip route show 2>/dev/null | sed -n 's/.* via .* src \(.*\) metric .*/\1/p' | head -1)
|
||||
[ -z "${IP}" ] && IP=$(ip addr show scope global 2>/dev/null | grep -E "inet .* eth" | awk '{print $2}' | cut -f1 -d'/' | head -1)
|
||||
fi
|
||||
fi
|
||||
echo "${IP}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get logo of model
|
||||
# 1 - model
|
||||
function getLogo() {
|
||||
local MODEL="${1}"
|
||||
rm -f "${PART3_PATH}/logo.png"
|
||||
STATUS=$(curl -skL -m 10 -w "%{http_code}" "https://www.synology.com/api/products/getPhoto?product=${MODEL/+/%2B}&type=img_s&sort=0" -o "${PART3_PATH}/logo.png")
|
||||
if [ $? -ne 0 -o ${STATUS:-0} -ne 200 -o ! -f "${PART3_PATH}/logo.png" ]; then
|
||||
rm -f "${PART3_PATH}/logo.png"
|
||||
return 1
|
||||
fi
|
||||
convert -rotate 180 "${PART3_PATH}/logo.png" "${PART3_PATH}/logo.png" 2>/dev/null
|
||||
magick montage "${PART3_PATH}/logo.png" -background 'none' -tile '3x3' -geometry '350x210' "${PART3_PATH}/logo.png" 2>/dev/null
|
||||
convert -rotate 180 "${PART3_PATH}/logo.png" "${PART3_PATH}/logo.png" 2>/dev/null
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Find and mount the DSM root filesystem
|
||||
function findDSMRoot() {
|
||||
local DSMROOTS=""
|
||||
[ -z "${DSMROOTS}" ] && DSMROOTS="$(mdadm --detail --scan 2>/dev/null | grep -E "name=SynologyNAS:0|name=DiskStation:0|name=SynologyNVR:0|name=BeeStation:0" | awk '{print $2}' | uniq)"
|
||||
[ -z "${DSMROOTS}" ] && DSMROOTS="$(lsblk -pno KNAME,PARTN,FSTYPE,FSVER,LABEL | grep -E "sd[a-z]{1,2}1" | grep -w "linux_raid_member" | grep "0.9" | awk '{print $1}')"
|
||||
echo "${DSMROOTS}"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Convert Netmask eq. 255.255.255.0 to /24
|
||||
# 1 - Netmask
|
||||
function convert_netmask() {
|
||||
bits=0
|
||||
for octet in $(echo $1| sed 's/\./ /g'); do
|
||||
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
|
||||
bits=$((${bits} + ${#binbits}))
|
||||
done
|
||||
echo "${bits}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# check Cmdline
|
||||
# 1 - key name
|
||||
# 2 - key string
|
||||
function checkCmdline() {
|
||||
return $(grub-editenv ${USER_GRUBENVFILE} list 2>/dev/null | grep "^${1}=" | cut -d'=' -f2- | grep -q "${2}")
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get logo of model
|
||||
# 1 - key name
|
||||
# 2 - key string
|
||||
function setCmdline() {
|
||||
[ -z "${1}" ] && return 1
|
||||
if [ -n "${2}" ]; then
|
||||
grub-editenv ${USER_GRUBENVFILE} set "${1}=${2}"
|
||||
else
|
||||
grub-editenv ${USER_GRUBENVFILE} unset "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get logo of model
|
||||
# check Cmdline
|
||||
# 1 - key name
|
||||
# 2 - key string
|
||||
function addCmdline() {
|
||||
local CMDLINE="$(grub-editenv ${USER_GRUBENVFILE} list 2>/dev/null | grep "^${1}=" | cut -d'=' -f2-)"
|
||||
[ -n "${CMDLINE}" ] && CMDLINE="${CMDLINE} ${2}" || CMDLINE="${2}"
|
||||
setCmdline "${1}" "${CMDLINE}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get logo of model
|
||||
# 1 - model
|
||||
function delCmdline() {
|
||||
local CMDLINE="$(grub-editenv ${USER_GRUBENVFILE} list 2>/dev/null | grep "^${1}=" | cut -d'=' -f2-)"
|
||||
CMDLINE="$(echo "${CMDLINE}" | sed "s/ *${2}//; s/^[[:space:]]*//;s/[[:space:]]*$//")"
|
||||
setCmdline "${1}" "${CMDLINE}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Rebooting
|
||||
# (based on pocopico's TCRP code)
|
||||
function rebootTo() {
|
||||
local MODES="config recovery junior automated update bios memtest"
|
||||
[ -z "${1}" ] && exit 1
|
||||
if ! echo "${MODES}" | grep -qw "${1}"; then exit 1; fi
|
||||
[ "${1}" == "automated" ] && echo "arc-${MODEL}-${PRODUCTVER}-${ARC_VERSION}" >"${PART3_PATH}/automated"
|
||||
[ ! -f "${USER_GRUBENVFILE}" ] && grub-editenv ${USER_GRUBENVFILE} create
|
||||
# echo -e "Rebooting to ${1} mode..."
|
||||
grub-editenv ${USER_GRUBENVFILE} set next_entry="${1}"
|
||||
exec reboot
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Copy DSM files to the boot partition
|
||||
# 1 - DSM root path
|
||||
function copyDSMFiles() {
|
||||
if [ -f "${1}/grub_cksum.syno" ] && [ -f "${1}/GRUB_VER" ] && [ -f "${1}/zImage" ] && [ -f "${1}/rd.gz" ]; then
|
||||
rm -f "${PART1_PATH}/grub_cksum.syno" "${PART1_PATH}/GRUB_VER" "${PART2_PATH}/grub_cksum.syno" "${PART2_PATH}/GRUB_VER" >/dev/null
|
||||
rm -f "${ORI_ZIMAGE_FILE}" "${ORI_RDGZ_FILE}" >/dev/null
|
||||
rm -f "${MOD_ZIMAGE_FILE}" "${MOD_RDGZ_FILE}" >/dev/null
|
||||
# Copy new model files
|
||||
cp -f "${1}/grub_cksum.syno" "${PART1_PATH}"
|
||||
cp -f "${1}/GRUB_VER" "${PART1_PATH}"
|
||||
cp -f "${1}/grub_cksum.syno" "${PART2_PATH}"
|
||||
cp -f "${1}/GRUB_VER" "${PART2_PATH}"
|
||||
cp -f "${1}/zImage" "${ORI_ZIMAGE_FILE}"
|
||||
cp -f "${1}/rd.gz" "${ORI_RDGZ_FILE}"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Extract DSM files
|
||||
# 1 - PAT File
|
||||
# 2 - Destination Path
|
||||
function extractDSMFiles() {
|
||||
rm -f "${LOG_FILE}"
|
||||
PAT_PATH="${1}"
|
||||
EXT_PATH="${2}"
|
||||
|
||||
header="$(od -bcN2 "${PAT_PATH}" | head -1 | awk '{print $3}')"
|
||||
case ${header} in
|
||||
105)
|
||||
echo -e "Uncompressed tar"
|
||||
isencrypted="no"
|
||||
;;
|
||||
213)
|
||||
echo -e "Compressed tar"
|
||||
isencrypted="no"
|
||||
;;
|
||||
255)
|
||||
echo -e "Encrypted tar"
|
||||
isencrypted="yes"
|
||||
;;
|
||||
*)
|
||||
echo -e "Could not determine if pat file is encrypted or not, maybe corrupted, try again!"
|
||||
;;
|
||||
esac
|
||||
if [ "${isencrypted}" == "yes" ]; then
|
||||
# Uses the extractor to untar PAT file
|
||||
LD_LIBRARY_PATH="${EXTRACTOR_PATH}" "${EXTRACTOR_PATH}/${EXTRACTOR_BIN}" "${PAT_PATH}" "${EXT_PATH}" >"${LOG_FILE}" 2>&1
|
||||
else
|
||||
# Untar PAT file
|
||||
tar -xf "${PAT_PATH}" -C "${EXT_PATH}" >"${LOG_FILE}" 2>&1
|
||||
fi
|
||||
if [ -f "${EXT_PATH}/grub_cksum.syno" ] && [ -f "${EXT_PATH}/GRUB_VER" ] && [ -f "${EXT_PATH}/zImage" ] && [ -f "${EXT_PATH}/rd.gz" ]; then
|
||||
rm -f "${LOG_FILE}"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Livepatch
|
||||
function livepatch() {
|
||||
PVALID="false"
|
||||
# Patch zImage
|
||||
echo -n "Patching zImage"
|
||||
if ${ARC_PATH}/zimage-patch.sh; then
|
||||
echo -e " - successful!"
|
||||
PVALID="true"
|
||||
else
|
||||
echo -e " - failed!"
|
||||
PVALID="false"
|
||||
fi
|
||||
if [ "${PVALID}" == "true" ]; then
|
||||
# Patch Ramdisk
|
||||
echo -n "Patching Ramdisk"
|
||||
if ${ARC_PATH}/ramdisk-patch.sh; then
|
||||
echo -e " - successful!"
|
||||
PVALID="true"
|
||||
else
|
||||
echo -e " - failed!"
|
||||
PVALID="false"
|
||||
fi
|
||||
fi
|
||||
if [ "${PVALID}" == "false" ]; then
|
||||
echo
|
||||
echo -e "Patching DSM Files failed! Please stay patient for Update."
|
||||
sleep 5
|
||||
exit 1
|
||||
elif [ "${PVALID}" == "true" ]; then
|
||||
ZIMAGE_HASH="$(sha256sum "${ORI_ZIMAGE_FILE}" | awk '{print $1}')"
|
||||
writeConfigKey "zimage-hash" "${ZIMAGE_HASH}" "${USER_CONFIG_FILE}"
|
||||
RAMDISK_HASH="$(sha256sum "${ORI_RDGZ_FILE}" | awk '{print $1}')"
|
||||
writeConfigKey "ramdisk-hash" "${RAMDISK_HASH}" "${USER_CONFIG_FILE}"
|
||||
echo "DSM Image patched - Ready!"
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check NTP and Keyboard Layout
|
||||
function onlineCheck() {
|
||||
LAYOUT="$(readConfigKey "layout" "${USER_CONFIG_FILE}")"
|
||||
KEYMAP="$(readConfigKey "keymap" "${USER_CONFIG_FILE}")"
|
||||
REGION="$(curl -m 10 -v "http://ip-api.com/line?fields=timezone" 2>/dev/null | tr -d '\n' | cut -d '/' -f1)"
|
||||
TIMEZONE="$(curl -m 10 -v "http://ip-api.com/line?fields=timezone" 2>/dev/null | tr -d '\n' | cut -d '/' -f2)"
|
||||
[ -z "${KEYMAP}" ] && KEYMAP="$(curl -m 10 -v "http://ip-api.com/line?fields=countryCode" 2>/dev/null | tr '[:upper:]' '[:lower:]')"
|
||||
if [ -n "${REGION}" ] && [ -n "${TIMEZONE}" ]; then
|
||||
writeConfigKey "arc.offline" "false" "${USER_CONFIG_FILE}"
|
||||
[ $(echo "${ARC_VERSION}" | grep "dev" | wc -l) -eq 0 ] && NEWTAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)"
|
||||
[ $(echo "${ARC_VERSION}" | grep "dev" | wc -l) -gt 0 ] && NEWTAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep "dev" | sort -rV | head -1)"
|
||||
writeConfigKey "time.region" "${REGION}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "time.timezone" "${TIMEZONE}" "${USER_CONFIG_FILE}"
|
||||
updateOffline
|
||||
else
|
||||
REGION="$(readConfigKey "time.region" "${USER_CONFIG_FILE}")"
|
||||
TIMEZONE="$(readConfigKey "time.timezone" "${USER_CONFIG_FILE}")"
|
||||
writeConfigKey "arc.offline" "true" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
[ -n "${TIMEZONE}" ] && [ -n "${REGION}" ] && ln -sf "/usr/share/zoneinfo/${REGION}/${TIMEZONE}" /etc/localtime
|
||||
if [ -z "${LAYOUT}" ]; then
|
||||
[ -n "${KEYMAP}" ] && KEYMAP="$(echo ${KEYMAP} | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' | tr -d '[:punct:]' | tr -d '[:digit:]')"
|
||||
[ -n "${KEYMAP}" ] && writeConfigKey "keymap" "${KEYMAP}" "${USER_CONFIG_FILE}"
|
||||
[ -z "${KEYMAP}" ] && KEYMAP="us"
|
||||
loadkeys ${KEYMAP}
|
||||
fi
|
||||
if [ "${KEYMAP}" == "ua" ]; then
|
||||
poweroff
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check System
|
||||
function systemCheck () {
|
||||
# Get Loader Disk Bus
|
||||
BUS=$(getBus "${LOADER_DISK}")
|
||||
[ -z "${LOADER_DISK}" ] && die "Loader Disk not found!"
|
||||
# Memory: Check Memory installed
|
||||
RAMTOTAL="$(awk '/MemTotal:/ {printf "%.0f\n", $2 / 1024 / 1024 + 0.5}' /proc/meminfo 2>/dev/null)"
|
||||
[ -z "${RAMTOTAL}" ] && RAMTOTAL="8"
|
||||
# Check for Hypervisor
|
||||
if grep -q "^flags.*hypervisor.*" /proc/cpuinfo; then
|
||||
MACHINE="$(lscpu | grep Hypervisor | awk '{print $3}')" # KVM or VMware
|
||||
else
|
||||
MACHINE="Native"
|
||||
fi
|
||||
# Check for AES Support
|
||||
if ! grep -q "^flags.*aes.*" /proc/cpuinfo; then
|
||||
AESSYS="false"
|
||||
else
|
||||
AESSYS="true"
|
||||
fi
|
||||
# Check for ACPI Support
|
||||
if ! grep -q "^flags.*acpi.*" /proc/cpuinfo; then
|
||||
ACPISYS="false"
|
||||
else
|
||||
ACPISYS="true"
|
||||
fi
|
||||
# Check for CPU Frequency Scaling
|
||||
CPUFREQUENCIES=$(ls -ltr /sys/devices/system/cpu/cpufreq/* 2>/dev/null | wc -l)
|
||||
if [ ${CPUFREQUENCIES} -gt 1 ] && [ "${ACPISYS}" == "true" ]; then
|
||||
CPUFREQ="true"
|
||||
else
|
||||
CPUFREQ="false"
|
||||
fi
|
||||
# Check for Arc Patch
|
||||
ARCCONF="$(readConfigKey "${MODEL:-SA6400}.serial" "${S_FILE}")"
|
||||
[ -z "${ARCCONF}" ] && writeConfigKey "arc.patch" "false" "${USER_CONFIG_FILE}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Generate HardwareID
|
||||
function genHWID () {
|
||||
HWID="$(echo $(dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g' | head -1) $(ifconfig | grep eth | awk '{print $NF}' | sed 's/://g' | sort | head -1) | sha256sum | awk '{print $1}' | cut -c1-16)" 2>/dev/null
|
||||
echo "${HWID}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check if port is valid
|
||||
function check_port() {
|
||||
if [ -z "${1}" ]; then
|
||||
return 0
|
||||
else
|
||||
if [[ "${1}" =~ ^[0-9]+$ ]] && [ "${1}" -ge 0 ] && [ "${1}" -le 65535 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
BIN
files/initrd/opt/arc/include/logo.png
Normal file
BIN
files/initrd/opt/arc/include/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
57
files/initrd/opt/arc/include/modulelist
Normal file
57
files/initrd/opt/arc/include/modulelist
Normal file
@@ -0,0 +1,57 @@
|
||||
# `#: comment
|
||||
# $1: operation
|
||||
# N: copy module to ramdisk, do not overwrite an existing file
|
||||
# F: copy module to ramdisk, overwrite an existing file
|
||||
# $2: module file name (not module name)
|
||||
#
|
||||
# eg: N i915.ko
|
||||
|
||||
# kvm
|
||||
N irqbypass.ko
|
||||
N kvm-intel.ko
|
||||
N kvm-amd.ko
|
||||
N kvm.ko
|
||||
|
||||
# acpi
|
||||
N acpi_call.ko
|
||||
|
||||
# misc
|
||||
N check_signature.ko
|
||||
|
||||
# sensors
|
||||
N coretemp.ko
|
||||
N k10temp.ko
|
||||
N hwmon-vid.ko
|
||||
N it87.ko
|
||||
N adt7470.ko
|
||||
N adt7475.ko
|
||||
N nct6683.ko
|
||||
N nct6775.ko
|
||||
|
||||
# rndis
|
||||
N mii.ko
|
||||
N cdc_ether.ko
|
||||
N rndis_host.ko
|
||||
N r8152.ko
|
||||
|
||||
# iwlwifi
|
||||
N libarc4.ko
|
||||
N cfg80211.ko
|
||||
N mac80211.ko
|
||||
N iwlwifi.ko
|
||||
N iwlmvm.ko
|
||||
N iwldvm.ko
|
||||
|
||||
## i915
|
||||
#N dmabuf.ko
|
||||
#N drm.ko
|
||||
#N drm_buddy.ko
|
||||
#N drm_display_helper.ko
|
||||
#N drm_kms_helper.ko
|
||||
#N drm_mipi_dsi.ko
|
||||
#N drm_panel_orientation_quirks.ko
|
||||
#N i2c-algo-bit.ko
|
||||
#N i915-compat.ko
|
||||
#N intel-gtt.ko
|
||||
#N ttm.ko
|
||||
#N i915.ko
|
||||
185
files/initrd/opt/arc/include/modules.sh
Executable file
185
files/initrd/opt/arc/include/modules.sh
Executable file
@@ -0,0 +1,185 @@
|
||||
###############################################################################
|
||||
# Return list of all modules available
|
||||
# 1 - Platform
|
||||
# 2 - Kernel Version
|
||||
function getAllModules() {
|
||||
local PLATFORM=${1}
|
||||
local KVER=${2}
|
||||
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
# Unzip modules for temporary folder
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
mkdir -p "${TMP_PATH}/modules"
|
||||
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
fi
|
||||
# Get list of all modules
|
||||
for F in $(ls ${TMP_PATH}/modules/*.ko 2>/dev/null); do
|
||||
local X=$(basename ${F})
|
||||
local M=${X:0:-3}
|
||||
local DESC=$(modinfo ${F} | awk -F':' '/description:/{ print $2}' | awk '{sub(/^[ ]+/,""); print}')
|
||||
[ -z "${DESC}" ] && DESC="${X}"
|
||||
echo "${M} \"${DESC}\""
|
||||
done
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Return list of all modules available
|
||||
# 1 - Platform
|
||||
# 2 - Kernel Version
|
||||
# 3 - Module list
|
||||
function installModules() {
|
||||
local PLATFORM=${1}
|
||||
local KVER=${2}
|
||||
shift 2
|
||||
local MLIST="${@}"
|
||||
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ]; then
|
||||
echo "ERROR: installModules: Platform or Kernel Version not defined" >"${LOG_FILE}"
|
||||
return 1
|
||||
fi
|
||||
# Unzip modules for temporary folder
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
mkdir -p "${TMP_PATH}/modules"
|
||||
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" 2>"${LOG_FILE}"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" 2>"${LOG_FILE}"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")"
|
||||
for F in $(ls "${TMP_PATH}/modules/"*.ko 2>/dev/null); do
|
||||
local M=$(basename ${F})
|
||||
[ "${ODP}" == "true" -a -f "${RAMDISK_PATH}/usr/lib/modules/${M}" ] && continue
|
||||
if echo "${MLIST}" | grep -wq "${M:0:-3}"; then
|
||||
cp -f "${F}" "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}"
|
||||
else
|
||||
rm -f "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}"
|
||||
fi
|
||||
done
|
||||
mkdir -p "${RAMDISK_PATH}/usr/lib/firmware"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/firmware.tgz" -C "${RAMDISK_PATH}/usr/lib/firmware" 2>"${LOG_FILE}"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/firmware.tgz" -C "${RAMDISK_PATH}/usr/lib/firmware" 2>"${LOG_FILE}"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Clean
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# add a ko of modules.tgz
|
||||
# 1 - Platform
|
||||
# 2 - Kernel Version
|
||||
# 3 - ko file
|
||||
function addToModules() {
|
||||
local PLATFORM=${1}
|
||||
local KVER=${2}
|
||||
local KOFILE=${3}
|
||||
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ] || [ -z "${KOFILE}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
# Unzip modules for temporary folder
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
mkdir -p "${TMP_PATH}/modules"
|
||||
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
fi
|
||||
cp -f ${KOFILE} ${TMP_PATH}/modules
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zcf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" .
|
||||
else
|
||||
tar -zcf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" .
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# del a ko of modules.tgz
|
||||
# 1 - Platform
|
||||
# 2 - Kernel Version
|
||||
# 3 - ko name
|
||||
function delToModules() {
|
||||
local PLATFORM=${1}
|
||||
local KVER=${2}
|
||||
local KONAME=${3}
|
||||
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ] || [ -z "${KONAME}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
# Unzip modules for temporary folder
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
mkdir -p "${TMP_PATH}/modules"
|
||||
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
fi
|
||||
rm -f ${TMP_PATH}/modules/${KONAME}
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zcf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" .
|
||||
else
|
||||
tar -zcf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules" .
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# get depends of ko
|
||||
# 1 - Platform
|
||||
# 2 - Kernel Version
|
||||
# 3 - ko name
|
||||
function getdepends() {
|
||||
function _getdepends() {
|
||||
if [ -f "${TMP_PATH}/modules/${1}.ko" ]; then
|
||||
depends=($(modinfo "${TMP_PATH}/modules/${1}.ko" 2>/dev/null | grep depends: | awk -F: '{print $2}' | awk '$1=$1' | sed 's/,/ /g'))
|
||||
if [ ${#depends[@]} -gt 0 ]; then
|
||||
for k in ${depends[@]}; do
|
||||
echo "${k}"
|
||||
_getdepends "${k}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
}
|
||||
local PLATFORM=${1}
|
||||
local KVER=${2}
|
||||
local KONAME=${3}
|
||||
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ] || [ -z "${KONAME}" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
# Unzip modules for temporary folder
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
mkdir -p "${TMP_PATH}/modules"
|
||||
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
else
|
||||
tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVER}.tgz" -C "${TMP_PATH}/modules"
|
||||
fi
|
||||
local DPS=($(_getdepends ${KONAME} | tr ' ' '\n' | sort -u))
|
||||
echo ${DPS[@]}
|
||||
rm -rf "${TMP_PATH}/modules"
|
||||
}
|
||||
50
files/initrd/opt/arc/include/network.sh
Executable file
50
files/initrd/opt/arc/include/network.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
# Get Network Config for Loader
|
||||
function getnet() {
|
||||
ETHX=$(ip -o link show | awk -F': ' '{print $2}' | grep eth)
|
||||
MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")"
|
||||
ARCPATCH="$(readConfigKey "arc.patch" "${USER_CONFIG_FILE}")"
|
||||
NICPORTS="$(readConfigKey "${MODEL}.ports" "${S_FILE}" 2>/dev/null)"
|
||||
ETHN=$(echo ${ETHX} | wc -w)
|
||||
if [ "${ARCPATCH}" == "true" ]; then
|
||||
MACS=($(generateMacAddress "${MODEL}" "${ETHN}" "true"))
|
||||
for I in $(seq 1 ${ETHN}); do
|
||||
eval MAC${I}="${MACS[$((${I} - 1))]}"
|
||||
writeConfigKey "eth$((${I} - 1))" "${MACS[$((${I} - 1))]}" "${USER_CONFIG_FILE}"
|
||||
done
|
||||
elif [ "${ARCPATCH}" == "false" ]; then
|
||||
MACS=($(generateMacAddress "${MODEL}" "${ETHN}" "false"))
|
||||
for I in $(seq 1 ${ETHN}); do
|
||||
eval MAC${I}="${MACS[$((${I} - 1))]}"
|
||||
writeConfigKey "eth$((${I} - 1))" "${MACS[$((${I} - 1))]}" "${USER_CONFIG_FILE}"
|
||||
done
|
||||
elif [ "${ARCPATCH}" == "user" ]; then
|
||||
# User Mac
|
||||
for N in ${ETHX}; do
|
||||
while true; do
|
||||
MAC="$(cat /sys/class/net/${N}/address | sed 's/://g' | tr '[:lower:]' '[:upper:]')"
|
||||
dialog --backtitle "$(backtitle)" --title "Mac Setting" \
|
||||
--inputbox "Type a custom MAC for ${ETH} (Eq. 001132abc123)." 7 50 "${MAC}"\
|
||||
2>"${TMP_PATH}/resp"
|
||||
[ $? -ne 0 ] && break
|
||||
MAC=$(cat "${TMP_PATH}/resp")
|
||||
[ -z "${MAC}" ] && MAC="$(readConfigKey "${N}" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${MAC}" ] && MAC="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g' | tr '[:lower:]' '[:upper:]')"
|
||||
MAC="$(echo "${MAC}" | tr '[:lower:]' '[:upper:]')"
|
||||
if [ ${#MAC} -eq 12 ]; then
|
||||
writeConfigKey "${N}" "${MAC}" "${USER_CONFIG_FILE}"
|
||||
break
|
||||
else
|
||||
dialog --backtitle "$(backtitle)" --title "Mac Setting" --msgbox "Invalid MAC - Try again!" 5 50
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Get Amount of NIC
|
||||
ETHX="$(ls /sys/class/net 2>/dev/null | grep eth)"
|
||||
# Get actual IP
|
||||
for ETH in ${ETHX}; do
|
||||
IPCON=$(getIP ${ETH})
|
||||
[ -n "${IPCON}" ] && break
|
||||
done
|
||||
254
files/initrd/opt/arc/include/storage.sh
Executable file
254
files/initrd/opt/arc/include/storage.sh
Executable file
@@ -0,0 +1,254 @@
|
||||
# Get PortMap for Loader
|
||||
function getmap() {
|
||||
# Sata Disks
|
||||
SATADRIVES=0
|
||||
# Clean old files
|
||||
[ -f "${TMP_PATH}/drivesmax" ] && rm -f "${TMP_PATH}/drivesmax"
|
||||
touch "${TMP_PATH}/drivesmax"
|
||||
[ -f "${TMP_PATH}/drivescon" ] && rm -f "${TMP_PATH}/drivescon"
|
||||
touch "${TMP_PATH}/drivescon"
|
||||
[ -f "${TMP_PATH}/ports" ] && rm -f "${TMP_PATH}/ports"
|
||||
touch "${TMP_PATH}/ports"
|
||||
[ -f "${TMP_PATH}/remap" ] && rm -f "${TMP_PATH}/remap"
|
||||
touch "${TMP_PATH}/remap"
|
||||
if [ $(lspci -d ::106 | wc -l) -gt 0 ]; then
|
||||
let DISKIDXMAPIDX=0
|
||||
DISKIDXMAP=""
|
||||
let DISKIDXMAPIDXMAX=0
|
||||
DISKIDXMAPMAX=""
|
||||
for PCI in $(lspci -d ::106 | awk '{print $1}'); do
|
||||
NUMPORTS=0
|
||||
CONPORTS=0
|
||||
unset HOSTPORTS
|
||||
declare -A HOSTPORTS
|
||||
while read -r LINE; do
|
||||
ATAPORT="$(echo ${LINE} | grep -o 'ata[0-9]*')"
|
||||
PORT=$(echo ${ATAPORT} | sed 's/ata//')
|
||||
HOSTPORTS[${PORT}]=$(echo ${LINE} | grep -o 'host[0-9]*$')
|
||||
done < <(ls -l /sys/class/scsi_host | grep -F "${PCI}")
|
||||
while read -r PORT; do
|
||||
ls -l /sys/block | grep -F -q "${PCI}/ata${PORT}" && ATTACH=1 || ATTACH=0
|
||||
PCMD=$(cat /sys/class/scsi_host/${HOSTPORTS[${PORT}]}/ahci_port_cmd)
|
||||
[ ${PCMD} = 0 ] && DUMMY=1 || DUMMY=0
|
||||
[ ${ATTACH} = 1 ] && CONPORTS="$((${CONPORTS} + 1))" && echo "$((${PORT} - 1))" >>"${TMP_PATH}/ports"
|
||||
[ ${DUMMY} = 1 ] # Do nothing for now
|
||||
NUMPORTS=$((${NUMPORTS} + 1))
|
||||
done < <(echo ${!HOSTPORTS[@]} | tr ' ' '\n' | sort -n)
|
||||
[ ${NUMPORTS} -gt 8 ] && NUMPORTS=8
|
||||
[ ${CONPORTS} -gt 8 ] && CONPORTS=8
|
||||
echo -n "${NUMPORTS}" >>"${TMP_PATH}/drivesmax"
|
||||
echo -n "${CONPORTS}" >>"${TMP_PATH}/drivescon"
|
||||
DISKIDXMAP=$DISKIDXMAP$(printf "%02x" $DISKIDXMAPIDX)
|
||||
let DISKIDXMAPIDX=$DISKIDXMAPIDX+$CONPORTS
|
||||
DISKIDXMAPMAX=$DISKIDXMAPMAX$(printf "%02x" $DISKIDXMAPIDXMAX)
|
||||
let DISKIDXMAPIDXMAX=$DISKIDXMAPIDXMAX+$NUMPORTS
|
||||
SATADRIVES=$((${SATADRIVES} + ${CONPORTS}))
|
||||
done
|
||||
fi
|
||||
# SAS Disks
|
||||
SASDRIVES=0
|
||||
if [ $(lspci -d ::107 | wc -l) -gt 0 ]; then
|
||||
for PCI in $(lspci -d ::107 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORT=$(ls -l /sys/class/scsi_host | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n 2>/dev/null)
|
||||
PORTNUM=$(lsscsi -b | grep -v - | grep "\[${PORT}:" | wc -l)
|
||||
SASDRIVES=$((${SASDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# SCSI Disks
|
||||
SCSIDRIVES=0
|
||||
if [ $(lspci -d ::100 | wc -l) -gt 0 ]; then
|
||||
for PCI in $(lspci -d ::100 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORT=$(ls -l /sys/class/scsi_host | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort - 2>/dev/null)
|
||||
PORTNUM=$(lsscsi -b | grep -v - | grep "\[${PORT}:" | wc -l)
|
||||
SCSIDRIVES=$((${SCSIDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# Raid Disks
|
||||
RAIDDRIVES=0
|
||||
if [ $(lspci -d ::104 | wc -l) -gt 0 ]; then
|
||||
for PCI in $(lspci -d ::104 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORT=$(ls -l /sys/class/scsi_host | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n 2>/dev/null)
|
||||
PORTNUM=$(lsscsi -b | grep -v - | grep "\[${PORT}:" | wc -l)
|
||||
RAIDDRIVES=$((${RAIDDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# USB Disks
|
||||
USBDRIVES=0
|
||||
if [[ -d "/sys/class/scsi_host" && $(ls -l /sys/class/scsi_host | grep usb | wc -l) -gt 0 ]]; then
|
||||
for PCI in $(lspci -d ::c03 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORT=$(ls -l /sys/class/scsi_host | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n 2>/dev/null)
|
||||
PORTNUM=$(lsscsi -b | grep -v - | grep "\[${PORT}:" | wc -l)
|
||||
[ ${PORTNUM} -eq 0 ] && continue
|
||||
USBDRIVES=$((${USBDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# MMC Disks
|
||||
MMCDRIVES=0
|
||||
if [[ -d "/sys/class/mmc_host" && $(ls -l /sys/class/mmc_host | grep mmc_host | wc -l) -gt 0 ]]; then
|
||||
for PCI in $(lspci -d ::805 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORTNUM=$(ls -l /sys/block/mmc* | grep "${PCI}" | wc -l 2>/dev/null)
|
||||
[ ${PORTNUM} -eq 0 ] && continue
|
||||
MMCDRIVES=$((${MMCDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# NVMe Disks
|
||||
NVMEDRIVES=0
|
||||
if [ $(lspci -d ::108 | wc -l) -gt 0 ]; then
|
||||
for PCI in $(lspci -d ::108 | awk '{print $1}'); do
|
||||
NAME=$(lspci -s "${PCI}" | sed "s/\ .*://")
|
||||
PORT=$(ls -l /sys/class/nvme | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/nvme//' | sort -n 2>/dev/null)
|
||||
PORTNUM=$(lsscsi -b | grep -v - | grep "\[N:${PORT}:" | wc -l)
|
||||
NVMEDRIVES=$((${NVMEDRIVES} + ${PORTNUM}))
|
||||
done
|
||||
fi
|
||||
# Disk Count for MaxDisks
|
||||
DRIVES=$((${SATADRIVES} + ${SASDRIVES} + ${SCSIDRIVES} + ${RAIDDRIVES} + ${USBDRIVES} + ${MMCDRIVES} + ${NVMEDRIVES}))
|
||||
HARDDRIVES=$((${SATADRIVES} + ${SASDRIVES} + ${SCSIDRIVES} + ${RAIDDRIVES} + ${NVMEDRIVES}))
|
||||
writeConfigKey "device.satadrives" "${SATADRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.sasdrives" "${SASDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.scsidrives" "${SCSIDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.raiddrives" "${RAIDDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.usbdrives" "${USBDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.mmcdrives" "${MMCDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.nvmedrives" "${NVMEDRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.drives" "${DRIVES}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "device.harddrives" "${HARDDRIVES}" "${USER_CONFIG_FILE}"
|
||||
# Check for Sata Boot
|
||||
if [ $(lspci -d ::106 | wc -l) -gt 0 ]; then
|
||||
LASTDRIVE=0
|
||||
while read -r D; do
|
||||
if [ "${BUS}" == "sata" ] && [ "${MACHINE}" != "Native" ] && [ ${D} -eq 0 ]; then
|
||||
MAXDISKS=${DRIVES}
|
||||
echo -n "${D}>${MAXDISKS}:">>"${TMP_PATH}/remap"
|
||||
elif [ ${D} != ${LASTDRIVE} ]; then
|
||||
echo -n "${D}>${LASTDRIVE}:">>"${TMP_PATH}/remap"
|
||||
LASTDRIVE=$((${LASTDRIVE} + 1))
|
||||
elif [ ${D} == ${LASTDRIVE} ]; then
|
||||
LASTDRIVE=$((${D} + 1))
|
||||
fi
|
||||
done < <(cat "${TMP_PATH}/ports")
|
||||
fi
|
||||
}
|
||||
|
||||
function getmapSelection() {
|
||||
# Compute PortMap Options
|
||||
SATAPORTMAPMAX="$(awk '{print $1}' "${TMP_PATH}/drivesmax")"
|
||||
SATAPORTMAP="$(awk '{print $1}' "${TMP_PATH}/drivescon")"
|
||||
SATAREMAP="$(awk '{print $1}' "${TMP_PATH}/remap" | sed 's/.$//')"
|
||||
EXTERNALCONTROLLER="$(readConfigKey "device.externalcontroller" "${USER_CONFIG_FILE}")"
|
||||
ARCMODE="$(readConfigKey "arc.mode" "${USER_CONFIG_FILE}")"
|
||||
if [ "${ARCMODE}" == "config" ]; then
|
||||
# Show recommended Option to user
|
||||
if [ -n "${SATAREMAP}" ] && [ "${EXTERNALCONTROLLER}" == "true" ] && [ "${MACHINE}" == "Native" ]; then
|
||||
REMAP2="*"
|
||||
elif [ -n "${SATAREMAP}" ] && [ "${EXTERNALCONTROLLER}" == "false" ]; then
|
||||
REMAP3="*"
|
||||
else
|
||||
REMAP1="*"
|
||||
fi
|
||||
# Ask for Portmap
|
||||
if [ "${STEP}" == "storagemap" ]; then
|
||||
dialog --backtitle "$(backtitlep)" --title "Sata Portmap" \
|
||||
--menu "Choose a Portmap for Sata!?\n* Recommended Option" 8 60 0 \
|
||||
1 "DiskIdxMap: Active Ports ${REMAP1}" \
|
||||
2 "DiskIdxMap: Max Ports ${REMAP2}" \
|
||||
3 "SataRemap: Remove empty Ports ${REMAP3}" \
|
||||
4 "AhciRemap: Remove empty Ports (new) ${REMAP4}" \
|
||||
5 "Set my own Portmap in Config" \
|
||||
2>"${TMP_PATH}/resp"
|
||||
[ $? -ne 0 ] && return 1
|
||||
resp=$(cat "${TMP_PATH}/resp")
|
||||
[ -z "${resp}" ] && return 1
|
||||
else
|
||||
dialog --backtitle "$(backtitle)" --title "Sata Portmap" \
|
||||
--menu "Choose a Portmap for Sata!?\n* Recommended Option" 8 60 0 \
|
||||
1 "DiskIdxMap: Active Ports ${REMAP1}" \
|
||||
2 "DiskIdxMap: Max Ports ${REMAP2}" \
|
||||
3 "SataRemap: Remove empty Ports ${REMAP3}" \
|
||||
4 "AhciRemap: Remove empty Ports (new) ${REMAP4}" \
|
||||
5 "Set my own Portmap in Config" \
|
||||
2>"${TMP_PATH}/resp"
|
||||
[ $? -ne 0 ] && return 1
|
||||
resp=$(cat "${TMP_PATH}/resp")
|
||||
[ -z "${resp}" ] && return 1
|
||||
fi
|
||||
if [ ${resp} -eq 1 ]; then
|
||||
writeConfigKey "arc.remap" "acports" "${USER_CONFIG_FILE}"
|
||||
elif [ ${resp} -eq 2 ]; then
|
||||
writeConfigKey "arc.remap" "maxports" "${USER_CONFIG_FILE}"
|
||||
elif [ ${resp} -eq 3 ]; then
|
||||
writeConfigKey "arc.remap" "remap" "${USER_CONFIG_FILE}"
|
||||
elif [ ${resp} -eq 4 ]; then
|
||||
writeConfigKey "arc.remap" "ahci" "${USER_CONFIG_FILE}"
|
||||
elif [ ${resp} -eq 5 ]; then
|
||||
writeConfigKey "arc.remap" "user" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
else
|
||||
# Show recommended Option to user
|
||||
if [ -n "${SATAREMAP}" ] && [ "${EXTERNALCONTROLLER}" == "true" ] && [ "${MACHINE}" == "Native" ]; then
|
||||
writeConfigKey "arc.remap" "maxports" "${USER_CONFIG_FILE}"
|
||||
elif [ -n "${SATAREMAP}" ] && [ "${EXTERNALCONTROLLER}" == "false" ]; then
|
||||
writeConfigKey "arc.remap" "remap" "${USER_CONFIG_FILE}"
|
||||
else
|
||||
writeConfigKey "arc.remap" "acports" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
fi
|
||||
# Check Remap for correct config
|
||||
REMAP="$(readConfigKey "arc.remap" "${USER_CONFIG_FILE}")"
|
||||
# Write Map to config and show Map to User
|
||||
if [ "${REMAP}" == "acports" ]; then
|
||||
writeConfigKey "cmdline.SataPortMap" "${SATAPORTMAP}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "cmdline.DiskIdxMap" "${DISKIDXMAP}" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.sata_remap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.ahci_remap" "${USER_CONFIG_FILE}"
|
||||
elif [ "${REMAP}" == "maxports" ]; then
|
||||
writeConfigKey "cmdline.SataPortMap" "${SATAPORTMAPMAX}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "cmdline.DiskIdxMap" "${DISKIDXMAPMAX}" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.sata_remap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.ahci_remap" "${USER_CONFIG_FILE}"
|
||||
elif [ "${REMAP}" == "remap" ]; then
|
||||
writeConfigKey "cmdline.sata_remap" "${SATAREMAP}" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.DiskIdxMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.SataPortMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.ahci_remap" "${USER_CONFIG_FILE}"
|
||||
elif [ "${REMAP}" == "ahci" ]; then
|
||||
writeConfigKey "cmdline.ahci_remap" "${SATAREMAP}" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.DiskIdxMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.SataPortMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.sata_remap" "${USER_CONFIG_FILE}"
|
||||
elif [ "${REMAP}" == "user" ]; then
|
||||
deleteConfigKey "cmdline.SataPortMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.DiskIdxMap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.sata_remap" "${USER_CONFIG_FILE}"
|
||||
deleteConfigKey "cmdline.ahci_remap" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for Controller // 104=RAID // 106=SATA // 107=SAS // 100=SCSI // c03=USB
|
||||
SATACONTROLLER=$(lspci -d ::106 | wc -l)
|
||||
writeConfigKey "device.satacontroller" "${SATACONTROLLER}" "${USER_CONFIG_FILE}"
|
||||
if [ ${SATACONTROLLER} -gt 0 ]; then
|
||||
writeConfigKey "device.externalcontroller" "false" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
SASCONTROLLER=$(lspci -d ::107 | wc -l)
|
||||
writeConfigKey "device.sascontroller" "${SASCONTROLLER}" "${USER_CONFIG_FILE}"
|
||||
if [ ${SASCONTROLLER} -gt 0 ]; then
|
||||
writeConfigKey "device.externalcontroller" "true" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
SCSICONTROLLER=$(lspci -d ::100 | wc -l)
|
||||
writeConfigKey "device.scsicontroller" "${SCSICONTROLLER}" "${USER_CONFIG_FILE}"
|
||||
if [ ${SCSICONTROLLER} -gt 0 ]; then
|
||||
writeConfigKey "device.externalcontroller" "true" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
RAIDCONTROLLER=$(lspci -d ::104 | wc -l)
|
||||
writeConfigKey "device.raidcontroller" "${RAIDCONTROLLER}" "${USER_CONFIG_FILE}"
|
||||
if [ ${RAIDCONTROLLER} -gt 0 ]; then
|
||||
writeConfigKey "device.externalcontroller" "true" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
# Check Controller for Disks
|
||||
getmap
|
||||
BIN
files/initrd/opt/arc/include/syno.png
Normal file
BIN
files/initrd/opt/arc/include/syno.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 227 KiB |
477
files/initrd/opt/arc/include/update.sh
Executable file
477
files/initrd/opt/arc/include/update.sh
Executable file
@@ -0,0 +1,477 @@
|
||||
###############################################################################
|
||||
# Update Loader
|
||||
function updateLoader() {
|
||||
CONFDONE="$(readConfigKey "arc.confdone" "${USER_CONFIG_FILE}")"
|
||||
local ARC_BRANCH="$(readConfigKey "arc.branch" "${USER_CONFIG_FILE}")"
|
||||
local ARCMODE="$(readConfigKey "arc.mode" "${USER_CONFIG_FILE}")"
|
||||
local ARCCONF="$(readConfigKey "${MODEL:-SA6400}.serial" "${S_FILE}")"
|
||||
local TAG="${1}"
|
||||
[ -n "${ARCCONF}" ] && cp -f "${S_FILE}" "${TMP_PATH}/bak.yml"
|
||||
if [ -z "${TAG}" ]; then
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
if [ "${ARC_BRANCH}" == "dev" ]; then
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep "dev" | sort -rV | head -1)"
|
||||
else
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)"
|
||||
fi
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
fi
|
||||
if [ -n "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc/releases/download/${TAG}/update-${TAG}-${ARC_BRANCH}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/update.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" \
|
||||
--gauge "Download Loader: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/update.zip" ] && [ $(ls -s "${TMP_PATH}/update.zip" | cut -d' ' -f1) -gt 300000 ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" \
|
||||
--infobox "Updating Loader..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/update.zip" -d "/mnt"; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
if [ "${ARCMODE}" == "update" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \
|
||||
--infobox "Update failed!\nTry again later." 0 0
|
||||
sleep 3
|
||||
exec reboot
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ "${ARCMODE}" == "update" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \
|
||||
--infobox "Update failed!\nTry again later." 0 0
|
||||
sleep 3
|
||||
exec reboot
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
[ -n "${ARCCONF}" ] && cp -f "${TMP_PATH}/bak.yml" "${S_FILE}"
|
||||
if [ "${ARCMODE}" == "update" ] && [ "${CONFDONE}" == "true" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \
|
||||
--infobox "Update successful! -> Reboot to automated Build Mode..." 3 60
|
||||
sleep 3
|
||||
writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
rebootTo "automated"
|
||||
else
|
||||
dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \
|
||||
--infobox "Update successful! -> Reboot to Config Mode..." 3 50
|
||||
sleep 3
|
||||
writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
rebootTo "config"
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Addons
|
||||
function updateAddons() {
|
||||
[ -f "${ADDONS_PATH}/VERSION" ] && local ADDONSVERSION="$(cat "${ADDONS_PATH}/VERSION")" || ADDONSVERSION="0.0.0"
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-addons/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
if [ -n "${TAG}" ] && [ "${ADDONSVERSION}" != "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc-addons/releases/download/${TAG}/addons-${TAG}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/addons.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Addons" \
|
||||
--gauge "Download Addons: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/addons.zip" ]; then
|
||||
rm -rf "${ADDONS_PATH}"
|
||||
mkdir -p "${ADDONS_PATH}"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Addons" \
|
||||
--infobox "Updating Addons..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/addons.zip" -d "${ADDONS_PATH}"; then
|
||||
rm -f "${TMP_PATH}/addons.zip"
|
||||
for F in $(ls ${ADDONS_PATH}/*.addon 2>/dev/null); do
|
||||
ADDON=$(basename "${F}" | sed 's|.addon||')
|
||||
rm -rf "${ADDONS_PATH}/${ADDON}"
|
||||
mkdir -p "${ADDONS_PATH}/${ADDON}"
|
||||
tar -xaf "${F}" -C "${ADDONS_PATH}/${ADDON}"
|
||||
rm -f "${F}"
|
||||
done
|
||||
dialog --backtitle "$(backtitle)" --title "Update Addons" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Patches
|
||||
function updatePatches() {
|
||||
[ -f "${PATCH_PATH}/VERSION" ] && local PATCHESVERSION="$(cat "${PATCH_PATH}/VERSION")" || PATCHESVERSION="0.0.0"
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-patches/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
if [ -n "${TAG}" ] && [ "${PATCHESVERSION}" != "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc-patches/releases/download/${TAG}/patches-${TAG}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/patches.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Patches" \
|
||||
--gauge "Download Patches: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/patches.zip" ]; then
|
||||
rm -rf "${PATCH_PATH}"
|
||||
mkdir -p "${PATCH_PATH}"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Patches" \
|
||||
--infobox "Updating Patches..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/patches.zip" -d "${PATCH_PATH}"; then
|
||||
rm -f "${TMP_PATH}/patches.zip"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Patches" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Custom
|
||||
function updateCustom() {
|
||||
[ -f "${CUSTOM_PATH}/VERSION" ] && local CUSTOMVERSION="$(cat "${CUSTOM_PATH}/VERSION")" || CUSTOMVERSION="0.0.0"
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-custom/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
if [ -n "${TAG}" ] && [ "${CUSTOMVERSION}" != "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc-custom/releases/download/${TAG}/custom-${TAG}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/custom.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Custom Kernel" \
|
||||
--gauge "Download Custom Kernel: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/custom.zip" ]; then
|
||||
rm -rf "${CUSTOM_PATH}"
|
||||
mkdir -p "${CUSTOM_PATH}"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Custom Kernel" \
|
||||
--infobox "Updating Custom Kernel..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/custom.zip" -d "${CUSTOM_PATH}"; then
|
||||
rm -f "${TMP_PATH}/custom.zip"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Custom Kernel" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Modules
|
||||
function updateModules() {
|
||||
[ -f "${MODULES_PATH}/VERSION" ] && local MODULESVERSION="$(cat "${MODULES_PATH}/VERSION")" || MODULESVERSION="0.0.0"
|
||||
local PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
local PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
|
||||
local KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")"
|
||||
[ "${PLATFORM}" == "epyc7002" ] && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}"
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-modules/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
if [ -n "${TAG}" ] && [[ "${MODULESVERSION}" != "${TAG}" || ! -f "${MODULES_PATH}/${PLATFORM}-${KVERP}.tgz" ]]; then
|
||||
rm -rf "${MODULES_PATH}"
|
||||
mkdir -p "${MODULES_PATH}"
|
||||
export URL="https://github.com/AuxXxilium/arc-modules/releases/download/${TAG}/modules-${TAG}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/modules.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Modules" \
|
||||
--gauge "Download Modules: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/modules.zip" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Modules" \
|
||||
--infobox "Updating Modules..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/modules.zip" -d "${MODULES_PATH}"; then
|
||||
rm -f "${TMP_PATH}/modules.zip"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Modules" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
if [ -f "${MODULES_PATH}/${PLATFORM}-${KVERP}.tgz" ] && [ -f "${MODULES_PATH}/firmware.tgz" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Modules" \
|
||||
--infobox "Rewrite Modules..." 3 50
|
||||
sleep 2
|
||||
writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
|
||||
while read -r ID DESC; do
|
||||
writeConfigKey "modules.${ID}" "" "${USER_CONFIG_FILE}"
|
||||
done < <(getAllModules "${PLATFORM}" "${KVERP}")
|
||||
dialog --backtitle "$(backtitle)" --title "Update Modules" \
|
||||
--infobox "Rewrite successful!" 3 50
|
||||
sleep 2
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Configs
|
||||
function updateConfigs() {
|
||||
[ -f "${MODEL_CONFIG_PATH}/VERSION" ] && local CONFIGSVERSION="$(cat "${MODEL_CONFIG_PATH}/VERSION")" || CONFIGSVERSION="0.0.0"
|
||||
local USERID="$(readConfigKey "arc.userid" "${USER_CONFIG_FILE}")"
|
||||
if [ -z "${1}" ]; then
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-configs/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
else
|
||||
local TAG="${1}"
|
||||
fi
|
||||
if [ -n "${TAG}" ] && [ "${CONFIGSVERSION}" != "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc-configs/releases/download/${TAG}/configs-${TAG}.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/configs.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update Configs" \
|
||||
--gauge "Download Configs: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/configs.zip" ]; then
|
||||
mkdir -p "${MODEL_CONFIG_PATH}"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Configs" \
|
||||
--infobox "Updating Configs..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/configs.zip" -d "${MODEL_CONFIG_PATH}"; then
|
||||
rm -f "${TMP_PATH}/configs.zip"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Configs" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
[ -z "${USERID}" ] && checkHardwareID || true
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update LKMs
|
||||
function updateLKMs() {
|
||||
[ -f "${LKMS_PATH}/VERSION" ] && local LKMVERSION="$(cat "${LKMS_PATH}/VERSION")" || LKMVERSION="0.0.0"
|
||||
if [ -z "${1}" ]; then
|
||||
idx=0
|
||||
while [ ${idx} -le 5 ]; do # Loop 5 times, if successful, break
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-lkm/releases" | jq -r ".[].tag_name" | sort -rV | head -1)"
|
||||
if [ -n "${TAG}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
idx=$((${idx} + 1))
|
||||
done
|
||||
else
|
||||
local TAG="${1}"
|
||||
fi
|
||||
if [ -n "${TAG}" ] && [ "${LKMVERSION}" != "${TAG}" ]; then
|
||||
export URL="https://github.com/AuxXxilium/arc-lkm/releases/download/${TAG}/rp-lkms.zip"
|
||||
export TAG="${TAG}"
|
||||
{
|
||||
curl -kL "$URL" -o ${TMP_PATH}/rp-lkms.zip 2>&1 |
|
||||
perl -C -lane '
|
||||
BEGIN {$header = "Downloading $ENV{TAG}...\n\n"; $| = 1}
|
||||
$pcent = $F[0];
|
||||
$_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20;
|
||||
s/ /\xa0/g;
|
||||
if ($. <= 3) {
|
||||
$header .= "$_\n";
|
||||
$/ = "\r" if $. == 2
|
||||
} else {
|
||||
print "XXX\n$pcent\n$header$_\nXXX"
|
||||
}' |
|
||||
dialog --backtitle "$(backtitle)" --title "Update LKMs" \
|
||||
--gauge "Download LKMs: $TAG ..." 14 72
|
||||
}
|
||||
if [ -f "${TMP_PATH}/rp-lkms.zip" ]; then
|
||||
rm -rf "${LKMS_PATH}"
|
||||
mkdir -p "${LKMS_PATH}"
|
||||
dialog --backtitle "$(backtitle)" --title "Update LKMs" \
|
||||
--infobox "Updating LKMs..." 3 50
|
||||
if unzip -oq "${TMP_PATH}/rp-lkms.zip" -d "${LKMS_PATH}"; then
|
||||
rm -f "${TMP_PATH}/rp-lkms.zip"
|
||||
dialog --backtitle "$(backtitle)" --title "Update LKMs" \
|
||||
--infobox "Update successful!" 3 50
|
||||
sleep 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Update Offline
|
||||
function updateOffline() {
|
||||
local ARCOFFLINE="$(readConfigKey "arc.offline" "${USER_CONFIG_FILE}")"
|
||||
if [ "${ARCOFFLINE}" != "true" ]; then
|
||||
[ -f "${MODEL_CONFIG_PATH}/data.yml" ] && cp -f "${MODEL_CONFIG_PATH}/data.yml" "${MODEL_CONFIG_PATH}/data.yml.bak"
|
||||
curl -skL "https://raw.githubusercontent.com/AuxXxilium/arc-dsm/refs/heads/main/data.yml" -o "${MODEL_CONFIG_PATH}/data.yml"
|
||||
[ ! -f "${MODEL_CONFIG_PATH}/data.yml" ] && cp -f "${MODEL_CONFIG_PATH}/data.yml.bak" "${MODEL_CONFIG_PATH}/data.yml"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Loading Update Mode
|
||||
function dependenciesUpdate() {
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
FAILED="false"
|
||||
dialog --backtitle "$(backtitle)" --title "Update Dependencies" --aspect 18 \
|
||||
--infobox "Updating Dependencies..." 3 40
|
||||
sleep 2
|
||||
updateAddons
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
updateModules
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
updateCustom
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
updatePatches
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
updateLKMs
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
updateOffline
|
||||
[ $? -ne 0 ] && FAILED="true"
|
||||
if [ "${FAILED}" == "true" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Dependencies" --aspect 18 \
|
||||
--infobox "Update failed! Try again later." 3 40
|
||||
sleep 3
|
||||
elif [ "${FAILED}" == "false" ]; then
|
||||
dialog --backtitle "$(backtitle)" --title "Update Dependencies" --aspect 18 \
|
||||
--infobox "Update successful!" 3 40
|
||||
writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
sleep 3
|
||||
clear
|
||||
exec arc.sh
|
||||
fi
|
||||
}
|
||||
29
files/initrd/opt/arc/informations/apollolake.yml
Normal file
29
files/initrd/opt/arc/informations/apollolake.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 8 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: yes
|
||||
Raid controller: yes
|
||||
SCSI controller: yes
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: yes
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
2nd - 9th Gen (Addon required)
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes (sometimes addon required)
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/broadwell.yml
Normal file
29
files/initrd/opt/arc/informations/broadwell.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 16 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: yes
|
||||
Raid controller: yes
|
||||
SCSI controller: yes
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: yes
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes (sometimes addon required)
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/broadwellnk.yml
Normal file
29
files/initrd/opt/arc/informations/broadwellnk.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 24 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: yes
|
||||
Raid controller: yes
|
||||
SCSI controller: yes
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: yes
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes (sometimes addon required)
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/broadwellnkv2.yml
Normal file
29
files/initrd/opt/arc/informations/broadwellnkv2.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 24 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: no
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
31
files/initrd/opt/arc/informations/denverton.yml
Normal file
31
files/initrd/opt/arc/informations/denverton.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 16 threads
|
||||
requires FMA3/MOVBE support
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: yes
|
||||
Raid controller: yes
|
||||
SCSI controller: yes
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: yes
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Partially natively supported
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes (sometimes addon required)
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/epyc7002.yml
Normal file
29
files/initrd/opt/arc/informations/epyc7002.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 24 threads (with CustomKernel up to 128 threads)
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: yes
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
up to the 14th generation
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): Addon required
|
||||
29
files/initrd/opt/arc/informations/geminilake.yml
Normal file
29
files/initrd/opt/arc/informations/geminilake.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 8 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: no
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
2nd - 9th Gen (Addon required)
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/purley.yml
Normal file
29
files/initrd/opt/arc/informations/purley.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 64 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: no
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/r1000.yml
Normal file
29
files/initrd/opt/arc/informations/r1000.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 16 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: no
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
29
files/initrd/opt/arc/informations/v1000.yml
Normal file
29
files/initrd/opt/arc/informations/v1000.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
- CPU
|
||||
Intel: yes
|
||||
AMD: yes
|
||||
Note: Not every model runs on every hardware!
|
||||
Up to 16 threads
|
||||
|
||||
- Cache
|
||||
SSD Cache: yes
|
||||
|
||||
- Additional controllers
|
||||
HBA Controller: no
|
||||
Raid controller: no
|
||||
SCSI controller: no
|
||||
Note: Partially incorrect smart values
|
||||
|
||||
- USB storage
|
||||
As internal: no
|
||||
As external: yes
|
||||
|
||||
- Intel iGPU
|
||||
Unsupported
|
||||
|
||||
- Nvidia GPU
|
||||
Community Package required *
|
||||
|
||||
- NVMe
|
||||
Cache: yes
|
||||
Storage: Addon required
|
||||
System (NVMe only): no
|
||||
228
files/initrd/opt/arc/init.sh
Executable file
228
files/initrd/opt/arc/init.sh
Executable file
@@ -0,0 +1,228 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/functions.sh
|
||||
|
||||
# Get Loader Disk Bus
|
||||
[ -z "${LOADER_DISK}" ] && die "Loader Disk not found!"
|
||||
checkBootLoader || die "The loader is corrupted, please rewrite it!"
|
||||
BUS=$(getBus "${LOADER_DISK}")
|
||||
|
||||
# Check if machine has EFI
|
||||
[ -d /sys/firmware/efi ] && EFI=1 || EFI=0
|
||||
|
||||
# Print Title centralized
|
||||
clear
|
||||
COLUMNS=${COLUMNS:-50}
|
||||
BANNER="$(figlet -c -w "$(((${COLUMNS})))" "Arc Loader")"
|
||||
TITLE="Version:"
|
||||
TITLE+=" ${ARC_VERSION} (${ARC_BUILD})"
|
||||
[ -n "${ARC_BRANCH}" ] && TITLE+=" | Branch: ${ARC_BRANCH}"
|
||||
printf "\033[1;30m%*s\n" ${COLUMNS} ""
|
||||
printf "\033[1;30m%*s\033[A\n" ${COLUMNS} ""
|
||||
printf "\033[1;34m%*s\033[0m\n" ${COLUMNS} "${BANNER}"
|
||||
printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}"
|
||||
TITLE="Boot:"
|
||||
[ ${EFI} -eq 1 ] && TITLE+=" [UEFI]" || TITLE+=" [BIOS]"
|
||||
TITLE+=" [${BUS}]"
|
||||
printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}"
|
||||
|
||||
# Check for Config File
|
||||
if [ ! -f "${USER_CONFIG_FILE}" ]; then
|
||||
touch "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
initConfigKey "addons" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.confdone" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.dynamic" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.offline" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.patch" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "arc.version" "${ARC_VERSION}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "boot" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "boot.dsminfo" "true" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "boot.systeminfo" "true" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "boot.dsmlogo" "true" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "bootipwait" "30" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "device" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "directboot" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "emmcboot" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "hddsort" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "kernel" "official" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "kernelload" "power" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "kernelpanic" "5" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "odp" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "pathash" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "paturl" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "sn" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "cmdline" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "keymap" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "layout" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "lkm" "prod" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "modblacklist" "evbug,cdc_ether" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "model" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "modelid" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "network" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "platform" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "productver" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "buildnum" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "smallnum" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "ramdisk-hash" "" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "rd-compressed" "false" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "satadom" "2" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "synoinfo" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "time" "{}" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "usbmount" "auto" "${USER_CONFIG_FILE}"
|
||||
initConfigKey "zimage-hash" "" "${USER_CONFIG_FILE}"
|
||||
if grep -q "automated_arc" /proc/cmdline; then
|
||||
writeConfigKey "arc.mode" "automated" "${USER_CONFIG_FILE}"
|
||||
elif grep -q "update_arc" /proc/cmdline; then
|
||||
writeConfigKey "arc.mode" "update" "${USER_CONFIG_FILE}"
|
||||
elif grep -q "force_arc" /proc/cmdline; then
|
||||
writeConfigKey "arc.mode" "config" "${USER_CONFIG_FILE}"
|
||||
else
|
||||
writeConfigKey "arc.mode" "dsm" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
[ -f "${PART3_PATH}/automated" ] && rm -f "${PART3_PATH}/automated" >/dev/null 2>&1 || true
|
||||
if [ -n "${ARC_BRANCH}" ]; then
|
||||
writeConfigKey "arc.branch" "${ARC_BRANCH}" "${USER_CONFIG_FILE}"
|
||||
fi
|
||||
# Sort network interfaces
|
||||
if arrayExistItem "sortnetif:" $(readConfigMap "addons" "${USER_CONFIG_FILE}"); then
|
||||
_sort_netif "$(readConfigKey "addons.sortnetif" "${USER_CONFIG_FILE}")"
|
||||
fi
|
||||
# Read/Write IP/Mac to config
|
||||
ETHX=$(ip -o link show | awk -F': ' '{print $2}' | grep eth)
|
||||
for N in ${ETHX}; do
|
||||
MACR="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g' | tr '[:lower:]' '[:upper:]')"
|
||||
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
|
||||
if [ -n "${IPR}" ] && [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
IFS='/' read -r -a IPRA <<<"${IPR}"
|
||||
ip addr flush dev ${N}
|
||||
ip addr add ${IPRA[0]}/${IPRA[1]:-"255.255.255.0"} dev ${N}
|
||||
if [ -n "${IPRA[2]}" ]; then
|
||||
ip route add default via ${IPRA[2]} dev ${N}
|
||||
fi
|
||||
if [ -n "${IPRA[3]:-${IPRA[2]}}" ]; then
|
||||
sed -i "/nameserver ${IPRA[3]:-${IPRA[2]}}/d" /etc/resolv.conf
|
||||
echo "nameserver ${IPRA[3]:-${IPRA[2]}}" >>/etc/resolv.conf
|
||||
fi
|
||||
sleep 1
|
||||
fi
|
||||
[ "${N::3}" == "eth" ] && ethtool -s ${N} wol g 2>/dev/null || true
|
||||
# [ "${N::3}" == "eth" ] && ethtool -K ${N} rxhash off 2>/dev/null || true
|
||||
initConfigKey "${N}" "${MACR}" "${USER_CONFIG_FILE}"
|
||||
done
|
||||
ETHN=$(echo ${ETHX} | wc -w)
|
||||
writeConfigKey "device.nic" "${ETHN}" "${USER_CONFIG_FILE}"
|
||||
# No network devices
|
||||
echo
|
||||
[ ${ETHN} -le 0 ] && die "No NIC found! - Loader does not work without Network connection."
|
||||
|
||||
# Get the VID/PID if we are in USB
|
||||
VID="0x46f4"
|
||||
PID="0x0001"
|
||||
|
||||
BUSLIST="usb sata sas scsi nvme mmc ide virtio vmbus xen"
|
||||
if [ "${BUS}" == "usb" ]; then
|
||||
VID="0x$(udevadm info --query property --name "${LOADER_DISK}" | grep ID_VENDOR_ID | cut -d= -f2)"
|
||||
PID="0x$(udevadm info --query property --name "${LOADER_DISK}" | grep ID_MODEL_ID | cut -d= -f2)"
|
||||
elif ! echo "${BUSLIST}" | grep -wq "${BUS}"; then
|
||||
die "$(printf "The boot disk does not support the current %s, only %s are supported." "${BUS}" "${BUSLIST// /\/}")"
|
||||
fi
|
||||
|
||||
# Inform user and check bus
|
||||
echo -e "Loader Disk: \033[1;34m${LOADER_DISK}\033[0m"
|
||||
echo -e "Loader Disk Type: \033[1;34m${BUS}\033[0m"
|
||||
echo
|
||||
|
||||
# Save variables to user config file
|
||||
writeConfigKey "vid" "${VID}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "pid" "${PID}" "${USER_CONFIG_FILE}"
|
||||
|
||||
# Decide if boot automatically
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
ARCMODE="$(readConfigKey "arc.mode" "${USER_CONFIG_FILE}")"
|
||||
if [ "${ARCMODE}" == "config" ]; then
|
||||
echo -e "\033[1;34mStarting Config Mode...\033[0m"
|
||||
elif [ "${ARCMODE}" == "automated" ]; then
|
||||
echo -e "\033[1;34mStarting automated Build Mode...\033[0m"
|
||||
elif [ "${ARCMODE}" == "update" ]; then
|
||||
echo -e "\033[1;34mStarting Update Mode...\033[0m"
|
||||
elif [ "${BUILDDONE}" == "true" ] && [ "${ARCMODE}" == "dsm" ]; then
|
||||
echo -e "\033[1;34mStarting DSM Mode...\033[0m"
|
||||
if [ -f "${ARC_PATH}/boot.sh" ]; then
|
||||
exec boot.sh && exit 0
|
||||
else
|
||||
echo -e "\033[1;31mError: Can't find Arc System Files...\033[0m"
|
||||
fi
|
||||
else
|
||||
echo -e "\033[1;34mStarting Config Mode...\033[0m"
|
||||
fi
|
||||
echo
|
||||
|
||||
BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m"
|
||||
IPCON=""
|
||||
echo
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S41dhcpcd restart >/dev/null 2>&1 || true
|
||||
sleep 3
|
||||
for N in ${ETHX}; do
|
||||
COUNT=0
|
||||
DRIVER=$(ls -ld /sys/class/net/${N}/device/driver 2>/dev/null | awk -F '/' '{print $NF}')
|
||||
while true; do
|
||||
if [ "0" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mNOT CONNECTED\033[0m"
|
||||
break
|
||||
fi
|
||||
COUNT=$((${COUNT} + 1))
|
||||
IP="$(getIP ${N})"
|
||||
if [ -n "${IP}" ]; then
|
||||
SPEED=$(ethtool ${N} 2>/dev/null | grep "Speed:" | awk '{print $2}')
|
||||
if [[ "${IP}" =~ ^169\.254\..* ]]; then
|
||||
echo -e "\r${DRIVER} (${SPEED}): \033[1;37mLINK LOCAL (No DHCP server found.)\033[0m"
|
||||
else
|
||||
echo -e "\r${DRIVER} (${SPEED}): \033[1;37m${IP}\033[0m"
|
||||
[ -z "${IPCON}" ] && IPCON="${IP}"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
if [ -z "$(cat /sys/class/net/${N}}/carrier 2>/dev/null)" ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mDOWN\033[0m"
|
||||
break
|
||||
fi
|
||||
if [ ${COUNT} -ge ${BOOTIPWAIT} ]; then
|
||||
echo -e "\r${DRIVER}: \033[1;37mTIMEOUT\033[0m"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
done
|
||||
echo
|
||||
|
||||
mkdir -p "${ADDONS_PATH}"
|
||||
mkdir -p "${CUSTOM_PATH}"
|
||||
mkdir -p "${LKMS_PATH}"
|
||||
mkdir -p "${MODEL_CONFIG_PATH}"
|
||||
mkdir -p "${MODULES_PATH}"
|
||||
mkdir -p "${PATCH_PATH}"
|
||||
mkdir -p "${USER_UP_PATH}"
|
||||
|
||||
# Load Arc Overlay
|
||||
echo -e "\033[1;34mLoading Arc Overlay...\033[0m"
|
||||
echo
|
||||
echo -e "Use \033[1;34mDisplay Output\033[0m or \033[1;34mhttp://${IPCON}:${TTYDPORT}\033[0m to configure Loader."
|
||||
|
||||
# Check memory and load Arc
|
||||
RAM=$(awk '/MemTotal:/ {printf "%.0f", $2 / 1024}' /proc/meminfo 2>/dev/null)
|
||||
if [ ${RAM} -le 3500 ]; then
|
||||
echo -e "\033[1;31mYou have less than 4GB of RAM, if errors occur in loader creation, please increase the amount of RAM.\033[0m\n\033[1;31mUse arc.sh to proceed. Not recommended!\033[0m"
|
||||
else
|
||||
arc.sh
|
||||
fi
|
||||
|
||||
exit 0
|
||||
BIN
files/initrd/opt/arc/kpatch
Executable file
BIN
files/initrd/opt/arc/kpatch
Executable file
Binary file not shown.
259
files/initrd/opt/arc/ramdisk-patch.sh
Executable file
259
files/initrd/opt/arc/ramdisk-patch.sh
Executable file
@@ -0,0 +1,259 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/functions.sh
|
||||
. ${ARC_PATH}/include/addons.sh
|
||||
. ${ARC_PATH}/include/modules.sh
|
||||
|
||||
set -o pipefail # Get exit code from process piped
|
||||
|
||||
# Sanity check
|
||||
if [ ! -f "${ORI_RDGZ_FILE}" ]; then
|
||||
echo "ERROR: ${ORI_RDGZ_FILE} not found!" >"${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove old rd.gz patched
|
||||
rm -f "${MOD_RDGZ_FILE}"
|
||||
|
||||
# Unzipping ramdisk
|
||||
rm -rf "${RAMDISK_PATH}"
|
||||
mkdir -p "${RAMDISK_PATH}"
|
||||
(
|
||||
cd "${RAMDISK_PATH}"
|
||||
xz -dc <"${ORI_RDGZ_FILE}" | cpio -idm
|
||||
) >/dev/null 2>&1
|
||||
|
||||
# Read Model Data
|
||||
PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
|
||||
MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")"
|
||||
MODELID="$(readConfigKey "modelid" "${USER_CONFIG_FILE}")"
|
||||
LKM="$(readConfigKey "lkm" "${USER_CONFIG_FILE}")"
|
||||
SN="$(readConfigKey "sn" "${USER_CONFIG_FILE}")"
|
||||
LAYOUT="$(readConfigKey "layout" "${USER_CONFIG_FILE}")"
|
||||
KEYMAP="$(readConfigKey "keymap" "${USER_CONFIG_FILE}")"
|
||||
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
RD_COMPRESSED="$(readConfigKey "rd-compressed" "${USER_CONFIG_FILE}")"
|
||||
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
BUILDNUM="$(readConfigKey "buildnum" "${USER_CONFIG_FILE}")"
|
||||
SMALLNUM="$(readConfigKey "smallnum" "${USER_CONFIG_FILE}")"
|
||||
ARCBRANCH="$(readConfigKey "arc.branch" "${USER_CONFIG_FILE}")"
|
||||
# Read new PAT Info from Config
|
||||
PAT_URL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
|
||||
PAT_HASH="$(readConfigKey "pathash" "${USER_CONFIG_FILE}")"
|
||||
|
||||
[ "${PATURL:0:1}" == "#" ] && PATURL=""
|
||||
[ "${PATSUM:0:1}" == "#" ] && PATSUM=""
|
||||
|
||||
# Check if DSM Version changed
|
||||
. "${RAMDISK_PATH}/etc/VERSION"
|
||||
|
||||
if [[ -n "${PRODUCTVER}" && -n "${BUILDNUM}" && -n "${SMALLNUM}" ]] &&
|
||||
([ "${PRODUCTVER}" != "${majorversion}.${minorversion}" ] || [ "${BUILDNUM}" != "${buildnumber}" ] || [ "${SMALLNUM}" != "${smallfixnumber}" ]); then
|
||||
OLDVER="${PRODUCTVER}(${BUILDNUM}$([ ${SMALLNUM:-0} -ne 0 ] && echo "u${SMALLNUM}"))"
|
||||
NEWVER="${majorversion}.${minorversion}(${buildnumber}$([ ${smallfixnumber:-0} -ne 0 ] && echo "u${smallfixnumber}"))"
|
||||
PAT_URL=""
|
||||
PAT_HASH=""
|
||||
fi
|
||||
PRODUCTVER=${majorversion}.${minorversion}
|
||||
BUILDNUM=${buildnumber}
|
||||
SMALLNUM=${smallfixnumber}
|
||||
writeConfigKey "productver" "${PRODUCTVER}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "buildnum" "${BUILDNUM}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "smallnum" "${SMALLNUM}" "${USER_CONFIG_FILE}"
|
||||
|
||||
# Read model data
|
||||
KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")"
|
||||
|
||||
# Modify KVER for Epyc7002
|
||||
[ "${PLATFORM}" == "epyc7002" ] && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}"
|
||||
|
||||
# Sanity check
|
||||
if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ]; then
|
||||
echo "ERROR: Configuration for model ${MODEL} and productversion ${PRODUCTVER} not found." >"${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
declare -A SYNOINFO
|
||||
declare -A ADDONS
|
||||
declare -A MODULES
|
||||
|
||||
# Read synoinfo and addons from config
|
||||
while IFS=': ' read -r KEY VALUE; do
|
||||
[ -n "${KEY}" ] && SYNOINFO["${KEY}"]="${VALUE}"
|
||||
done < <(readConfigMap "synoinfo" "${USER_CONFIG_FILE}")
|
||||
while IFS=': ' read -r KEY VALUE; do
|
||||
[ -n "${KEY}" ] && ADDONS["${KEY}"]="${VALUE}"
|
||||
done < <(readConfigMap "addons" "${USER_CONFIG_FILE}")
|
||||
|
||||
# Read modules from user config
|
||||
while IFS=': ' read -r KEY VALUE; do
|
||||
[ -n "${KEY}" ] && MODULES["${KEY}"]="${VALUE}"
|
||||
done < <(readConfigMap "modules" "${USER_CONFIG_FILE}")
|
||||
|
||||
# Patches (diff -Naru OLDFILE NEWFILE > xxx.patch)
|
||||
PATCHES=()
|
||||
PATCHES+=("ramdisk-etc-rc-*.patch")
|
||||
PATCHES+=("ramdisk-init-script-*.patch")
|
||||
PATCHES+=("ramdisk-post-init-script-*.patch")
|
||||
PATCHES+=("ramdisk-disable-root-pwd-*.patch")
|
||||
PATCHES+=("ramdisk-disable-disabled-ports-*.patch")
|
||||
for PE in ${PATCHES[@]}; do
|
||||
RET=1
|
||||
echo "Patching with ${PE}" >"${LOG_FILE}"
|
||||
for PF in $(ls ${PATCH_PATH}/${PE} 2>/dev/null); do
|
||||
echo "Patching with ${PF}" >>"${LOG_FILE}"
|
||||
(
|
||||
cd "${RAMDISK_PATH}"
|
||||
patch -p1 -i "${PF}" >>"${LOG_FILE}" 2>&1 # busybox patch and gun patch have different processing methods and parameters.
|
||||
)
|
||||
RET=$?
|
||||
[ ${RET} -eq 0 ] && break
|
||||
done
|
||||
[ ${RET} -ne 0 ] && exit 1
|
||||
done
|
||||
|
||||
# Add serial number to synoinfo.conf, to help to recovery a installed DSM
|
||||
echo "Set synoinfo SN" >"${LOG_FILE}"
|
||||
_set_conf_kv "SN" "${SN}" "${RAMDISK_PATH}/etc/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
_set_conf_kv "SN" "${SN}" "${RAMDISK_PATH}/etc.defaults/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
for KEY in ${!SYNOINFO[@]}; do
|
||||
echo "Set synoinfo ${KEY}" >>"${LOG_FILE}"
|
||||
_set_conf_kv "${KEY}" "${SYNOINFO[${KEY}]}" "${RAMDISK_PATH}/etc/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
_set_conf_kv "${KEY}" "${SYNOINFO[${KEY}]}" "${RAMDISK_PATH}/etc.defaults/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
done
|
||||
|
||||
# Patch /sbin/init.post
|
||||
grep -v -e '^[\t ]*#' -e '^$' "${PATCH_PATH}/config-manipulators.sh" >"${TMP_PATH}/rp.txt"
|
||||
sed -e "/@@@CONFIG-MANIPULATORS-TOOLS@@@/ {" -e "r ${TMP_PATH}/rp.txt" -e 'd' -e '}' -i "${RAMDISK_PATH}/sbin/init.post"
|
||||
rm -f "${TMP_PATH}/rp.txt"
|
||||
touch "${TMP_PATH}/rp.txt"
|
||||
echo "_set_conf_kv 'SN' '${SN}' '/tmpRoot/etc/synoinfo.conf'" >>"${TMP_PATH}/rp.txt"
|
||||
echo "_set_conf_kv 'SN' '${SN}' '/tmpRoot/etc.defaults/synoinfo.conf'" >>"${TMP_PATH}/rp.txt"
|
||||
for KEY in ${!SYNOINFO[@]}; do
|
||||
echo "_set_conf_kv '${KEY}' '${SYNOINFO[${KEY}]}' '/tmpRoot/etc/synoinfo.conf'" >>"${TMP_PATH}/rp.txt"
|
||||
echo "_set_conf_kv '${KEY}' '${SYNOINFO[${KEY}]}' '/tmpRoot/etc.defaults/synoinfo.conf'" >>"${TMP_PATH}/rp.txt"
|
||||
done
|
||||
sed -e "/@@@CONFIG-GENERATED@@@/ {" -e "r ${TMP_PATH}/rp.txt" -e 'd' -e '}' -i "${RAMDISK_PATH}/sbin/init.post"
|
||||
rm -f "${TMP_PATH}/rp.txt"
|
||||
|
||||
# Extract Modules to Ramdisk
|
||||
installModules "${PLATFORM}" "${KVERP}" "${!MODULES[@]}" || exit 1
|
||||
|
||||
# Copying fake modprobe
|
||||
[ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 5 ] && cp -f "${PATCH_PATH}/iosched-trampoline.sh" "${RAMDISK_PATH}/usr/sbin/modprobe"
|
||||
# Copying LKM to /usr/lib/modules
|
||||
gzip -dc "${LKMS_PATH}/rp-${PLATFORM}-${KVERP}-${LKM}.ko.gz" >"${RAMDISK_PATH}/usr/lib/modules/rp.ko" 2>"${LOG_FILE}" || exit 1
|
||||
|
||||
# Addons
|
||||
echo "Create addons.sh" >"${LOG_FILE}"
|
||||
mkdir -p "${RAMDISK_PATH}/addons"
|
||||
echo "#!/bin/sh" >"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo 'echo "addons.sh called with params ${@}"' >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export LOADERLABEL=\"ARC\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export LOADERVERSION=\"${ARC_VERSION}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export LOADERBUILD=\"${ARC_BUILD}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export LOADERBRANCH=\"${ARCBRANCH}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export PLATFORM=\"${PLATFORM}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export PRODUCTVER=\"${PRODUCTVER}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export MODEL=\"${MODEL}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export MODELID=\"${MODELID}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export MLINK=\"${PAT_URL}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export MCHECKSUM=\"${PAT_HASH}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export LAYOUT=\"${LAYOUT}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
echo "export KEYMAP=\"${KEYMAP}\"" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
chmod +x "${RAMDISK_PATH}/addons/addons.sh"
|
||||
|
||||
# System Addons
|
||||
for ADDON in "redpill" "revert" "misc" "eudev" "disks" "localrss" "notify" "wol" "mountloader"; do
|
||||
PARAMS=""
|
||||
if [ "${ADDON}" == "disks" ]; then
|
||||
HDDSORT="$(readConfigKey "hddsort" "${USER_CONFIG_FILE}")"
|
||||
USBMOUNT="$(readConfigKey "usbmount" "${USER_CONFIG_FILE}")"
|
||||
PARAMS="${HDDSORT} ${USBMOUNT}"
|
||||
[ -f "${USER_UP_PATH}/${MODEL}.dts" ] && cp -f "${USER_UP_PATH}/${MODEL}.dts" "${RAMDISK_PATH}/addons/model.dts"
|
||||
fi
|
||||
installAddon "${ADDON}" "${PLATFORM}" || exit 1
|
||||
echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >>"${RAMDISK_PATH}/addons/addons.sh" 2>>"${LOG_FILE}" || exit 1
|
||||
done
|
||||
|
||||
# User Addons
|
||||
for ADDON in ${!ADDONS[@]}; do
|
||||
PARAMS=${ADDONS[${ADDON}]}
|
||||
installAddon "${ADDON}" "${PLATFORM}" || echo "Addon ${ADDON} not found"
|
||||
echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >>"${RAMDISK_PATH}/addons/addons.sh" 2>>"${LOG_FILE}" || exit 1
|
||||
done
|
||||
|
||||
# Enable Telnet
|
||||
echo "inetd" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
|
||||
echo "Modify files" >"${LOG_FILE}"
|
||||
# Remove function from scripts
|
||||
[ "2" == "${PRODUCTVER:0:1}" ] && sed -i 's/function //g' $(find "${RAMDISK_PATH}/addons/" -type f -name "*.sh")
|
||||
|
||||
# Build modules dependencies
|
||||
# ${ARC_PATH}/depmod -a -b ${RAMDISK_PATH} 2>/dev/null
|
||||
|
||||
# Copying modulelist
|
||||
if [ -f "${USER_UP_PATH}/modulelist" ]; then
|
||||
cp -f "${USER_UP_PATH}/modulelist" "${RAMDISK_PATH}/addons/modulelist"
|
||||
else
|
||||
cp -f "${ARC_PATH}/include/modulelist" "${RAMDISK_PATH}/addons/modulelist"
|
||||
fi
|
||||
|
||||
# backup current loader configs
|
||||
BACKUP_PATH="${RAMDISK_PATH}/usr/arc/backup"
|
||||
rm -rf "${BACKUP_PATH}"
|
||||
for F in "${USER_GRUB_CONFIG}" "${USER_CONFIG_FILE}" "${USER_UP_PATH}"; do
|
||||
if [ -f "${F}" ]; then
|
||||
FD="$(dirname "${F}")"
|
||||
mkdir -p "${FD/\/mnt/${BACKUP_PATH}}"
|
||||
cp -f "${F}" "${FD/\/mnt/${BACKUP_PATH}}"
|
||||
elif [ -d "${F}" ]; then
|
||||
SIZE="$(du -sm "${F}" 2>/dev/null | awk '{print $1}')"
|
||||
if [ ${SIZE:-0} -gt 4 ]; then
|
||||
echo "Backup of ${F} skipped, size is ${SIZE}MB" >>"${LOG_FILE}"
|
||||
continue
|
||||
fi
|
||||
FD="$(dirname "${F}")"
|
||||
mkdir -p "${FD/\/mnt/${BACKUP_PATH}}"
|
||||
cp -rf "${F}" "${FD/\/mnt/${BACKUP_PATH}}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Network card configuration file
|
||||
for N in $(seq 0 7); do
|
||||
echo -e "DEVICE=eth${N}\nBOOTPROTO=dhcp\nONBOOT=yes\nIPV6INIT=dhcp\nIPV6_ACCEPT_RA=1" >"${RAMDISK_PATH}/etc/sysconfig/network-scripts/ifcfg-eth${N}"
|
||||
done
|
||||
|
||||
# SA6400 patches
|
||||
if [ "${PLATFORM}" == "epyc7002" ]; then
|
||||
echo -n " - Apply Epyc7002 Fixes"
|
||||
sed -i 's#/dev/console#/var/log/lrc#g' ${RAMDISK_PATH}/usr/bin/busybox
|
||||
sed -i '/^echo "START/a \\nmknod -m 0666 /dev/console c 1 3' ${RAMDISK_PATH}/linuxrc.syno
|
||||
fi
|
||||
|
||||
# Broadwellntbap patches
|
||||
if [ "${PLATFORM}" == "broadwellntbap" ]; then
|
||||
echo -n " - Apply Broadwellntbap Fixes"
|
||||
sed -i 's/IsUCOrXA="yes"/XIsUCOrXA="yes"/g; s/IsUCOrXA=yes/XIsUCOrXA=yes/g' ${RAMDISK_PATH}/usr/syno/share/environments.sh
|
||||
fi
|
||||
|
||||
# Call user patch scripts
|
||||
for F in $(ls -1 ${USER_UP_PATH}/*.sh 2>/dev/null); do
|
||||
echo "Calling ${F}" >"${LOG_FILE}"
|
||||
. "${F}" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
done
|
||||
|
||||
# Reassembly ramdisk
|
||||
if [ "${RD_COMPRESSED}" == "true" ]; then
|
||||
(cd "${RAMDISK_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root | xz -9 --format=lzma >"${MOD_RDGZ_FILE}") >"${LOG_FILE}" 2>&1 || exit 1
|
||||
else
|
||||
(cd "${RAMDISK_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root >"${MOD_RDGZ_FILE}") >"${LOG_FILE}" 2>&1 || exit 1
|
||||
fi
|
||||
|
||||
sync
|
||||
|
||||
# Clean
|
||||
rm -rf "${RAMDISK_PATH}"
|
||||
82
files/initrd/opt/arc/vmlinux-to-bzImage.sh
Executable file
82
files/initrd/opt/arc/vmlinux-to-bzImage.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
# Based on code and ideas from @jumkey
|
||||
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/functions.sh
|
||||
|
||||
PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
|
||||
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")"
|
||||
|
||||
# Adapted from: scripts/Makefile.lib
|
||||
# Usage: size_append FILE [FILE2] [FILEn]...
|
||||
# Output: LE HEX with size of file in bytes (to STDOUT)
|
||||
file_size_le() {
|
||||
printf $(
|
||||
dec_size=0
|
||||
for F in "${@}"; do
|
||||
fsize=$(stat -c "%s" ${F})
|
||||
dec_size=$((${dec_size} + ${fsize}))
|
||||
done
|
||||
printf "%08x\n" ${dec_size} |
|
||||
sed 's/\(..\)/\1 /g' | {
|
||||
read ch0 ch1 ch2 ch3
|
||||
for ch in ${ch3} ${ch2} ${ch1} ${ch0}; do
|
||||
printf '%s%03o' '\' $((0x${ch}))
|
||||
done
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
size_le() {
|
||||
printf $(
|
||||
printf "%08x\n" "${@}" |
|
||||
sed 's/\(..\)/\1 /g' | {
|
||||
read ch0 ch1 ch2 ch3
|
||||
for ch in ${ch3} ${ch2} ${ch1} ${ch0}; do
|
||||
printf '%s%03o' '\' $((0x${ch}))
|
||||
done
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
VMLINUX_MOD=${1}
|
||||
ZIMAGE_MOD=${2}
|
||||
KVER_MAJOR=${KVER:0:1}
|
||||
if [ ${KVER_MAJOR} -eq 4 ]; then
|
||||
# Kernel version 4.x or 3.x (bromolow)
|
||||
#zImage_head 16494
|
||||
#payload(
|
||||
# vmlinux.bin x
|
||||
# padding 0xf00000-x
|
||||
# vmlinux.bin size 4
|
||||
#) 0xf00004
|
||||
#zImage_tail(
|
||||
# unknown 72
|
||||
# run_size 4
|
||||
# unknown 30
|
||||
# vmlinux.bin size 4
|
||||
# unknown 114460
|
||||
#) 114570
|
||||
#crc32 4
|
||||
gzip -dc "${ARC_PATH}/bzImage-template-v4.gz" >"${ZIMAGE_MOD}" || exit 1
|
||||
|
||||
dd if="${VMLINUX_MOD}" of="${ZIMAGE_MOD}" bs=16494 seek=1 conv=notrunc || exit 1
|
||||
file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=15745134 seek=1 conv=notrunc || exit 1
|
||||
file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=15745244 seek=1 conv=notrunc || exit 1
|
||||
|
||||
RUN_SIZE=$(objdump -h ${VMLINUX_MOD} | sh "${ARC_PATH}/calc_run_size.sh")
|
||||
size_le ${RUN_SIZE} | dd of=${ZIMAGE_MOD} bs=15745210 seek=1 conv=notrunc|| exit 1
|
||||
size_le $(($((16#$(crc32 "${ZIMAGE_MOD}" | awk '{print $1}'))) ^ 0xFFFFFFFF)) | dd of="${ZIMAGE_MOD}" conv=notrunc oflag=append || exit 1
|
||||
else
|
||||
# Kernel version 5.x
|
||||
gzip -dc "${ARC_PATH}/bzImage-template-v5.gz" >"${ZIMAGE_MOD}" || exit 1
|
||||
|
||||
dd if="${VMLINUX_MOD}" of="${ZIMAGE_MOD}" bs=14561 seek=1 conv=notrunc || exit 1
|
||||
file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=34463421 seek=1 conv=notrunc || exit 1
|
||||
file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=34479132 seek=1 conv=notrunc || exit 1
|
||||
# RUN_SIZE=$(objdump -h ${VMLINUX_MOD} | sh "${ARC_PATH}/calc_run_size.sh")
|
||||
# size_le ${RUN_SIZE} | dd of=${ZIMAGE_MOD} bs=34626904 seek=1 conv=notrunc || exit 1
|
||||
size_le $(($((16#$(crc32 "${ZIMAGE_MOD}" | awk '{print $1}'))) ^ 0xFFFFFFFF)) | dd of="${ZIMAGE_MOD}" conv=notrunc oflag=append || exit 1
|
||||
fi
|
||||
33
files/initrd/opt/arc/zimage-patch.sh
Executable file
33
files/initrd/opt/arc/zimage-patch.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
[[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
||||
|
||||
. ${ARC_PATH}/include/functions.sh
|
||||
|
||||
set -o pipefail # Get exit code from process piped
|
||||
|
||||
# Sanity check
|
||||
[ -f "${ORI_ZIMAGE_FILE}" ] || (die "${ORI_ZIMAGE_FILE} not found!" | tee -a "${LOG_FILE}")
|
||||
|
||||
rm -f "${MOD_ZIMAGE_FILE}"
|
||||
|
||||
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
|
||||
if [ "${KERNEL}" == "custom" ]; then
|
||||
echo -n " - Using customized Kernel"
|
||||
PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
|
||||
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")"
|
||||
# Modify KVER for Epyc7002
|
||||
[ "${PLATFORM}" == "epyc7002" ] && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}"
|
||||
# Extract bzImage
|
||||
gzip -dc "${CUSTOM_PATH}/bzImage-${PLATFORM}-${KVERP}.gz" >"${MOD_ZIMAGE_FILE}"
|
||||
else
|
||||
# Extract vmlinux
|
||||
${ARC_PATH}/bzImage-to-vmlinux.sh "${ORI_ZIMAGE_FILE}" "${TMP_PATH}/vmlinux" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
# Patch boot params and ramdisk check
|
||||
${ARC_PATH}/kpatch "${TMP_PATH}/vmlinux" "${TMP_PATH}/vmlinux-mod" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
# rebuild zImage
|
||||
${ARC_PATH}/vmlinux-to-bzImage.sh "${TMP_PATH}/vmlinux-mod" "${MOD_ZIMAGE_FILE}" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
fi
|
||||
|
||||
sync
|
||||
1
files/p1/ARC-VERSION
Normal file
1
files/p1/ARC-VERSION
Normal file
@@ -0,0 +1 @@
|
||||
23.1.1
|
||||
19
files/p1/EFI/BOOT/SynoBootLoader.conf
Normal file
19
files/p1/EFI/BOOT/SynoBootLoader.conf
Normal file
@@ -0,0 +1,19 @@
|
||||
serial --unit=1 --speed=115200
|
||||
terminal serial
|
||||
default 1
|
||||
timeout 3
|
||||
verbose
|
||||
hiddenmenu
|
||||
fallback 0
|
||||
|
||||
title SYNOLOGY_1
|
||||
root (hd0,0)
|
||||
kernel /zImage root=/dev/md0
|
||||
initrd /rd.gz
|
||||
|
||||
title SYNOLOGY_2
|
||||
root (hd0,1)
|
||||
cksum /grub_cksum.syno
|
||||
vender /vender show
|
||||
kernel /zImage root=/dev/md0
|
||||
initrd /rd.gz
|
||||
0
files/p1/EFI/BOOT/SynoBootLoader.efi
Normal file
0
files/p1/EFI/BOOT/SynoBootLoader.efi
Normal file
200
files/p1/boot/grub/grub.cfg
Normal file
200
files/p1/boot/grub/grub.cfg
Normal file
@@ -0,0 +1,200 @@
|
||||
insmod search
|
||||
insmod echo
|
||||
insmod terminal
|
||||
insmod test
|
||||
insmod font
|
||||
insmod loadenv
|
||||
insmod serial
|
||||
insmod usb_keyboard
|
||||
insmod linux
|
||||
insmod gzio
|
||||
insmod fat
|
||||
insmod ext2
|
||||
insmod ata
|
||||
insmod btrfs
|
||||
insmod ntfs
|
||||
insmod part_msdos
|
||||
insmod part_gpt
|
||||
|
||||
set default="boot"
|
||||
set timeout="5"
|
||||
set timeout_style="menu"
|
||||
set vesa_mode=1
|
||||
|
||||
if [ -s $prefix/grubenv ]; then
|
||||
load_env
|
||||
fi
|
||||
if [ "${next_entry}" ]; then
|
||||
set default="${next_entry}"
|
||||
unset next_entry
|
||||
save_env next_entry
|
||||
fi
|
||||
if [ "${vesa_mode}" ]; then
|
||||
set vesa_mode=${vesa_mode}
|
||||
fi
|
||||
|
||||
function load_video {
|
||||
if [ x$feature_all_video_module = xy ]; then
|
||||
insmod all_video
|
||||
else
|
||||
insmod efi_gop
|
||||
insmod efi_uga
|
||||
insmod ieee1275_fb
|
||||
insmod vbe
|
||||
insmod vga
|
||||
insmod video_bochs
|
||||
insmod video_cirrus
|
||||
fi
|
||||
}
|
||||
|
||||
load_video
|
||||
if loadfont unicode; then
|
||||
insmod gfxterm
|
||||
set gfxmode=1024x768
|
||||
set gfxpayload=auto
|
||||
terminal_output gfxterm
|
||||
insmod gfxmenu
|
||||
loadfont ${prefix}/theme/dejavu_bold_14.pf2
|
||||
loadfont ${prefix}/theme/dejavu_mono_12.pf2
|
||||
insmod png
|
||||
set theme=${prefix}/theme/theme.txt
|
||||
export theme
|
||||
fi
|
||||
|
||||
if serial --unit=0 --speed=115200; then
|
||||
terminal_input --append serial_com0
|
||||
terminal_output --append serial_com0
|
||||
fi
|
||||
|
||||
function set_gfxpayload {
|
||||
if [ ${vesa_mode} -eq 1 ]; then
|
||||
set gfxpayload=keep
|
||||
else
|
||||
set gfxpayload=text
|
||||
fi
|
||||
}
|
||||
|
||||
set menu_color_normal=white/black
|
||||
set menu_color_highlight=white/red
|
||||
set color_normal=white/black
|
||||
|
||||
set ARC_CMDLINE="earlyprintk earlycon=uart8250,io,0x3f8,115200n8 console=ttyS0,115200n8 root=/dev/ram rootwait net.ifnames=0 panic=5 split_lock_detect=off pcie_aspm=off intel_pstate=disable"
|
||||
|
||||
search --set=root --label "ARC3"
|
||||
if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
if [ "${default}" = "direct" ]; then
|
||||
set timeout="1"
|
||||
menuentry 'DSM Direct Mode' --id direct {
|
||||
set_gfxpayload
|
||||
echo "Loading DSM Kernel..."
|
||||
linux /zImage-dsm ${dsm_cmdline}
|
||||
echo "Loading DSM Initramfs..."
|
||||
initrd /initrd-dsm
|
||||
echo "Booting..."
|
||||
echo "Access http://find.synology.com/ to connect the DSM via web."
|
||||
}
|
||||
fi
|
||||
menuentry 'Arc DSM Mode' --id boot {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline}
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
fi
|
||||
|
||||
if [ -e /automated ]; then
|
||||
menuentry 'Arc Automated Mode' --id automated {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} automated_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
fi
|
||||
|
||||
menuentry 'Arc Config Mode' --id config {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
|
||||
if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
menuentry 'Arc Update Mode' --id update {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} update_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
menuentry 'DSM Recovery Mode' --id recovery {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} recovery
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
menuentry 'DSM Reinstall Mode' --id junior {
|
||||
set_gfxpayload
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_junior
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
else
|
||||
initrd /initrd-arc
|
||||
fi
|
||||
echo "Booting..."
|
||||
}
|
||||
fi
|
||||
|
||||
menuentry 'Enter BIOS Setup' --id bios {
|
||||
fwsetup
|
||||
}
|
||||
|
||||
menuentry 'Start Memtest86+' --id memtest {
|
||||
echo "Loading memtest86+..."
|
||||
linux ${prefix}/memtest
|
||||
}
|
||||
|
||||
if [ ${vesa_mode} = 1 ]; then
|
||||
menuentry 'Change Vesa to Text Output' --id videomode {
|
||||
set vesa_mode=0
|
||||
save_env vesa_mode
|
||||
configfile ${prefix}/grub.cfg
|
||||
}
|
||||
else
|
||||
menuentry 'Change Text to Vesa Output' --id videomode {
|
||||
set vesa_mode=1
|
||||
save_env vesa_mode
|
||||
reboot
|
||||
configfile ${prefix}/grub.cfg
|
||||
}
|
||||
fi
|
||||
BIN
files/p1/boot/grub/memtest
Executable file
BIN
files/p1/boot/grub/memtest
Executable file
Binary file not shown.
0
files/p3/addons/.gitkeep
Normal file
0
files/p3/addons/.gitkeep
Normal file
0
files/p3/configs/.gitkeep
Normal file
0
files/p3/configs/.gitkeep
Normal file
0
files/p3/custom/.gitkeep
Normal file
0
files/p3/custom/.gitkeep
Normal file
BIN
files/p3/extractor/libcurl.so.4
Executable file
BIN
files/p3/extractor/libcurl.so.4
Executable file
Binary file not shown.
BIN
files/p3/extractor/libmbedcrypto.so.5
Executable file
BIN
files/p3/extractor/libmbedcrypto.so.5
Executable file
Binary file not shown.
BIN
files/p3/extractor/libmbedtls.so.13
Executable file
BIN
files/p3/extractor/libmbedtls.so.13
Executable file
Binary file not shown.
BIN
files/p3/extractor/libmbedx509.so.1
Executable file
BIN
files/p3/extractor/libmbedx509.so.1
Executable file
Binary file not shown.
BIN
files/p3/extractor/libmsgpackc.so.2
Executable file
BIN
files/p3/extractor/libmsgpackc.so.2
Executable file
Binary file not shown.
BIN
files/p3/extractor/libsodium.so
Executable file
BIN
files/p3/extractor/libsodium.so
Executable file
Binary file not shown.
BIN
files/p3/extractor/libsynocodesign-ng-virtual-junior-wins.so.7
Executable file
BIN
files/p3/extractor/libsynocodesign-ng-virtual-junior-wins.so.7
Executable file
Binary file not shown.
BIN
files/p3/extractor/syno_extract_system_patch
Executable file
BIN
files/p3/extractor/syno_extract_system_patch
Executable file
Binary file not shown.
0
files/p3/lkms/.gitkeep
Normal file
0
files/p3/lkms/.gitkeep
Normal file
0
files/p3/modules/.gitkeep
Normal file
0
files/p3/modules/.gitkeep
Normal file
0
files/p3/patches/.gitkeep
Normal file
0
files/p3/patches/.gitkeep
Normal file
65
img-gen-n.sh
Executable file
65
img-gen-n.sh
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Clean cached Files
|
||||
sudo git clean -fdx
|
||||
|
||||
. scripts/func.sh
|
||||
|
||||
# Get extractor, LKM, addons and Modules
|
||||
echo "Get Dependencies"
|
||||
getAddons "files/p3/addons"
|
||||
getModules "files/p3/modules"
|
||||
getConfigs "files/p3/configs"
|
||||
getPatches "files/p3/patches"
|
||||
getCustom "files/p3/custom"
|
||||
getLKMs "files/p3/lkms"
|
||||
getTheme "files/p1/boot/grub"
|
||||
getOffline "files/p3/configs"
|
||||
getBuildrootx "brx"
|
||||
|
||||
# Sbase
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
sudo rm -rf "/tmp/p1"
|
||||
sudo rm -rf "/tmp/p3"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[[ ! -f "brx/bzImage-arc" || ! -f "brx/initrd-arc" ]] && return 1
|
||||
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="13.37.dev"
|
||||
ARC_BRANCH="next"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brx/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brx/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brx/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
65
img-gen-s.sh
Executable file
65
img-gen-s.sh
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Clean cached Files
|
||||
sudo git clean -fdx
|
||||
|
||||
. scripts/func.sh
|
||||
|
||||
# Get extractor, LKM, addons and Modules
|
||||
echo "Get Dependencies"
|
||||
getAddons "files/p3/addons"
|
||||
getModules "files/p3/modules"
|
||||
getConfigs "files/p3/configs"
|
||||
getPatches "files/p3/patches"
|
||||
getCustom "files/p3/custom"
|
||||
getLKMs "files/p3/lkms"
|
||||
getTheme "files/p1/boot/grub"
|
||||
getOffline "files/p3/configs"
|
||||
getBuildroots "brs"
|
||||
|
||||
# Sbase
|
||||
IMAGE_FILE="arc.img"
|
||||
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
|
||||
fdisk -l "${IMAGE_FILE}"
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||
|
||||
echo "Mounting Image File"
|
||||
sudo rm -rf "/tmp/p1"
|
||||
sudo rm -rf "/tmp/p3"
|
||||
mkdir -p "/tmp/p1"
|
||||
mkdir -p "/tmp/p3"
|
||||
sudo mount ${LOOPX}p1 "/tmp/p1"
|
||||
sudo mount ${LOOPX}p3 "/tmp/p3"
|
||||
|
||||
[[ ! -f "brs/bzImage-arc" || ! -f "brs/initrd-arc" ]] && return 1
|
||||
|
||||
ARC_BUILD="`date +'%y%m%d'`"
|
||||
ARC_VERSION="13.37.dev"
|
||||
ARC_BRANCH="stable"
|
||||
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
|
||||
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
|
||||
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
|
||||
|
||||
echo "Repack initrd"
|
||||
cp -f "brs/bzImage-arc" "files/p3/bzImage-arc"
|
||||
#cp -f "brs/initrd-arc" "files/p3/initrd-arc"
|
||||
repackInitrd "brs/initrd-arc" "files/initrd" "files/p3/initrd-arc"
|
||||
|
||||
echo "Copying files"
|
||||
sudo cp -rf "files/p1/"* "/tmp/p1"
|
||||
sudo cp -rf "files/p3/"* "/tmp/p3"
|
||||
sync
|
||||
|
||||
echo "Unmount image file"
|
||||
sudo umount "/tmp/p1"
|
||||
sudo umount "/tmp/p3"
|
||||
rmdir "/tmp/p1"
|
||||
rmdir "/tmp/p3"
|
||||
|
||||
sudo losetup --detach ${LOOPX}
|
||||
|
||||
qemu-img convert ${IMAGE_FILE} -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat arc.vmdk
|
||||
12
kpatch/Makefile
Normal file
12
kpatch/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
CFLAGS = -Wall -pedantic
|
||||
LDFLAGS =
|
||||
LIBS = /lib/x86_64-linux-gnu/libelf.a /lib/x86_64-linux-gnu/libz.a
|
||||
|
||||
all: kpatch
|
||||
|
||||
kpatch: main.o
|
||||
cc $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f kpatch *.o
|
||||
BIN
kpatch/kpatch
Executable file
BIN
kpatch/kpatch
Executable file
Binary file not shown.
492
kpatch/main.c
Normal file
492
kpatch/main.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Fabio Belavenuto <belavenuto@gmail.com>
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Converted from php code by Fabio Belavenuto <belavenuto@gmail.com>
|
||||
*
|
||||
* A quick tool for patching the boot_params check in the DSM kernel image
|
||||
* This lets you tinker with the initial ramdisk contents without disabling mount() features and modules loading
|
||||
*
|
||||
* The overall pattern we need to find is:
|
||||
* - an CDECL function
|
||||
* - does "LOCK OR [const-ptr],n" 4x
|
||||
* - values of ORs are 1/2/4/8 respectively
|
||||
* - [const-ptr] is always the same
|
||||
*
|
||||
* Added patch for CMOS_WRITE by Fabio Belavenuto
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <gelf.h>
|
||||
|
||||
const int DIR_FWD = 1;
|
||||
const int DIR_RWD = -1;
|
||||
|
||||
/* Variables */
|
||||
int fd, verbose = 1, read_only = 0;
|
||||
Elf *elfHandle;
|
||||
GElf_Ehdr elfExecHeader;
|
||||
uint64_t orPos[4], fileSize, rodataAddr, rodataOffs, initTextOffs;
|
||||
unsigned char *fileData;
|
||||
|
||||
/*****************************************************************************/
|
||||
void errorMsg(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void errorNum()
|
||||
{
|
||||
char str[100] = {0};
|
||||
perror(str);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void elfErrno()
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = elf_errno()) != 0)
|
||||
{
|
||||
fprintf(stderr, "%s\n", elf_errmsg(err));
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// Finding a function boundary is non-trivial really as patters can vary, we can have multiple exit points, and in CISC
|
||||
// there are many things which may match e.g. "PUSH EBP". Implementing even a rough disassembler is pointless.
|
||||
// However, we can certainly cheat here as we know with CDECL a non-empty function will always contain one or more
|
||||
// PUSH (0x41) R12-R15 (0x54-57) sequences. Then we can search like a 1K forward for these characteristic LOCK OR.
|
||||
uint64_t findPUSH_R12_R15_SEQ(uint64_t start)
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
for (i = start; i < fileSize; i++)
|
||||
{
|
||||
if (fileData[i] == 0x41 && (fileData[i + 1] >= 0x54 && fileData[i + 1] <= 0x57))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
//[0xF0, 0x80, null, null, null, null, null, 0xXX],
|
||||
uint64_t findORs(uint64_t start, uint32_t maxCheck)
|
||||
{
|
||||
uint64_t i;
|
||||
int c = 0;
|
||||
uint8_t lb = 0x01;
|
||||
|
||||
for (i = start; i < fileSize; i++)
|
||||
{
|
||||
if (fileData[i] == 0xF0 && fileData[i + 1] == 0x80 && fileData[i + 7] == lb)
|
||||
{
|
||||
orPos[c++] = i;
|
||||
i += 7;
|
||||
lb <<= 1;
|
||||
}
|
||||
if (c == 4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (--maxCheck == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void patchBootParams()
|
||||
{
|
||||
uint64_t addr, pos;
|
||||
uint64_t newPtrOffset, ptrOffset;
|
||||
int n;
|
||||
|
||||
printf("Patching boot params.\n");
|
||||
// The function will reside in init code part. We don't care we may potentially search beyond as we expect it to be found
|
||||
while (initTextOffs < fileSize)
|
||||
{
|
||||
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
||||
if (addr == -1)
|
||||
break; // no more "functions" left
|
||||
printf("\rAnalyzing f() candidate @ %lX, PUSH @ %lX", initTextOffs, addr);
|
||||
// we found something looking like PUSH R12-R15, now find the ORs
|
||||
n = findORs(initTextOffs, 1024);
|
||||
if (n != 4)
|
||||
{
|
||||
// We can always move forward by the function token length (obvious) but if we couldn't find any LOCK-OR tokens
|
||||
// we can skip the whole look ahead distance. We CANNOT do that if we found even a single token because the next one
|
||||
// might have been just after the look ahead distance
|
||||
initTextOffs += 2;
|
||||
if (n == 0)
|
||||
{
|
||||
initTextOffs += 1024;
|
||||
}
|
||||
continue; // Continue the main search loop to find next function candidate
|
||||
}
|
||||
// We found LOCK(); OR ptr sequences so we can print some logs and collect ptrs (as this is quite expensive)
|
||||
printf("\n[?] Found possible f() @ %lX\n", initTextOffs);
|
||||
ptrOffset = 0;
|
||||
int ec = 0;
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
// data will have the following bytes:
|
||||
// [0-LOCK()] [1-OR()] [2-BYTE-PTR] [3-OFFS-b3] [4-OFFS-b2] [5-OFFS-b1] [6-OFFS-b1] [7-NUMBER]
|
||||
pos = orPos[n];
|
||||
// how far it "jumps"
|
||||
newPtrOffset = pos + (fileData[pos + 6] << 24 | fileData[pos + 5] << 16 | fileData[pos + 4] << 8 | fileData[pos + 3]);
|
||||
if (ptrOffset == 0)
|
||||
{
|
||||
ptrOffset = newPtrOffset;
|
||||
++ec;
|
||||
}
|
||||
else if (ptrOffset == newPtrOffset)
|
||||
{
|
||||
++ec;
|
||||
}
|
||||
printf("\t[+] Found LOCK-OR#%d sequence @ %lX => %02X %02X %02X %02X %02X %02X %02X %02X [RIP+%lX]\n",
|
||||
n, pos, fileData[pos], fileData[pos + 1], fileData[pos + 2], fileData[pos + 3], fileData[pos + 4],
|
||||
fileData[pos + 5], fileData[pos + 6], fileData[pos + 7], newPtrOffset);
|
||||
}
|
||||
if (ec != 4)
|
||||
{
|
||||
printf("\t[-] LOCK-OR PTR offset mismatch - %d/4 matched\n", ec);
|
||||
// If the pointer checking failed we can at least move beyond the last LOCK-OR found as we know there's no valid
|
||||
// sequence of LOCK-ORs there
|
||||
initTextOffs = orPos[3];
|
||||
continue;
|
||||
}
|
||||
printf("\t[+] All %d LOCK-OR PTR offsets equal - match found!\n", ec);
|
||||
break;
|
||||
}
|
||||
if (addr == -1)
|
||||
{
|
||||
errorMsg("\nFailed to find matching sequences\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Patch offsets
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
// The offset will point at LOCK(), we need to change the OR (0x80 0x0d) to AND (0x80 0x25) so the two bytes after
|
||||
pos = orPos[n] + 2;
|
||||
printf("Patching OR to AND @ %lX\n", pos);
|
||||
fileData[pos] = 0x25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
uint32_t changeEndian(uint32_t num)
|
||||
{
|
||||
return ((num >> 24) & 0xff) | // move byte 3 to byte 0
|
||||
((num << 8) & 0xff0000) | // move byte 1 to byte 2
|
||||
((num >> 8) & 0xff00) | // move byte 2 to byte 1
|
||||
((num << 24) & 0xff000000); // move byte 0 to byte 3
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
uint64_t findSeq(const char *seq, int len, uint32_t pos, int dir, uint64_t max)
|
||||
{
|
||||
uint64_t i = pos;
|
||||
|
||||
do
|
||||
{
|
||||
if (memcmp((const char *)fileData + i, seq, len) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
i += dir;
|
||||
--max;
|
||||
} while (i > 0 && i < fileSize && max > 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void patchRamdiskCheck()
|
||||
{
|
||||
uint64_t pos, errPrintAddr;
|
||||
uint64_t printkPos, testPos, jzPos;
|
||||
const char str[] = "3ramdisk corrupt";
|
||||
|
||||
printf("Patching ramdisk check.\n");
|
||||
for (pos = rodataOffs; pos < fileSize; pos++)
|
||||
{
|
||||
if (memcmp(str, (const char *)(fileData + pos), 16) == 0)
|
||||
{
|
||||
pos -= rodataOffs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
errPrintAddr = rodataAddr + pos - 1;
|
||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||
printkPos = findSeq((const char *)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||
if (printkPos == -1)
|
||||
{
|
||||
errorMsg("printk pos not found!\n");
|
||||
}
|
||||
// double check if it's a MOV reg,VAL (where reg is EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)
|
||||
printkPos -= 3;
|
||||
if (memcmp((const char *)fileData + printkPos, "\x48\xc7", 2) != 0)
|
||||
{
|
||||
errorMsg("Expected MOV=>reg before printk error, got %02X %02X\n", fileData[printkPos], fileData[printkPos + 1]);
|
||||
}
|
||||
if (fileData[printkPos + 2] < 0xC0 || fileData[printkPos + 2] > 0xC7)
|
||||
{
|
||||
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[printkPos + 2]);
|
||||
}
|
||||
printf("Found printk MOV @ %08lX\n", printkPos);
|
||||
|
||||
// now we should seek a reasonable amount (say, up to 32 bytes) for a sequence of CALL x => TEST EAX,EAX => JZ
|
||||
testPos = findSeq("\x85\xc0", 2, printkPos, DIR_RWD, 32);
|
||||
if (testPos == -1)
|
||||
{
|
||||
errorMsg("Failed to find TEST eax,eax\n");
|
||||
}
|
||||
printf("Found TEST eax,eax @ %08lX\n", testPos);
|
||||
jzPos = testPos + 2;
|
||||
if (fileData[jzPos] != 0x74)
|
||||
{
|
||||
errorMsg("Failed to find JZ\n");
|
||||
}
|
||||
printf("OK - patching %02X%02X (JZ) to %02X%02X (JMP) @ %08lX\n",
|
||||
fileData[jzPos], fileData[jzPos + 1], 0xEB, fileData[jzPos + 1], jzPos);
|
||||
fileData[jzPos] = 0xEB;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void patchCmosWrite()
|
||||
{
|
||||
uint64_t pos, errPrintAddr;
|
||||
uint64_t pr_errPos, testPos, callPos;
|
||||
const char str[] = "3smpboot: %s: this boot have memory training";
|
||||
|
||||
printf("Patching call to rtc_cmos_write.\n");
|
||||
for (pos = rodataOffs; pos < fileSize; pos++)
|
||||
{
|
||||
if (memcmp(str, (const char *)(fileData + pos), 16) == 0)
|
||||
{
|
||||
pos -= rodataOffs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
errPrintAddr = rodataAddr + pos - 1;
|
||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||
pr_errPos = findSeq((const char *)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||
if (pr_errPos == -1)
|
||||
{
|
||||
printf("pr_err pos not found - ignoring.\n"); // Some kernels do not have the call, exit without error
|
||||
return;
|
||||
}
|
||||
// double check if it's a MOV reg,VAL (where reg is EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)
|
||||
pr_errPos -= 3;
|
||||
if (memcmp((const char *)fileData + pr_errPos, "\x48\xc7", 2) != 0)
|
||||
{
|
||||
errorMsg("Expected MOV=>reg before pr_err error, got %02X %02X\n", fileData[pr_errPos], fileData[pr_errPos + 1]);
|
||||
}
|
||||
if (fileData[pr_errPos + 2] < 0xC0 || fileData[pr_errPos + 2] > 0xC7)
|
||||
{
|
||||
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[pr_errPos + 2]);
|
||||
}
|
||||
printf("Found pr_err MOV @ %08lX\n", pr_errPos);
|
||||
|
||||
// now we should seek a reasonable amount (say, up to 64 bytes) for a sequence of
|
||||
// MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX
|
||||
testPos = findSeq("\xBE\x48\x00\x00\x00\xBF\xFF\x00\x00\x00\x89\xC3", 12, pr_errPos, DIR_RWD, 64);
|
||||
if (testPos == -1)
|
||||
{
|
||||
printf("Failed to find MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX\n");
|
||||
return;
|
||||
}
|
||||
printf("Found MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX @ %08lX\n", testPos);
|
||||
callPos = testPos + 12;
|
||||
if (fileData[callPos] != 0xE8)
|
||||
{
|
||||
errorMsg("Failed to find CALL\n");
|
||||
}
|
||||
printf("OK - patching %02X (CALL) to 0x90.. (NOPs) @ %08lX\n",
|
||||
fileData[callPos], callPos);
|
||||
for (uint64_t i = 0; i < 5; i++)
|
||||
fileData[callPos + i] = 0x90;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct stat fileInf;
|
||||
Elf_Scn *section;
|
||||
GElf_Shdr sectionHeader;
|
||||
char *sectionName;
|
||||
char *fileIn = NULL, *fileOut = NULL;
|
||||
int onlyBoot = 0, onlyRD = 0, onlyCMOS = 0, c;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
errorMsg("Use: kpatch (option) <vmlinux> <output>\nOptions:\n -b Only bootparams\n -r Only ramdisk\n -c Only CMOS");
|
||||
}
|
||||
c = 1;
|
||||
while (c < argc)
|
||||
{
|
||||
if (strcmp(argv[c], "-b") == 0)
|
||||
{
|
||||
onlyBoot = 1;
|
||||
}
|
||||
else if (strcmp(argv[c], "-r") == 0)
|
||||
{
|
||||
onlyRD = 1;
|
||||
}
|
||||
else if (strcmp(argv[c], "-c") == 0)
|
||||
{
|
||||
onlyCMOS = 1;
|
||||
}
|
||||
else if (fileIn == NULL)
|
||||
{
|
||||
fileIn = argv[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
fileOut = argv[c];
|
||||
break;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
if (NULL == fileIn)
|
||||
{
|
||||
errorMsg("Please give a input filename");
|
||||
}
|
||||
if (NULL == fileOut)
|
||||
{
|
||||
errorMsg("Please give a output filename");
|
||||
}
|
||||
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
elfErrno();
|
||||
|
||||
if ((fd = open(fileIn, O_RDONLY)) == -1)
|
||||
errorNum();
|
||||
|
||||
if ((elfHandle = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
|
||||
elfErrno();
|
||||
if (gelf_getehdr(elfHandle, &elfExecHeader) == NULL)
|
||||
elfErrno();
|
||||
|
||||
switch (elf_kind(elfHandle))
|
||||
{
|
||||
case ELF_K_NUM:
|
||||
case ELF_K_NONE:
|
||||
errorMsg("file type unknown\n");
|
||||
break;
|
||||
case ELF_K_COFF:
|
||||
errorMsg("COFF binaries not supported\n");
|
||||
break;
|
||||
case ELF_K_AR:
|
||||
errorMsg("AR archives not supported\n");
|
||||
break;
|
||||
case ELF_K_ELF:
|
||||
break;
|
||||
}
|
||||
|
||||
section = NULL;
|
||||
while ((section = elf_nextscn(elfHandle, section)) != NULL)
|
||||
{
|
||||
if (gelf_getshdr(section, §ionHeader) != §ionHeader)
|
||||
elfErrno();
|
||||
if ((sectionName = elf_strptr(elfHandle, elfExecHeader.e_shstrndx, sectionHeader.sh_name)) == NULL)
|
||||
elfErrno();
|
||||
if (strcmp(sectionName, ".init.text") == 0)
|
||||
{
|
||||
initTextOffs = sectionHeader.sh_offset;
|
||||
}
|
||||
else if (strcmp(sectionName, ".rodata") == 0)
|
||||
{
|
||||
rodataAddr = sectionHeader.sh_addr & 0xFFFFFFFF;
|
||||
rodataOffs = sectionHeader.sh_offset;
|
||||
}
|
||||
}
|
||||
elfErrno(); /* If there isn't elf_errno set, nothing will happend. */
|
||||
elf_end(elfHandle);
|
||||
|
||||
if (fstat(fd, &fileInf) == -1)
|
||||
errorNum();
|
||||
|
||||
fileSize = fileInf.st_size;
|
||||
fileData = malloc(fileSize);
|
||||
if (fileSize != read(fd, fileData, fileSize))
|
||||
{
|
||||
errorNum();
|
||||
}
|
||||
close(fd);
|
||||
|
||||
printf("Found .init.text offset @ %lX\n", initTextOffs);
|
||||
printf("Found .rodata address @ %lX\n", rodataAddr);
|
||||
printf("Found .rodata offset @ %lX\n", rodataOffs);
|
||||
if (onlyBoot == 0 && onlyCMOS == 0 && onlyRD == 0)
|
||||
{
|
||||
patchBootParams();
|
||||
patchRamdiskCheck();
|
||||
patchCmosWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (onlyBoot == 1)
|
||||
{
|
||||
patchBootParams();
|
||||
}
|
||||
if (onlyRD == 1)
|
||||
{
|
||||
patchRamdiskCheck();
|
||||
}
|
||||
if (onlyCMOS == 1)
|
||||
{
|
||||
patchCmosWrite();
|
||||
}
|
||||
}
|
||||
if ((fd = open(fileOut, O_WRONLY | O_CREAT, 0644)) == -1)
|
||||
{
|
||||
errorNum();
|
||||
}
|
||||
if (fileSize != write(fd, fileData, fileSize))
|
||||
{
|
||||
errorNum();
|
||||
}
|
||||
close(fd);
|
||||
printf("Finish!\n");
|
||||
return 0;
|
||||
}
|
||||
426
scripts/func.sh
Executable file
426
scripts/func.sh
Executable file
@@ -0,0 +1,426 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2024 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
# Get latest Arc
|
||||
# $1 path
|
||||
function getArcSystem() {
|
||||
echo "Getting ArcSystem begin"
|
||||
local DEST_PATH="${1}"
|
||||
local RELEASE="${2}"
|
||||
local CACHE_FILE="/tmp/system.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
if [ "${RELEASE}" = "dev" ]; then
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-system/releases" | jq -r ".[].tag_name" | grep "dev" | sort -rV | head -1)"
|
||||
else
|
||||
local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-system/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)"
|
||||
fi
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-system/releases/download/${TAG}/system-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip LKMs
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting ArcSystem end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get ArcSystem"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest LKMs
|
||||
# $1 path
|
||||
function getLKMs() {
|
||||
echo "Getting LKMs begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/rp-lkms.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s "https://api.github.com/repos/AuxXxilium/arc-lkm/releases/latest" | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export LKMTAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-lkm/releases/download/${TAG}/rp-lkms.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip LKMs
|
||||
rm -rf "${DEST_PATH}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting LKMs end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get LKMs"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Addons
|
||||
# $1 path
|
||||
function getAddons() {
|
||||
echo "Getting Addons begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_DIR="/tmp/addons"
|
||||
local CACHE_FILE="/tmp/addons.zip"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-addons/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export ADDONTAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-addons/releases/download/${TAG}/addons-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Addons
|
||||
rm -rf "${CACHE_DIR}"
|
||||
mkdir -p "${CACHE_DIR}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${CACHE_DIR}"
|
||||
echo "Installing Addons to ${DEST_PATH}"
|
||||
[ -f /tmp/addons/VERSION ] && cp -f /tmp/addons/VERSION ${DEST_PATH}/
|
||||
for PKG in $(ls ${CACHE_DIR}/*.addon); do
|
||||
ADDON=$(basename "${PKG}" .addon)
|
||||
mkdir -p "${DEST_PATH}/${ADDON}"
|
||||
echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}"
|
||||
tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}"
|
||||
done
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting Addons end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Addons"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Modules
|
||||
# $1 path
|
||||
function getModules() {
|
||||
echo "Getting Modules begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/modules.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-modules/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export MODULETAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-modules/releases/download/${TAG}/modules-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Modules
|
||||
rm -rf "${DEST_PATH}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
echo "Getting Modules end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Modules"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Configs
|
||||
# $1 path
|
||||
function getConfigs() {
|
||||
echo "Getting Configs begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/configs.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-configs/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export CONFIGTAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-configs/releases/download/${TAG}/configs-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Configs
|
||||
rm -rf "${DEST_PATH}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting Configs end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Configs"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Patches
|
||||
# $1 path
|
||||
function getPatches() {
|
||||
echo "Getting Patches begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/patches.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-patches/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export PATCHTAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-patches/releases/download/${TAG}/patches-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Patches
|
||||
rm -rf "${DEST_PATH}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting Patches end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Patches"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Custom
|
||||
# $1 path
|
||||
function getCustom() {
|
||||
echo "Getting Custom begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/custom.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-custom/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export CUSTOMTAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-custom/releases/download/${TAG}/custom-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Custom
|
||||
rm -rf "${DEST_PATH}"
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting Custom end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Custom"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Theme
|
||||
# $1 path
|
||||
function getTheme() {
|
||||
echo "Getting Theme begin"
|
||||
local DEST_PATH="${1}"
|
||||
local CACHE_FILE="/tmp/theme.zip"
|
||||
rm -f "${CACHE_FILE}"
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-theme/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export THEMETAG="${TAG}"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-theme/releases/download/${TAG}/arc-theme-${TAG}.zip" -o "${CACHE_FILE}"; then
|
||||
# Unzip Theme
|
||||
mkdir -p "${DEST_PATH}"
|
||||
unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||
rm -f "${CACHE_FILE}"
|
||||
echo "Getting Theme end - ${TAG}"
|
||||
else
|
||||
echo "Failed to get Theme"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Buildroot-X
|
||||
# $1 path
|
||||
function getBuildrootx() {
|
||||
echo "Getting Buildroot-X begin"
|
||||
local DEST_PATH="${1}"
|
||||
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-buildroot-x/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export BRXTAG="${TAG}"
|
||||
[ ! -d "${DEST_PATH}" ] && mkdir -p "${DEST_PATH}"
|
||||
echo "Getting Kernel"
|
||||
rm -f "${DEST_PATH}/bzImage-arc"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-buildroot-x/releases/download/${TAG}/bzImage" -o "${DEST_PATH}/bzImage-arc"; then
|
||||
echo "Kernel: ${TAG}"
|
||||
else
|
||||
echo "Failed to get Kernel"
|
||||
exit 1
|
||||
fi
|
||||
echo "Getting Ramdisk"
|
||||
rm -f "${DEST_PATH}/initrd-arc"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-buildroot-x/releases/download/${TAG}/rootfs.cpio.xz" -o "${DEST_PATH}/initrd-arc"; then
|
||||
echo "Ramdisk: ${TAG}"
|
||||
else
|
||||
echo "Failed to get Ramdisk"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Buildroot-X
|
||||
# $1 path
|
||||
function getBuildroots() {
|
||||
echo "Getting Buildroot-S begin"
|
||||
local DEST_PATH="${1}"
|
||||
|
||||
TAG="$(curl -s https://api.github.com/repos/AuxXxilium/arc-buildroot-s/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')"
|
||||
export BRSTAG="${TAG}"
|
||||
[ ! -d "${DEST_PATH}" ] && mkdir -p "${DEST_PATH}"
|
||||
echo "Getting Kernel"
|
||||
rm -f "${DEST_PATH}/bzImage-arc"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-buildroot-s/releases/download/${TAG}/bzImage" -o "${DEST_PATH}/bzImage-arc"; then
|
||||
echo "Kernel: ${TAG}"
|
||||
else
|
||||
echo "Failed to get Kernel"
|
||||
exit 1
|
||||
fi
|
||||
echo "Getting Ramdisk"
|
||||
rm -f "${DEST_PATH}/initrd-arc"
|
||||
if curl -skL "https://github.com/AuxXxilium/arc-buildroot-s/releases/download/${TAG}/rootfs.cpio.xz" -o "${DEST_PATH}/initrd-arc"; then
|
||||
echo "Ramdisk: ${TAG}"
|
||||
else
|
||||
echo "Failed to get Ramdisk"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get latest Offline
|
||||
# $1 path
|
||||
function getOffline() {
|
||||
echo "Getting Offline begin"
|
||||
local DEST_PATH="${1}"
|
||||
|
||||
[ ! -d "${DEST_PATH}" ] && mkdir -p "${DEST_PATH}"
|
||||
rm -f "${DEST_PATH}/data.yml"
|
||||
if curl -skL "https://raw.githubusercontent.com/AuxXxilium/arc-dsm/refs/heads/main/data.yml" -o "${DEST_PATH}/data.yml"; then
|
||||
echo "Getting Offline end"
|
||||
else
|
||||
echo "Failed to get Offline"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# repack initrd
|
||||
# $1 initrd file
|
||||
# $2 plugin path
|
||||
# $3 output file
|
||||
function repackInitrd() {
|
||||
INITRD_FILE="${1}"
|
||||
PLUGIN_PATH="${2}"
|
||||
OUTPUT_PATH="${3:-${INITRD_FILE}}"
|
||||
|
||||
[ -z "${INITRD_FILE}" ] || [ ! -f "${INITRD_FILE}" ] && exit 1
|
||||
[ -z "${PLUGIN_PATH}" ] || [ ! -d "${PLUGIN_PATH}" ] && exit 1
|
||||
|
||||
INITRD_FILE="$(readlink -f "${INITRD_FILE}")"
|
||||
PLUGIN_PATH="$(readlink -f "${PLUGIN_PATH}")"
|
||||
OUTPUT_PATH="$(readlink -f "${OUTPUT_PATH}")"
|
||||
|
||||
RDXZ_PATH="rdxz_tmp"
|
||||
mkdir -p "${RDXZ_PATH}"
|
||||
(
|
||||
cd "${RDXZ_PATH}"
|
||||
sudo xz -dc <"${INITRD_FILE}" | sudo cpio -idm
|
||||
) || true
|
||||
sudo cp -rf "${PLUGIN_PATH}/"* "${RDXZ_PATH}/"
|
||||
[ -f "${OUTPUT_PATH}" ] && rm -rf "${OUTPUT_PATH}"
|
||||
(
|
||||
cd "${RDXZ_PATH}"
|
||||
sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | xz -9 --check=crc32 >"${OUTPUT_PATH}"
|
||||
) || true
|
||||
sudo rm -rf "${RDXZ_PATH}"
|
||||
}
|
||||
|
||||
# resizeimg
|
||||
# $1 input file
|
||||
# $2 changsize MB eg: +50M -50M
|
||||
# $3 output file
|
||||
function resizeImg() {
|
||||
INPUT_FILE="${1}"
|
||||
CHANGE_SIZE="${2}"
|
||||
OUTPUT_FILE="${3:-${INPUT_FILE}}"
|
||||
|
||||
[[ -z "${INPUT_FILE}" || ! -f "${INPUT_FILE}" ]] && exit 1
|
||||
[ -z "${CHANGE_SIZE}" ] && exit 1
|
||||
|
||||
INPUT_FILE="$(readlink -f "${INPUT_FILE}")"
|
||||
OUTPUT_FILE="$(readlink -f "${OUTPUT_FILE}")"
|
||||
|
||||
|
||||
SIZE=$(($(du -m "${INPUT_FILE}" | awk '{print $1}')$(echo "${CHANGE_SIZE}" | sed 's/M//g; s/b//g')))
|
||||
[[ -z "${SIZE}" || "${SIZE}" -lt 0 ]] && exit 1
|
||||
|
||||
if [ ! "${INPUT_FILE}" = "${OUTPUT_FILE}" ]; then
|
||||
sudo cp -f "${INPUT_FILE}" "${OUTPUT_FILE}"
|
||||
fi
|
||||
|
||||
sudo truncate -s ${SIZE}M "${OUTPUT_FILE}"
|
||||
echo -e "d\n\nn\n\n\n\n\nn\nw" | sudo fdisk "${OUTPUT_FILE}"
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P ${LOOPX} "${OUTPUT_FILE}"
|
||||
sudo e2fsck -fp $(ls ${LOOPX}* | sort -n | tail -1)
|
||||
sudo resize2fs $(ls ${LOOPX}* | sort -n | tail -1)
|
||||
sudo losetup -d ${LOOPX}
|
||||
}
|
||||
|
||||
# convertova
|
||||
# $1 bootloader file
|
||||
# $2 ova file
|
||||
function convertova() {
|
||||
BLIMAGE=${1}
|
||||
OVAPATH=${2}
|
||||
|
||||
BLIMAGE="$(readlink -f "${BLIMAGE}")"
|
||||
OVAPATH="$(readlink -f "${OVAPATH}")"
|
||||
VMNAME="$(basename "${OVAPATH}" .ova)"
|
||||
|
||||
# Download and install ovftool if it doesn't exist
|
||||
if [ ! -x ovftool/ovftool ]; then
|
||||
rm -rf ovftool ovftool.zip
|
||||
curl -skL https://github.com/rgl/ovftool-binaries/raw/main/archive/VMware-ovftool-4.6.0-21452615-lin.x86_64.zip -o ovftool.zip
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to download ovftool"
|
||||
exit 1
|
||||
fi
|
||||
unzip ovftool.zip -d . >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to extract ovftool"
|
||||
exit 1
|
||||
fi
|
||||
chmod +x ovftool/ovftool
|
||||
fi
|
||||
if ! command -v qemu-img &>/dev/null; then
|
||||
sudo apt install -y qemu-utils
|
||||
fi
|
||||
|
||||
# Convert raw image to VMDK
|
||||
rm -rf "OVA_${VMNAME}"
|
||||
mkdir -p "OVA_${VMNAME}"
|
||||
qemu-img convert -O vmdk -o 'adapter_type=lsilogic,subformat=streamOptimized,compat6' "${BLIMAGE}" "OVA_${VMNAME}/${VMNAME}-disk1.vmdk"
|
||||
qemu-img create -f vmdk "OVA_${VMNAME}/${VMNAME}-disk2.vmdk" "32G"
|
||||
|
||||
# Create VM configuration
|
||||
cat <<_EOF_ >"OVA_${VMNAME}/${VMNAME}.vmx"
|
||||
.encoding = "UTF-8"
|
||||
config.version = "8"
|
||||
virtualHW.version = "21"
|
||||
displayName = "${VMNAME}"
|
||||
annotation = "https://github.com/AuxXxilium/arc"
|
||||
guestOS = "ubuntu-64"
|
||||
firmware = "efi"
|
||||
mks.enable3d = "TRUE"
|
||||
pciBridge0.present = "TRUE"
|
||||
pciBridge4.present = "TRUE"
|
||||
pciBridge4.virtualDev = "pcieRootPort"
|
||||
pciBridge4.functions = "8"
|
||||
pciBridge5.present = "TRUE"
|
||||
pciBridge5.virtualDev = "pcieRootPort"
|
||||
pciBridge5.functions = "8"
|
||||
pciBridge6.present = "TRUE"
|
||||
pciBridge6.virtualDev = "pcieRootPort"
|
||||
pciBridge6.functions = "8"
|
||||
pciBridge7.present = "TRUE"
|
||||
pciBridge7.virtualDev = "pcieRootPort"
|
||||
pciBridge7.functions = "8"
|
||||
vmci0.present = "TRUE"
|
||||
hpet0.present = "TRUE"
|
||||
nvram = "${VMNAME}.nvram"
|
||||
virtualHW.productCompatibility = "hosted"
|
||||
powerType.powerOff = "soft"
|
||||
powerType.powerOn = "soft"
|
||||
powerType.suspend = "soft"
|
||||
powerType.reset = "soft"
|
||||
tools.syncTime = "FALSE"
|
||||
sound.autoDetect = "TRUE"
|
||||
sound.fileName = "-1"
|
||||
sound.present = "TRUE"
|
||||
numvcpus = "2"
|
||||
cpuid.coresPerSocket = "1"
|
||||
vcpu.hotadd = "TRUE"
|
||||
memsize = "4096"
|
||||
mem.hotadd = "TRUE"
|
||||
usb.present = "TRUE"
|
||||
ehci.present = "TRUE"
|
||||
usb_xhci.present = "TRUE"
|
||||
svga.graphicsMemoryKB = "8388608"
|
||||
usb.vbluetooth.startConnected = "TRUE"
|
||||
extendedConfigFile = "${VMNAME}.vmxf"
|
||||
floppy0.present = "FALSE"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.virtualDev = "vmxnet3"
|
||||
ethernet0.connectionType = "nat"
|
||||
ethernet0.allowguestconnectioncontrol = "true"
|
||||
ethernet0.present = "TRUE"
|
||||
sata0.present = "TRUE"
|
||||
sata0:0.fileName = "${VMNAME}-disk1.vmdk"
|
||||
sata0:0.present = "TRUE"
|
||||
sata0:1.fileName = "${VMNAME}-disk2.vmdk"
|
||||
sata0:1.present = "TRUE"
|
||||
_EOF_
|
||||
|
||||
rm -f "${OVAPATH}"
|
||||
ovftool/ovftool "OVA_${VMNAME}/${VMNAME}.vmx" "${OVAPATH}"
|
||||
rm -rf "OVA_${VMNAME}"
|
||||
}
|
||||
622
scripts/functions.py
Executable file → Normal file
622
scripts/functions.py
Executable file → Normal file
@@ -1,251 +1,373 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2025 AuxXxilium <https://github.com/AuxXxilium>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
import os, re, sys, glob, json, yaml, click, shutil, tarfile, kmodule, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
from openpyxl import Workbook
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
"""
|
||||
The CLI is a commands to ARC.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getmodels(workpath, jsonpath):
|
||||
models = {}
|
||||
platforms_yml = os.path.join(workpath, "mnt", "p3", "configs", "platforms.yml")
|
||||
with open(platforms_yml, "r") as f:
|
||||
P_data = yaml.safe_load(f)
|
||||
P_platforms = P_data.get("platforms", [])
|
||||
for P in P_platforms:
|
||||
productvers = {}
|
||||
for V in P_platforms[P]["productvers"]:
|
||||
kpre = P_platforms[P]["productvers"][V].get("kpre", "")
|
||||
kver = P_platforms[P]["productvers"][V].get("kver", "")
|
||||
productvers[V] = f"{kpre}-{kver}" if kpre else kver
|
||||
models[P] = {"productvers": productvers, "models": []}
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
try:
|
||||
url = "http://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
#url = "https://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
|
||||
req = session.get(url, timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
p = re.compile(r"<mUnique>(.*?)</mUnique>.*?<mLink>(.*?)</mLink>", re.MULTILINE | re.DOTALL)
|
||||
data = p.findall(req.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
return
|
||||
|
||||
for item in data:
|
||||
if not "DSM" in item[1]:
|
||||
continue
|
||||
arch = item[0].split("_")[1]
|
||||
name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if arch not in models:
|
||||
continue
|
||||
if name in (A for B in models for A in models[B]["models"]):
|
||||
continue
|
||||
models[arch]["models"].append(name)
|
||||
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(models, f, indent=4, ensure_ascii=False)
|
||||
|
||||
@cli.command()
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getpats(workpath, jsonpath):
|
||||
def __fullversion(ver):
|
||||
arr = ver.split('-')
|
||||
a, b, c = (arr[0].split('.') + ['0', '0', '0'])[:3]
|
||||
d = arr[1] if len(arr) > 1 else '00000'
|
||||
e = arr[2] if len(arr) > 2 else '0'
|
||||
return f'{a}.{b}.{c}-{d}-{e}'
|
||||
|
||||
platforms_yml = os.path.join(workpath, "mnt", "p3", "configs", "platforms.yml")
|
||||
with open(platforms_yml, "r") as f:
|
||||
data = yaml.safe_load(f)
|
||||
platforms = data.get("platforms", [])
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
try:
|
||||
url = "http://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
#url = "https://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
|
||||
req = session.get(url, timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
p = re.compile(r"<mUnique>(.*?)</mUnique>.*?<mLink>(.*?)</mLink>", re.MULTILINE | re.DOTALL)
|
||||
data = p.findall(req.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
return
|
||||
|
||||
models = []
|
||||
for item in data:
|
||||
if not "DSM" in item[1]:
|
||||
continue
|
||||
arch = item[0].split("_")[1]
|
||||
name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if arch not in platforms:
|
||||
continue
|
||||
if name in models:
|
||||
continue
|
||||
models.append(name)
|
||||
|
||||
pats = {}
|
||||
for M in models:
|
||||
pats[M] = {}
|
||||
version = '7'
|
||||
urlInfo = "https://www.synology.com/api/support/findDownloadInfo?lang=en-us"
|
||||
urlSteps = "https://www.synology.com/api/support/findUpgradeSteps?"
|
||||
#urlInfo = "https://www.synology.cn/api/support/findDownloadInfo?lang=zh-cn"
|
||||
#urlSteps = "https://www.synology.cn/api/support/findUpgradeSteps?"
|
||||
|
||||
major = f"&major={version.split('.')[0]}" if len(version.split('.')) > 0 else ""
|
||||
minor = f"&minor={version.split('.')[1]}" if len(version.split('.')) > 1 else ""
|
||||
try:
|
||||
req = session.get(f"{urlInfo}&product={M.replace('+', '%2B')}{major}{minor}", timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
data = json.loads(req.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
|
||||
build_ver = data['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = data['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = data['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V = __fullversion(f"{build_ver}-{build_num}-{buildnano}")
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': data['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0],
|
||||
'sum': data['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
}
|
||||
|
||||
from_ver = min(I['build'] for I in data['info']['pubVers'])
|
||||
|
||||
for I in data['info']['productVers']:
|
||||
if not I['version'].startswith(version):
|
||||
continue
|
||||
if not major or not minor:
|
||||
majorTmp = f"&major={I['version'].split('.')[0]}" if len(I['version'].split('.')) > 0 else ""
|
||||
minorTmp = f"&minor={I['version'].split('.')[1]}" if len(I['version'].split('.')) > 1 else ""
|
||||
try:
|
||||
reqTmp = session.get(f"{urlInfo}&product={M.replace('+', '%2B')}{majorTmp}{minorTmp}", timeout=10, verify=False)
|
||||
reqTmp.encoding = "utf-8"
|
||||
dataTmp = json.loads(reqTmp.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
|
||||
build_ver = dataTmp['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = dataTmp['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = dataTmp['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V = __fullversion(f"{build_ver}-{build_num}-{buildnano}")
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0],
|
||||
'sum': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
}
|
||||
|
||||
for J in I['versions']:
|
||||
to_ver = J['build']
|
||||
try:
|
||||
reqSteps = session.get(f"{urlSteps}&product={M.replace('+', '%2B')}&from_ver={from_ver}&to_ver={to_ver}", timeout=10, verify=False)
|
||||
if reqSteps.status_code != 200:
|
||||
continue
|
||||
reqSteps.encoding = "utf-8"
|
||||
dataSteps = json.loads(reqSteps.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
|
||||
for S in dataSteps['upgrade_steps']:
|
||||
if not S.get('full_patch') or not S['build_ver'].startswith(version):
|
||||
continue
|
||||
V = __fullversion(f"{S['build_ver']}-{S['build_num']}-{S['nano']}")
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': S['files'][0]['url'].split('?')[0],
|
||||
'sum': S['files'][0]['checksum']
|
||||
}
|
||||
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(pats, f, indent=4, ensure_ascii=False)
|
||||
|
||||
@cli.command()
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getaddons(workpath, jsonpath):
|
||||
AS = glob.glob(os.path.join(workpath, "mnt", "p3", "addons", "*", "manifest.yml"))
|
||||
AS.sort()
|
||||
addons = {}
|
||||
for A in AS:
|
||||
with open(A, "r") as file:
|
||||
A_data = yaml.safe_load(file)
|
||||
A_name = A_data.get("name", "")
|
||||
A_system = A_data.get("system", False)
|
||||
A_description = A_data.get("description", "")
|
||||
addons[A_name] = {"system": A_system, "description": A_description}
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(addons, f, indent=4, ensure_ascii=False)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getmodules(workpath, jsonpath):
|
||||
MS = glob.glob(os.path.join(workpath, "mnt", "p3", "modules", "*.tgz"))
|
||||
MS.sort()
|
||||
modules = {}
|
||||
TMP_PATH = "/tmp/modules"
|
||||
if os.path.exists(TMP_PATH):
|
||||
shutil.rmtree(TMP_PATH)
|
||||
for M in MS:
|
||||
M_name = os.path.splitext(os.path.basename(M))[0]
|
||||
M_modules = {}
|
||||
os.makedirs(TMP_PATH)
|
||||
with tarfile.open(M, "r") as tar:
|
||||
tar.extractall(TMP_PATH)
|
||||
KS = glob.glob(os.path.join(TMP_PATH, "*.ko"))
|
||||
KS.sort()
|
||||
for K in KS:
|
||||
K_name = os.path.splitext(os.path.basename(K))[0]
|
||||
K_info = kmodule.modinfo(K, basedir=os.path.dirname(K), kernel=None)[0]
|
||||
K_description = K_info.get("description", "")
|
||||
K_depends = K_info.get("depends", "")
|
||||
M_modules[K_name] = {"description": K_description, "depends": K_depends}
|
||||
modules[M_name] = M_modules
|
||||
if os.path.exists(TMP_PATH):
|
||||
shutil.rmtree(TMP_PATH)
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as file:
|
||||
json.dump(modules, file, indent=4, ensure_ascii=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium> and Ing <https://github.com/wjz304>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
import os, click
|
||||
|
||||
WORK_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
"""
|
||||
The CLI is a commands to Arc.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def mutually_exclusive_options(ctx, param, value):
|
||||
other_option = "file" if param.name == "data" else "data"
|
||||
if value is not None and ctx.params.get(other_option) is not None:
|
||||
raise click.UsageError(f"Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_required_param(ctx, param, value):
|
||||
if not value and "file" not in ctx.params and "data" not in ctx.params:
|
||||
raise click.MissingParameter(param_decls=[param.name])
|
||||
return value
|
||||
|
||||
def __fullversion(ver):
|
||||
out = ver
|
||||
arr = ver.split('-')
|
||||
if len(arr) > 0:
|
||||
a = arr[0].split('.')[0] if len(arr[0].split('.')) > 0 else '0'
|
||||
b = arr[0].split('.')[1] if len(arr[0].split('.')) > 1 else '0'
|
||||
c = arr[0].split('.')[2] if len(arr[0].split('.')) > 2 else '0'
|
||||
d = arr[1] if len(arr) > 1 else '00000'
|
||||
e = arr[2] if len(arr) > 2 else '0'
|
||||
out = '{}.{}.{}-{}-{}'.format(a,b,c,d,e)
|
||||
return out
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-d", "--data", type=str, callback=mutually_exclusive_options, is_eager=True, help="The data of QRCode.")
|
||||
@click.option("-f", "--file", type=str, callback=mutually_exclusive_options, is_eager=True, help="The file of QRCode.")
|
||||
@click.option("--validate", is_flag=True, callback=validate_required_param, expose_value=False, is_eager=True)
|
||||
@click.option("-l", "--location", type=click.IntRange(0, 7), required=True, help="The location of QRCode. (range 0<=x<=7)")
|
||||
@click.option("-o", "--output", type=str, required=True, help="The output file of QRCode.")
|
||||
def makeqr(data, file, location, output):
|
||||
"""
|
||||
Generate a QRCode.
|
||||
"""
|
||||
try:
|
||||
import fcntl, struct
|
||||
import qrcode
|
||||
from PIL import Image
|
||||
|
||||
FBIOGET_VSCREENINFO = 0x4600
|
||||
FBIOPUT_VSCREENINFO = 0x4601
|
||||
FBIOGET_FSCREENINFO = 0x4602
|
||||
FBDEV = "/dev/fb0"
|
||||
if data is not None:
|
||||
qr = qrcode.QRCode(version=1, box_size=10, error_correction=qrcode.constants.ERROR_CORRECT_H, border=4,)
|
||||
qr.add_data(data)
|
||||
qr.make(fit=True)
|
||||
img = qr.make_image(fill_color="grey", back_color="black")
|
||||
img = img.convert("RGBA")
|
||||
pixels = img.load()
|
||||
for i in range(img.size[0]):
|
||||
for j in range(img.size[1]):
|
||||
if pixels[i, j] == (255, 255, 255, 255):
|
||||
pixels[i, j] = (255, 255, 255, 0)
|
||||
|
||||
if os.path.exists(os.path.join(WORK_PATH, "logo.png")):
|
||||
icon = Image.open(os.path.join(WORK_PATH, "logo.png"))
|
||||
icon = icon.convert("RGBA")
|
||||
img.paste(icon.resize((int(img.size[0] / 5), int(img.size[1] / 5))), (int((img.size[0] - int(img.size[0] / 5)) / 2), int((img.size[1] - int(img.size[1] / 5)) / 2),),)
|
||||
|
||||
if file is not None:
|
||||
img = Image.open(file)
|
||||
# img = img.convert("RGBA")
|
||||
# pixels = img.load()
|
||||
# for i in range(img.size[0]):
|
||||
# for j in range(img.size[1]):
|
||||
# if pixels[i, j] == (255, 255, 255, 255):
|
||||
# pixels[i, j] = (255, 255, 255, 0)
|
||||
|
||||
(xres, yres) = (1920, 1080)
|
||||
with open(FBDEV, "rb") as fb:
|
||||
vi = fcntl.ioctl(fb, FBIOGET_VSCREENINFO, bytes(160))
|
||||
res = struct.unpack("I" * 40, vi)
|
||||
if res[0] != 0 and res[1] != 0:
|
||||
(xres, yres) = (res[0], res[1])
|
||||
xqr, yqr = (int(xres / 8), int(xres / 8))
|
||||
img = img.resize((xqr, yqr))
|
||||
|
||||
alpha = Image.new("RGBA", (xres, yres), (0, 0, 0, 0))
|
||||
if int(location) not in range(0, 8):
|
||||
location = 0
|
||||
loc = (img.size[0] * int(location), alpha.size[1] - img.size[1])
|
||||
alpha.paste(img, loc)
|
||||
alpha.save(output)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--platforms", type=str, help="The platforms of Syno.")
|
||||
def getmodels(platforms=None):
|
||||
"""
|
||||
Get Syno Models.
|
||||
"""
|
||||
import json, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
if platforms is not None and platforms != "":
|
||||
PS = platforms.lower().replace(",", " ").split()
|
||||
else:
|
||||
PS = []
|
||||
|
||||
models = []
|
||||
try:
|
||||
req = session.get("https://autoupdate.synology.com/os/v2", timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
data = json.loads(req.text)
|
||||
|
||||
for I in data["channel"]["item"]:
|
||||
if not I["title"].startswith("DSM"):
|
||||
continue
|
||||
for J in I["model"]:
|
||||
arch = J["mUnique"].split("_")[1]
|
||||
name = J["mLink"].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if len(PS) > 0 and arch.lower() not in PS:
|
||||
continue
|
||||
if any(name == B["name"] for B in models):
|
||||
continue
|
||||
models.append({"name": name, "arch": arch})
|
||||
|
||||
models = sorted(models, key=lambda k: (k["arch"], k["name"]))
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
models.sort(key=lambda x: (x["arch"], x["name"]))
|
||||
print(json.dumps(models, indent=4))
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--platforms", type=str, help="The platforms of Syno.")
|
||||
def getmodelsbykb(platforms=None):
|
||||
"""
|
||||
Get Syno Models.
|
||||
"""
|
||||
import json, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
if platforms is not None and platforms != "":
|
||||
PS = platforms.lower().replace(",", " ").split()
|
||||
else:
|
||||
PS = []
|
||||
|
||||
models = []
|
||||
try:
|
||||
import re
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
url="https://kb.synology.com/en-us/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have"
|
||||
#url = "https://kb.synology.cn/zh-cn/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have"
|
||||
req = session.get(url, timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
bs = BeautifulSoup(req.text, "html.parser")
|
||||
p = re.compile(r"data: (.*?),$", re.MULTILINE | re.DOTALL)
|
||||
data = json.loads(p.search(bs.find("script", string=p).prettify()).group(1))
|
||||
model = "(.*?)" # (.*?): all, FS6400: one
|
||||
p = re.compile(r"<td>{}<\/td><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td>".format(model), re.MULTILINE | re.DOTALL,)
|
||||
it = p.finditer(data["preload"]["content"].replace("\n", "").replace("\t", ""))
|
||||
for i in it:
|
||||
d = i.groups()
|
||||
if len(d) == 6:
|
||||
d = model + d
|
||||
if len(PS) > 0 and d[5].lower() not in PS:
|
||||
continue
|
||||
models.append({"name": d[0].split("<br")[0], "arch": d[5].lower()})
|
||||
except:
|
||||
pass
|
||||
|
||||
models.sort(key=lambda x: (x["arch"], x["name"]))
|
||||
print(json.dumps(models, indent=4))
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-m", "--model", type=str, required=True, help="The model of Syno.")
|
||||
@click.option("-v", "--version", type=str, required=True, help="The version of Syno.")
|
||||
def getpats4mv(model, version):
|
||||
import json, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
pats = {}
|
||||
try:
|
||||
urlInfo = "https://www.synology.com/api/support/findDownloadInfo?lang=en-us"
|
||||
urlSteps = "https://www.synology.com/api/support/findUpgradeSteps?"
|
||||
#urlInfo = "https://www.synology.cn/api/support/findDownloadInfo?lang=zh-cn"
|
||||
#urlSteps = "https://www.synology.cn/api/support/findUpgradeSteps?"
|
||||
|
||||
major = "&major={}".format(version.split('.')[0]) if len(version.split('.')) > 0 else ""
|
||||
minor = "&minor={}".format(version.split('.')[1]) if len(version.split('.')) > 1 else ""
|
||||
req = session.get("{}&product={}{}{}".format(urlInfo, model.replace("+", "%2B"), major, minor), timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
data = json.loads(req.text)
|
||||
|
||||
build_ver = data['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = data['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = data['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V=__fullversion("{}-{}-{}".format(build_ver, build_num, buildnano))
|
||||
if not V in pats:
|
||||
pats[V]={}
|
||||
pats[V]['url'] = data['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0]
|
||||
pats[V]['sum'] = data['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
|
||||
from_ver=0
|
||||
for I in data['info']['pubVers']:
|
||||
if from_ver == 0 or I['build'] < from_ver: from_ver = I['build']
|
||||
|
||||
for I in data['info']['productVers']:
|
||||
if not I['version'].startswith(version): continue
|
||||
if major == "" or minor == "":
|
||||
majorTmp = "&major={}".format(I['version'].split('.')[0]) if len(I['version'].split('.')) > 0 else ""
|
||||
minorTmp = "&minor={}".format(I['version'].split('.')[1]) if len(I['version'].split('.')) > 1 else ""
|
||||
reqTmp = session.get("{}&product={}{}{}".format(urlInfo, model.replace("+", "%2B"), majorTmp, minorTmp), timeout=10, verify=False)
|
||||
reqTmp.encoding = "utf-8"
|
||||
dataTmp = json.loads(reqTmp.text)
|
||||
|
||||
build_ver = dataTmp['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = dataTmp['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = dataTmp['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V=__fullversion("{}-{}-{}".format(build_ver, build_num, buildnano))
|
||||
if not V in pats:
|
||||
pats[V]={}
|
||||
pats[V]['url'] = dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0]
|
||||
pats[V]['sum'] = dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
|
||||
for J in I['versions']:
|
||||
to_ver=J['build']
|
||||
reqSteps = session.get("{}&product={}&from_ver={}&to_ver={}".format(urlSteps, model.replace("+", "%2B"), from_ver, to_ver), timeout=10, verify=False)
|
||||
if reqSteps.status_code != 200: continue
|
||||
reqSteps.encoding = "utf-8"
|
||||
dataSteps = json.loads(reqSteps.text)
|
||||
for S in dataSteps['upgrade_steps']:
|
||||
if not 'full_patch' in S or S['full_patch'] is False: continue
|
||||
if not 'build_ver' in S or not S['build_ver'].startswith(version): continue
|
||||
V=__fullversion("{}-{}-{}".format(S['build_ver'], S['build_num'], S['nano']))
|
||||
if not V in pats:
|
||||
pats[V] = {}
|
||||
pats[V]['url'] = S['files'][0]['url'].split('?')[0]
|
||||
pats[V]['sum'] = S['files'][0]['checksum']
|
||||
except:
|
||||
pass
|
||||
|
||||
pats = {k: pats[k] for k in sorted(pats.keys(), reverse=True)}
|
||||
print(json.dumps(pats, indent=4))
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--models", type=str, help="The models of Syno.")
|
||||
def getpats(models=None):
|
||||
import json, requests, urllib3, re
|
||||
from bs4 import BeautifulSoup
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
if models is not None and models != "":
|
||||
MS = models.lower().replace(",", " ").split()
|
||||
else:
|
||||
MS = []
|
||||
|
||||
pats = {}
|
||||
try:
|
||||
req = session.get('https://archive.synology.com/download/Os/DSM', timeout=10, verify=False)
|
||||
req.encoding = 'utf-8'
|
||||
bs=BeautifulSoup(req.text, 'html.parser')
|
||||
p = re.compile(r"(.*?)-(.*?)", re.MULTILINE | re.DOTALL)
|
||||
l = bs.find_all('a', string=p)
|
||||
for i in l:
|
||||
ver = i.attrs['href'].split('/')[-1]
|
||||
if not ver.startswith('7'): continue
|
||||
req = session.get('https://archive.synology.com{}'.format(i.attrs['href']), timeout=10, verify=False)
|
||||
req.encoding = 'utf-8'
|
||||
bs=BeautifulSoup(req.text, 'html.parser')
|
||||
p = re.compile(r"^(.*?)_(.*?)_(.*?).pat$", re.MULTILINE | re.DOTALL)
|
||||
data = bs.find_all('a', string=p)
|
||||
for item in data:
|
||||
p = re.compile(r"DSM_(.*?)_(.*?).pat", re.MULTILINE | re.DOTALL)
|
||||
rels = p.search(item.attrs['href'])
|
||||
if rels != None:
|
||||
info = p.search(item.attrs['href']).groups()
|
||||
model = info[0].replace('%2B', '+')
|
||||
if len(MS) > 0 and model.lower() not in MS:
|
||||
continue
|
||||
if model not in pats.keys():
|
||||
pats[model]={}
|
||||
pats[model][__fullversion(ver)] = item.attrs['href']
|
||||
except:
|
||||
pass
|
||||
|
||||
print(json.dumps(pats, indent=4))
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--platforms", type=str, help="The platforms of Syno.")
|
||||
def getmodelsoffline(platforms=None):
|
||||
"""
|
||||
Get Syno Models.
|
||||
"""
|
||||
import re, json
|
||||
import requests
|
||||
import fcntl, struct
|
||||
|
||||
if platforms is not None and platforms != "":
|
||||
PS = platforms.lower().replace(",", " ").split()
|
||||
else:
|
||||
PS = []
|
||||
|
||||
models = []
|
||||
with open(os.path.join('/mnt/p3/configs', "offline.json")) as user_file:
|
||||
data = json.load(user_file)
|
||||
|
||||
for I in data["channel"]["item"]:
|
||||
if not I["title"].startswith("DSM"):
|
||||
continue
|
||||
for J in I["model"]:
|
||||
arch = J["mUnique"].split("_")[1]
|
||||
name = J["mLink"].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if len(PS) > 0 and arch.lower() not in PS:
|
||||
continue
|
||||
if any(name == B["name"] for B in models):
|
||||
continue
|
||||
models.append({"name": name, "arch": arch})
|
||||
|
||||
models = sorted(models, key=lambda k: (k["arch"], k["name"]))
|
||||
print(json.dumps(models, indent=4))
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
74
scripts/grub.sh
Executable file
74
scripts/grub.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium> and Ing <https://github.com/wjz304>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
GRUB=${1:-"grub-2.12"}
|
||||
BIOS=${2:-"i386-pc i386-efi x86_64-efi"}
|
||||
NAME=${3:-"ARC"}
|
||||
|
||||
curl -#kLO https://ftp.gnu.org/gnu/grub/${GRUB}.tar.gz
|
||||
tar -zxvf ${GRUB}.tar.gz
|
||||
|
||||
pushd ${GRUB}
|
||||
echo depends bli part_gpt > grub-core/extra_deps.lst
|
||||
for B in ${BIOS}; do
|
||||
b=${B}
|
||||
b=(${b//-/ })
|
||||
echo "Make ${b[@]} ..."
|
||||
mkdir -p ${B}
|
||||
pushd ${B}
|
||||
../configure --prefix=$PWD/usr -sbindir=$PWD/sbin --sysconfdir=$PWD/etc --disable-werror --target=${b[0]} --with-platform=${b[1]}
|
||||
make
|
||||
make install
|
||||
popd
|
||||
done
|
||||
popd
|
||||
|
||||
rm -f grub.img
|
||||
dd if=/dev/zero of=grub.img bs=1M seek=1024 count=0
|
||||
echo -e "n\np\n1\n\n+50M\nn\np\n2\n\n+50M\nn\np\n3\n\n\na\n1\nw\nq\n" | fdisk grub.img
|
||||
fdisk -l grub.img
|
||||
|
||||
LOOPX=$(sudo losetup -f)
|
||||
sudo losetup -P ${LOOPX} grub.img
|
||||
sudo mkdosfs -F32 -n ${NAME}1 ${LOOPX}p1
|
||||
sudo mkfs.ext2 -F -L ${NAME}2 ${LOOPX}p2
|
||||
sudo mkfs.ext4 -F -L ${NAME}3 ${LOOPX}p3
|
||||
|
||||
rm -rf ${NAME}1
|
||||
mkdir -p ${NAME}1
|
||||
sudo mount ${LOOPX}p1 ${NAME}1
|
||||
|
||||
sudo mkdir -p ${NAME}1/EFI
|
||||
sudo mkdir -p ${NAME}1/boot/grub
|
||||
cat >device.map <<EOF
|
||||
(hd0) ${LOOPX}
|
||||
EOF
|
||||
sudo mv device.map ${NAME}1/boot/grub/device.map
|
||||
|
||||
for B in ${BIOS}; do
|
||||
args=""
|
||||
args+=" ${LOOPX} --target=${B} --no-floppy --recheck --grub-mkdevicemap=${NAME}1/boot/grub/device.map --boot-directory=${NAME}1/boot"
|
||||
if [[ "${B}" == *"efi" ]]; then
|
||||
args+=" --efi-directory=${NAME}1 --removable --no-nvram"
|
||||
else
|
||||
args+=" --root-directory=${NAME}1"
|
||||
fi
|
||||
sudo ${GRUB}/${B}/grub-install ${args}
|
||||
done
|
||||
|
||||
if [ -d ${NAME}1/boot/grub/fonts ] && [ -f /usr/share/grub/unicode.pf2 ]; then
|
||||
sudo cp /usr/share/grub/unicode.pf2 ${NAME}1/boot/grub/fonts
|
||||
fi
|
||||
|
||||
sudo sync
|
||||
|
||||
sudo umount ${LOOPX}p1
|
||||
sudo losetup -d ${LOOPX}
|
||||
sudo rm -rf ${NAME}1
|
||||
|
||||
gzip grub.img
|
||||
7
scripts/random.sh
Executable file
7
scripts/random.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function genRandomValue() {
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R S T V W X Y Z; do
|
||||
echo ${i}
|
||||
done | sort -R | tail -1
|
||||
}
|
||||
211
scripts/vm.sh
Executable file
211
scripts/vm.sh
Executable file
@@ -0,0 +1,211 @@
|
||||
|
||||
filename=$(basename "${1}")
|
||||
|
||||
OVFNAME=${filename%.*}
|
||||
BLDISKNAME="${OVFNAME}-disk1.vmdk"
|
||||
SDDISKNAME="${OVFNAME}-disk2.vmdk"
|
||||
|
||||
# Convert raw image to VMDK
|
||||
qemu-img convert -O vmdk -o 'adapter_type=lsilogic,subformat=streamOptimized,compat6' "${1}" "${BLDISKNAME}"
|
||||
#qemu-img create -f vmdk "${SDDISKNAME}" "32G"
|
||||
|
||||
BLSIZE=$(du -b "${BLDISKNAME}" | cut -f 1)
|
||||
SDSIZE=$(du -b "${SDDISKNAME}" | cut -f 1)
|
||||
BLVIRTUALSIZE=$(qemu-img info "${BLDISKNAME}" --output json | jq -r '."virtual-size"')
|
||||
SDVIRTUALSIZE=$(qemu-img info "${SDDISKNAME}" --output json | jq -r '."virtual-size"')
|
||||
|
||||
# Create VM configuration
|
||||
cat << _EOF_ > "${OVFNAME}.ovf"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Envelope vmw:buildId="build-22220919" xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<References>
|
||||
<File ovf:href="${BLDISKNAME}" ovf:id="file1" ovf:size="${BLSIZE}"/>
|
||||
<File ovf:href="${SDDISKNAME}" ovf:id="file2" ovf:size="${SDSIZE}"/>
|
||||
</References>
|
||||
<DiskSection>
|
||||
<Info>Virtual disk information</Info>
|
||||
<Disk ovf:capacity="${BLVIRTUALSIZE}" ovf:capacityAllocationUnits="byte" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="${BLSIZE}"/>
|
||||
<Disk ovf:capacity="${SDVIRTUALSIZE}" ovf:capacityAllocationUnits="byte" ovf:diskId="vmdisk2" ovf:fileRef="file2" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="${SDSIZE}"/>
|
||||
</DiskSection>
|
||||
<NetworkSection>
|
||||
<Info>The list of logical networks</Info>
|
||||
<Network ovf:name="bridged">
|
||||
<Description>The bridged network</Description>
|
||||
</Network>
|
||||
</NetworkSection>
|
||||
<VirtualSystem ovf:id="vm">
|
||||
<Info>A virtual machine</Info>
|
||||
<Name>${OVFNAME}</Name>
|
||||
<OperatingSystemSection ovf:id="94" vmw:osType="ubuntu64Guest">
|
||||
<Info>The kind of installed guest operating system</Info>
|
||||
</OperatingSystemSection>
|
||||
<VirtualHardwareSection>
|
||||
<Info>Virtual hardware requirements</Info>
|
||||
<System>
|
||||
<vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
|
||||
<vssd:InstanceID>0</vssd:InstanceID>
|
||||
<vssd:VirtualSystemIdentifier>${OVFNAME}</vssd:VirtualSystemIdentifier>
|
||||
<vssd:VirtualSystemType>vmx-21</vssd:VirtualSystemType>
|
||||
</System>
|
||||
<Item>
|
||||
<rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
|
||||
<rasd:Description>Number of Virtual CPUs</rasd:Description>
|
||||
<rasd:ElementName>2 virtual CPU(s)</rasd:ElementName>
|
||||
<rasd:InstanceID>1</rasd:InstanceID>
|
||||
<rasd:ResourceType>3</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>2</rasd:VirtualQuantity>
|
||||
<vmw:CoresPerSocket ovf:required="false">2</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item>
|
||||
<rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
|
||||
<rasd:Description>Memory Size</rasd:Description>
|
||||
<rasd:ElementName>4096MB of memory</rasd:ElementName>
|
||||
<rasd:InstanceID>2</rasd:InstanceID>
|
||||
<rasd:ResourceType>4</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>4096</rasd:VirtualQuantity>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item>
|
||||
<rasd:Address>0</rasd:Address>
|
||||
<rasd:Description>SATA Controller</rasd:Description>
|
||||
<rasd:ElementName>sataController0</rasd:ElementName>
|
||||
<rasd:InstanceID>3</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>vmware.sata.ahci</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>20</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:Address>0</rasd:Address>
|
||||
<rasd:Description>USB Controller (XHCI)</rasd:Description>
|
||||
<rasd:ElementName>usb3</rasd:ElementName>
|
||||
<rasd:InstanceID>4</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>vmware.usb.xhci</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>23</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:Address>0</rasd:Address>
|
||||
<rasd:Description>USB Controller (EHCI)</rasd:Description>
|
||||
<rasd:ElementName>usb</rasd:ElementName>
|
||||
<rasd:InstanceID>5</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>vmware.usb.ehci</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>23</rasd:ResourceType>
|
||||
<vmw:Config ovf:required="false" vmw:key="ehciEnabled" vmw:value="true"/>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
|
||||
<rasd:ElementName>serial0</rasd:ElementName>
|
||||
<rasd:InstanceID>6</rasd:InstanceID>
|
||||
<rasd:ResourceType>21</rasd:ResourceType>
|
||||
<vmw:Config ovf:required="false" vmw:key="yieldOnPoll" vmw:value="false"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="connectable.allowGuestControl" vmw:value="false"/>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item>
|
||||
<rasd:AddressOnParent>1</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
|
||||
<rasd:Connection>bridged</rasd:Connection>
|
||||
<rasd:Description>VmxNet3 ethernet adapter on "bridged"</rasd:Description>
|
||||
<rasd:ElementName>ethernet0</rasd:ElementName>
|
||||
<rasd:InstanceID>7</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>10</rasd:ResourceType>
|
||||
<vmw:Config ovf:required="false" vmw:key="connectable.allowGuestControl" vmw:value="false"/>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:ElementName>sound</rasd:ElementName>
|
||||
<rasd:InstanceID>8</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>vmware.soundcard.ensoniq1371</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>1</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:ElementName>video</rasd:ElementName>
|
||||
<rasd:InstanceID>9</rasd:InstanceID>
|
||||
<rasd:ResourceType>24</rasd:ResourceType>
|
||||
<vmw:Config ovf:required="false" vmw:key="enable3DSupport" vmw:value="true"/>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item ovf:required="false">
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:ElementName>vmci</rasd:ElementName>
|
||||
<rasd:InstanceID>10</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>1</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:ElementName>disk0</rasd:ElementName>
|
||||
<rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>
|
||||
<rasd:InstanceID>11</rasd:InstanceID>
|
||||
<rasd:Parent>3</rasd:Parent>
|
||||
<rasd:ResourceType>17</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<Item>
|
||||
<rasd:AddressOnParent>1</rasd:AddressOnParent>
|
||||
<rasd:ElementName>disk1</rasd:ElementName>
|
||||
<rasd:HostResource>ovf:/disk/vmdisk2</rasd:HostResource>
|
||||
<rasd:InstanceID>12</rasd:InstanceID>
|
||||
<rasd:Parent>3</rasd:Parent>
|
||||
<rasd:ResourceType>17</rasd:ResourceType>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</Item>
|
||||
<vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="true"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" vmw:value="true"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="firmware" vmw:value="efi"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="simultaneousThreads" vmw:value="1"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="virtualNuma.coresPerNumaNode" vmw:value="0"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" vmw:value="false"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" vmw:value="soft"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" vmw:value="soft"/>
|
||||
<vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" vmw:value="soft"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="cpuid.coresPerSocket" vmw:value="2"/>
|
||||
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="hpet0.present" vmw:value="TRUE"/>
|
||||
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="nvram" vmw:value="${OVFNAME}.nvram"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge0.present" vmw:value="TRUE"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge4.functions" vmw:value="8"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge4.present" vmw:value="TRUE"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge4.virtualDev" vmw:value="pcieRootPort"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge5.functions" vmw:value="8"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge5.present" vmw:value="TRUE"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge5.virtualDev" vmw:value="pcieRootPort"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge6.functions" vmw:value="8"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge6.present" vmw:value="TRUE"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge6.virtualDev" vmw:value="pcieRootPort"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge7.functions" vmw:value="8"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge7.present" vmw:value="TRUE"/>
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="pciBridge7.virtualDev" vmw:value="pcieRootPort"/>
|
||||
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="usb.vbluetooth.startConnected" vmw:value="TRUE"/>
|
||||
|
||||
<vmw:ExtraConfig ovf:required="false" vmw:key="virtualHW.productCompatibility" vmw:value="hosted"/>
|
||||
</VirtualHardwareSection>
|
||||
<AnnotationSection ovf:required="false">
|
||||
<Info>A human-readable annotation</Info>
|
||||
<Annotation>Arc Loader</Annotation>
|
||||
</AnnotationSection>
|
||||
</VirtualSystem>
|
||||
</Envelope>
|
||||
_EOF_
|
||||
|
||||
# Create manifest file for automatic integrity check
|
||||
cat << _EOF_ > "${OVFNAME}.mf"
|
||||
SHA256(${OVFNAME}.ovf)= $(sha256sum "${OVFNAME}.ovf" | mawk '{print $1}')
|
||||
SHA256(${BLDISKNAME})= $(sha256sum "${BLDISKNAME}" | mawk '{print $1}')
|
||||
SHA256(${SDDISKNAME})= $(sha256sum "${SDDISKNAME}" | mawk '{print $1}')
|
||||
_EOF_
|
||||
|
||||
# Pack everything as OVA appliance for ESXi import
|
||||
rm -f "${OVFNAME}.ova"
|
||||
tar -cf "${OVFNAME}.ova" ${OVFNAME}.ovf ${BLDISKNAME} ${SDDISKNAME} ${OVFNAME}.mf
|
||||
rm -f ${OVFNAME}.ovf ${BLDISKNAME} ${SDDISKNAME} ${OVFNAME}.mf
|
||||
#gzip "${OVFNAME}.ova"
|
||||
|
||||
Reference in New Issue
Block a user