Compare commits
430 Commits
v4.x-branc
...
v5.x-branc
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e63d804f6f | ||
![]() |
cad3c72fce | ||
![]() |
7cd46f3d26 | ||
![]() |
f4051f49db | ||
![]() |
a5051f92bf | ||
![]() |
ec564407da | ||
![]() |
a0127f9f40 | ||
![]() |
e49865a467 | ||
![]() |
2bba72634f | ||
![]() |
45b39285f1 | ||
![]() |
a795dc1972 | ||
![]() |
c1860c8d80 | ||
![]() |
49cfba851c | ||
![]() |
b348bb75e7 | ||
![]() |
c1f5b21177 | ||
![]() |
b474b6bad0 | ||
![]() |
5323bce117 | ||
![]() |
1bcbf817ed | ||
![]() |
f81b9d2dc3 | ||
![]() |
d0a1285feb | ||
![]() |
a0c2f95a1d | ||
![]() |
d421ebcb58 | ||
![]() |
7117b85c86 | ||
![]() |
3a81c3e13d | ||
![]() |
a0997a598b | ||
![]() |
212dbd32c1 | ||
![]() |
a55f68b3bd | ||
![]() |
a83dafe6f4 | ||
![]() |
afdc556301 | ||
![]() |
bfc518cc07 | ||
![]() |
81c39fc080 | ||
![]() |
87a88bf565 | ||
![]() |
3fde8f0158 | ||
![]() |
50f4383f93 | ||
![]() |
c7df84e237 | ||
![]() |
f1236373fe | ||
![]() |
a36de776a7 | ||
![]() |
a0fb5a04d3 | ||
![]() |
042a6e9554 | ||
![]() |
c5c43cb0fd | ||
![]() |
5f7bcc0b1d | ||
![]() |
45958f7162 | ||
![]() |
e9b5511084 | ||
![]() |
f4bfe1289a | ||
![]() |
cdac49ebfb | ||
![]() |
90b82dc43f | ||
![]() |
e3d65aa628 | ||
![]() |
f33732a2e5 | ||
![]() |
09c430f286 | ||
![]() |
2200161e7d | ||
![]() |
f8bfe41e71 | ||
![]() |
0f7ee05635 | ||
![]() |
b54c3fc9cc | ||
![]() |
756dd235ea | ||
![]() |
09c87feaee | ||
![]() |
916aa370b2 | ||
![]() |
0ebf0245df | ||
![]() |
8f789fc0ae | ||
![]() |
b5cffbb6e8 | ||
![]() |
9ff62c2a62 | ||
![]() |
68f82c3d30 | ||
![]() |
2642249edd | ||
![]() |
e6a67c80a6 | ||
![]() |
541dbd265c | ||
![]() |
e207c03f69 | ||
![]() |
57e4ae6e25 | ||
![]() |
a30cad3556 | ||
![]() |
ac0d9465f5 | ||
![]() |
f0b899b5bc | ||
![]() |
4abedffb43 | ||
![]() |
50dab6c2f1 | ||
![]() |
ba5d63b82a | ||
![]() |
573d0095bf | ||
![]() |
27a32e416c | ||
![]() |
9a074530a9 | ||
![]() |
a248b557bb | ||
![]() |
d66df6b38a | ||
![]() |
1e9a42e7ce | ||
![]() |
b8fff872de | ||
![]() |
820d4751d3 | ||
![]() |
82ea6d6a57 | ||
![]() |
030242d69a | ||
![]() |
b64335f62a | ||
![]() |
50b8ab2c26 | ||
![]() |
2d0752f60c | ||
![]() |
ff86be6be6 | ||
![]() |
2f1dac0600 | ||
![]() |
0ecb2ab895 | ||
![]() |
474fc105a5 | ||
![]() |
418f8d7280 | ||
![]() |
722bde2cbc | ||
![]() |
5bdb1bbf55 | ||
![]() |
8f167bc2e5 | ||
![]() |
d73cd37834 | ||
![]() |
478b6f3806 | ||
![]() |
4b452e69a4 | ||
![]() |
98f30bfdd6 | ||
![]() |
ba2597605b | ||
![]() |
9921af54d0 | ||
![]() |
a2e502328d | ||
![]() |
dc68fcaff7 | ||
![]() |
f365a46617 | ||
![]() |
871a8053c2 | ||
![]() |
49ecb6b577 | ||
![]() |
997e2c756a | ||
![]() |
bc1896c5bb | ||
![]() |
e261a96fa4 | ||
![]() |
1f82dd89c7 | ||
![]() |
93942a3334 | ||
![]() |
b72d033510 | ||
![]() |
11f50a6aaa | ||
![]() |
79e50a82af | ||
![]() |
17e26c8c95 | ||
![]() |
9333f1ca8b | ||
![]() |
99d671ecf8 | ||
![]() |
7882d89b4e | ||
![]() |
1ad6d6013e | ||
![]() |
2ac43a320f | ||
![]() |
2d6a1e4535 | ||
![]() |
d08ea721a5 | ||
![]() |
6e41938206 | ||
![]() |
67fd1a8d9f | ||
![]() |
66268f7d7f | ||
![]() |
cb14f44eb3 | ||
![]() |
910a0d84a0 | ||
![]() |
2da0a08072 | ||
![]() |
670b635ae8 | ||
![]() |
bc8188e275 | ||
![]() |
38ccb76c40 | ||
![]() |
7b1284808a | ||
![]() |
34a2e85c34 | ||
![]() |
ece02695e8 | ||
![]() |
45fd1ac08f | ||
![]() |
264decd0ef | ||
![]() |
d0b9bbdca6 | ||
![]() |
1c5fde5dc9 | ||
![]() |
a069e220c0 | ||
![]() |
b764792c97 | ||
![]() |
a9e6e00994 | ||
![]() |
2b154138fe | ||
![]() |
cde874fe80 | ||
![]() |
a627c732d5 | ||
![]() |
b78309b45a | ||
![]() |
666c5dfcd1 | ||
![]() |
13042bd25e | ||
![]() |
f6946a7f0c | ||
![]() |
74a6b8e125 | ||
![]() |
705719a229 | ||
![]() |
e205d51ca4 | ||
![]() |
fa7b2409e7 | ||
![]() |
1f01ddfc6d | ||
![]() |
9274ee656e | ||
![]() |
e91196d452 | ||
![]() |
bee1d50c1a | ||
![]() |
fe083d3701 | ||
![]() |
dce1c31ad5 | ||
![]() |
f26b651e5f | ||
![]() |
679fdd4351 | ||
![]() |
4190710dc6 | ||
![]() |
9079f3007d | ||
![]() |
eac03c8c89 | ||
![]() |
0125dcd67a | ||
![]() |
844386487d | ||
![]() |
71b175b7b9 | ||
![]() |
153412f53e | ||
![]() |
7989064599 | ||
![]() |
836d1c2038 | ||
![]() |
2c11fb337c | ||
![]() |
73462a5116 | ||
![]() |
f618eb26af | ||
![]() |
e9186e1859 | ||
![]() |
35808c593e | ||
![]() |
717c60cd6a | ||
![]() |
e0c3e6bdce | ||
![]() |
df34599feb | ||
![]() |
fdcb9a9243 | ||
![]() |
1a4888858b | ||
![]() |
8dd7973e23 | ||
![]() |
36846549e0 | ||
![]() |
172060e249 | ||
![]() |
d7da6d63b5 | ||
![]() |
2362f1a785 | ||
![]() |
2a26d90394 | ||
![]() |
64a0c6073b | ||
![]() |
73b126e067 | ||
![]() |
c41e3969a6 | ||
![]() |
b991fb93f8 | ||
![]() |
e57050d9c7 | ||
![]() |
93ae0e9afc | ||
![]() |
3613997108 | ||
![]() |
eae24e64e5 | ||
![]() |
2da6225f9e | ||
![]() |
a3f84fc4a3 | ||
![]() |
240d9688b0 | ||
![]() |
7ad444936e | ||
![]() |
eba0183b6e | ||
![]() |
ebd1953e51 | ||
![]() |
514522125b | ||
![]() |
3438b8d235 | ||
![]() |
e0f8d94de7 | ||
![]() |
67d2631826 | ||
![]() |
b66184cfbd | ||
![]() |
012605adf9 | ||
![]() |
d0df21abb9 | ||
![]() |
01eeeb6e1d | ||
![]() |
779571339e | ||
![]() |
936240a3c6 | ||
![]() |
a2dd3449a8 | ||
![]() |
42027470c7 | ||
![]() |
45ff0e2e93 | ||
![]() |
d0ee1e7d65 | ||
![]() |
698ca1a665 | ||
![]() |
830251e68e | ||
![]() |
d4334699e3 | ||
![]() |
5a53f91e01 | ||
![]() |
0196abf2ec | ||
![]() |
2ea3f7e9d8 | ||
![]() |
3bf159d81c | ||
![]() |
9663318102 | ||
![]() |
c202cce72c | ||
![]() |
813c1e6c95 | ||
![]() |
fadb9a7c13 | ||
![]() |
7d6125d413 | ||
![]() |
f71f506b0a | ||
![]() |
08647f7d5c | ||
![]() |
c7a7539d23 | ||
![]() |
5f5c98866e | ||
![]() |
7dc04b42cc | ||
![]() |
9009404a11 | ||
![]() |
674f490f7b | ||
![]() |
b072a08f72 | ||
![]() |
8d61d0ab3a | ||
![]() |
d1e4b9946c | ||
![]() |
828e3790a4 | ||
![]() |
ca69475609 | ||
![]() |
246276a538 | ||
![]() |
980c122475 | ||
![]() |
4ef529b4eb | ||
![]() |
5bc6fbca3b | ||
![]() |
fc4e283ad5 | ||
![]() |
0f4beb1bfd | ||
![]() |
9d6c64954c | ||
![]() |
1dd75a18ac | ||
![]() |
8bb12244be | ||
![]() |
753bb820ae | ||
![]() |
5f84ade177 | ||
![]() |
959c44658e | ||
![]() |
11ef3bced2 | ||
![]() |
a786c26a26 | ||
![]() |
8ee9dc1ebd | ||
![]() |
d17e220e61 | ||
![]() |
9bcad9d258 | ||
![]() |
b4649f8808 | ||
![]() |
1e65ada438 | ||
![]() |
c924d7b7e5 | ||
![]() |
ce7a552723 | ||
![]() |
c7f344784c | ||
![]() |
48053fd206 | ||
![]() |
e909489635 | ||
![]() |
a3f814b5f7 | ||
![]() |
3ae87be595 | ||
![]() |
9b07351208 | ||
![]() |
82aec4b1b2 | ||
![]() |
143d3d85de | ||
![]() |
1099993b14 | ||
![]() |
71b3ae548b | ||
![]() |
caaf4f94a5 | ||
![]() |
bcac8b6256 | ||
![]() |
d744fc8c63 | ||
![]() |
ec34c86d58 | ||
![]() |
8b7dc549f7 | ||
![]() |
7e46840b86 | ||
![]() |
87bea2fe0d | ||
![]() |
8d427d7699 | ||
![]() |
cd8188d832 | ||
![]() |
fb4b02a451 | ||
![]() |
8c7655eacd | ||
![]() |
c30afde043 | ||
![]() |
843be07536 | ||
![]() |
8c7a98310a | ||
![]() |
191ad51eaa | ||
![]() |
5c1b96b393 | ||
![]() |
a7721872dd | ||
![]() |
28dd8a1062 | ||
![]() |
2091aa9c21 | ||
![]() |
41d4b3af54 | ||
![]() |
3dd0a6fb41 | ||
![]() |
ac1c5d1b95 | ||
![]() |
a085af55ec | ||
![]() |
8caf7b5b75 | ||
![]() |
a0d8c7b2ab | ||
![]() |
2ee939725e | ||
![]() |
1aba6b3aeb | ||
![]() |
10bbba0066 | ||
![]() |
b3c08f8122 | ||
![]() |
fc6b69f0ac | ||
![]() |
382d88913d | ||
![]() |
040a15817f | ||
![]() |
98bfcc6dbd | ||
![]() |
6df8a35698 | ||
![]() |
3fc36e9ac1 | ||
![]() |
25c6c18c8b | ||
![]() |
0748cf5bf2 | ||
![]() |
a48036141f | ||
![]() |
ba5aca6fd8 | ||
![]() |
32d7aa1815 | ||
![]() |
04d22b1e52 | ||
![]() |
ffaaabf14a | ||
![]() |
c2854bde82 | ||
![]() |
f9399fd5a3 | ||
![]() |
15127263ca | ||
![]() |
d39baeaa80 | ||
![]() |
28187433f9 | ||
![]() |
9b68f081cf | ||
![]() |
bf4c0f7d7a | ||
![]() |
99f8c7b187 | ||
![]() |
e924aa5f26 | ||
![]() |
970292460d | ||
![]() |
60c115658c | ||
![]() |
20572082c1 | ||
![]() |
07d8dd2c68 | ||
![]() |
c477414c5c | ||
![]() |
d82dc64b93 | ||
![]() |
22c041ff08 | ||
![]() |
1258f01bc2 | ||
![]() |
144c481ed5 | ||
![]() |
7e403e0059 | ||
![]() |
ae771dd8a1 | ||
![]() |
49f4ccd312 | ||
![]() |
09faf82bc4 | ||
![]() |
d8193abc98 | ||
![]() |
ce4046d559 | ||
![]() |
7e1d4a9870 | ||
![]() |
3c541576f3 | ||
![]() |
c7e62083fd | ||
![]() |
f0d6aa8033 | ||
![]() |
c14bb6059f | ||
![]() |
e0aec79cb6 | ||
![]() |
01ee09373c | ||
![]() |
502f77b30f | ||
![]() |
42b1db1063 | ||
![]() |
b30d2dc978 | ||
![]() |
da5896b764 | ||
![]() |
6022f5bf23 | ||
![]() |
96fe1aa2e0 | ||
![]() |
d265cad7b6 | ||
![]() |
ce33e9dff3 | ||
![]() |
fa40b927cd | ||
![]() |
d10d2baded | ||
![]() |
af80341c8c | ||
![]() |
53d20619ec | ||
![]() |
2557aa8f46 | ||
![]() |
4ba1b2fd9d | ||
![]() |
3d95c8960c | ||
![]() |
23f2c7dbac | ||
![]() |
02c26a8738 | ||
![]() |
b1319408dd | ||
![]() |
7f09259c57 | ||
![]() |
610a98d8b2 | ||
![]() |
6e1c792e41 | ||
![]() |
fb994e61c6 | ||
![]() |
44a3f3f2f7 | ||
![]() |
68e936e7f4 | ||
![]() |
ac34ec411f | ||
![]() |
ec9d384bf2 | ||
![]() |
cc8ff90865 | ||
![]() |
6cbb9c4577 | ||
![]() |
ffa6d4e0c7 | ||
![]() |
d187c576d8 | ||
![]() |
ff8c5f318c | ||
![]() |
f977548e84 | ||
![]() |
48a7c12e5b | ||
![]() |
d3c8a66918 | ||
![]() |
b34954bb43 | ||
![]() |
45312e66ae | ||
![]() |
f6ba5991b5 | ||
![]() |
0f1d86e7e4 | ||
![]() |
8849d08eeb | ||
![]() |
4d855fc17e | ||
![]() |
e466501f92 | ||
![]() |
96c184fdf6 | ||
![]() |
7f046f67b9 | ||
![]() |
e5d786158f | ||
![]() |
0d7b1e1148 | ||
![]() |
00e9f2ce46 | ||
![]() |
a2ba71eb1d | ||
![]() |
c849bfc10b | ||
![]() |
bd7c3602bb | ||
![]() |
97c928a354 | ||
![]() |
64c897a82d | ||
![]() |
714d8ac2ce | ||
![]() |
4a4409e1b2 | ||
![]() |
0cb98610f0 | ||
![]() |
e062b4ed7d | ||
![]() |
e67a75fe09 | ||
![]() |
34a53292f7 | ||
![]() |
b9f41799b4 | ||
![]() |
390372533f | ||
![]() |
b229d0cdf3 | ||
![]() |
0a28a0959b | ||
![]() |
dab2a35b3e | ||
![]() |
d5ff44676b | ||
![]() |
b1bfa2d2d8 | ||
![]() |
a6189abdc1 | ||
![]() |
e89d834457 | ||
![]() |
87e09dba61 | ||
![]() |
59bbd1f657 | ||
![]() |
26f6ac3bb2 | ||
![]() |
dc5ed66e67 | ||
![]() |
f86a421209 | ||
![]() |
0ae552a25c | ||
![]() |
7f14f2f0d0 | ||
![]() |
e76c8d47a9 | ||
![]() |
50b524838a | ||
![]() |
886523359c | ||
![]() |
430e841903 | ||
![]() |
708868c889 | ||
![]() |
a95d475c89 | ||
![]() |
2b71eaedb6 | ||
![]() |
0f04f6860a | ||
![]() |
7e6aad3113 | ||
![]() |
ae4605936a | ||
![]() |
c1e98f26c9 | ||
![]() |
9680a1ad51 | ||
![]() |
71eb143611 | ||
![]() |
a1bcf3c09b | ||
![]() |
8906518cd2 | ||
![]() |
f8d714317b | ||
![]() |
528be7230f | ||
![]() |
82eb809111 |
5
.github/workflows/check.yml
vendored
5
.github/workflows/check.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: pacman --noconfirm -Syu && pacman --needed --noconfirm -S base-devel git autoconf automake nasm curl mtools llvm clang lld aarch64-linux-gnu-gcc
|
||||
run: pacman --noconfirm -Syu && pacman --needed --noconfirm -S base-devel git autoconf automake nasm curl mtools llvm clang lld aarch64-linux-gnu-gcc riscv64-linux-gnu-gcc
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
@ -26,3 +26,6 @@ jobs:
|
||||
|
||||
- name: Build the bootloader (GNU, aarch64)
|
||||
run: ./bootstrap && ./configure TOOLCHAIN_FOR_TARGET=aarch64-linux-gnu --enable-werror --enable-uefi-aarch64 && make all && make maintainer-clean
|
||||
|
||||
- name: Build the bootloader (GNU, riscv64)
|
||||
run: ./bootstrap && ./configure TOOLCHAIN_FOR_TARGET=riscv64-linux-gnu --enable-werror --enable-uefi-riscv64 && make all && make maintainer-clean
|
||||
|
30
.github/workflows/release.yml
vendored
30
.github/workflows/release.yml
vendored
@ -41,29 +41,17 @@ jobs:
|
||||
- name: Build the bootloader
|
||||
run: make -C build
|
||||
|
||||
- name: Clean limine-version
|
||||
run: rm build/bin/limine-version
|
||||
- name: Clean limine
|
||||
run: rm build/bin/limine
|
||||
|
||||
- name: Clean limine-enroll-config
|
||||
run: rm build/bin/limine-enroll-config
|
||||
- name: Build limine for Windows
|
||||
run: make -C build/bin CC="i686-w64-mingw32-gcc" CFLAGS="-O2 -pipe" CPPFLAGS="-D__USE_MINGW_ANSI_STDIO" limine
|
||||
|
||||
- name: Build limine-enroll-config-win32
|
||||
run: make -C build/bin CC="i686-w64-mingw32-gcc" CFLAGS="-O2 -pipe" CPPFLAGS="-D__USE_MINGW_ANSI_STDIO" limine-enroll-config
|
||||
|
||||
- name: Strip limine-enroll-config-win32
|
||||
run: i686-w64-mingw32-strip build/bin/limine-enroll-config.exe
|
||||
|
||||
- name: Clean limine-deploy
|
||||
run: rm build/bin/limine-deploy
|
||||
|
||||
- name: Build limine-deploy-win32
|
||||
run: make -C build/bin CC="i686-w64-mingw32-gcc" CFLAGS="-O2 -pipe" CPPFLAGS="-D__USE_MINGW_ANSI_STDIO" limine-deploy
|
||||
|
||||
- name: Strip limine-deploy-win32
|
||||
run: i686-w64-mingw32-strip build/bin/limine-deploy.exe
|
||||
- name: Strip limine for Windows
|
||||
run: i686-w64-mingw32-strip build/bin/limine.exe
|
||||
|
||||
- name: Copy LICENSE to bin
|
||||
run: cp LICENSE build/bin/
|
||||
run: cp COPYING build/bin/LICENSE
|
||||
|
||||
- name: Copy install-sh to bin
|
||||
run: cp build-aux/install-sh build/bin/
|
||||
@ -71,8 +59,8 @@ jobs:
|
||||
- name: Copy limine.h to bin
|
||||
run: cp limine.h build/bin/
|
||||
|
||||
- name: Remove limine-hdd.bin
|
||||
run: rm build/bin/limine-hdd.bin
|
||||
- name: Remove limine-bios-hdd.bin
|
||||
run: rm build/bin/limine-bios-hdd.bin
|
||||
|
||||
- name: Push binaries to binary branch
|
||||
run: |
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -29,20 +29,20 @@
|
||||
/freestanding-toolchain
|
||||
/configure
|
||||
/configure.ac.save
|
||||
/INSTALL
|
||||
/build-aux
|
||||
/aclocal.m4
|
||||
/*~
|
||||
/config.status
|
||||
/config.log
|
||||
/autom4te.cache
|
||||
/man/man1/limine-version.1
|
||||
/man/man1/limine-deploy.1
|
||||
/man/man1/limine-enroll-config.1
|
||||
/man/man1/limine.1
|
||||
/GNUmakefile
|
||||
/config.h
|
||||
/common-bios
|
||||
/common-uefi-ia32
|
||||
/common-uefi-x86-64
|
||||
/common-uefi-aarch64
|
||||
/common-uefi-riscv64
|
||||
/decompressor-build
|
||||
/stage1.stamp
|
||||
|
@ -199,4 +199,4 @@ Macros must always be placed inside `${...}` where `...` is the arbitrary macro
|
||||
|
||||
Limine automatically defines these macros:
|
||||
|
||||
* `ARCH` - This built-in macro expands to the architecture of the machine. Possible values are: `x86-64`, `ia-32`, `aarch64`. In the case of IA-32, BIOS or UEFI, the macro will always expand to `x86-64` if the 64-bit extensions are available, else `ia-32`.
|
||||
* `ARCH` - This built-in macro expands to the architecture of the machine. Possible values are: `x86-64`, `ia-32`, `aarch64`, `riscv64`. In the case of IA-32, BIOS or UEFI, the macro will always expand to `x86-64` if the 64-bit extensions are available, else `ia-32`.
|
||||
|
173
GNUmakefile.in
173
GNUmakefile.in
@ -40,10 +40,10 @@ override BUILD_BIOS := @BUILD_BIOS@
|
||||
override BUILD_UEFI_X86_64 := @BUILD_UEFI_X86_64@
|
||||
override BUILD_UEFI_IA32 := @BUILD_UEFI_IA32@
|
||||
override BUILD_UEFI_AARCH64 := @BUILD_UEFI_AARCH64@
|
||||
override BUILD_CD_EFI := @BUILD_CD_EFI@
|
||||
override BUILD_PXE := @BUILD_PXE@
|
||||
override BUILD_CD := @BUILD_CD@
|
||||
override BUILD_LIMINE_DEPLOY := @BUILD_LIMINE_DEPLOY@
|
||||
override BUILD_UEFI_RISCV64 := @BUILD_UEFI_RISCV64@
|
||||
override BUILD_UEFI_CD := @BUILD_UEFI_CD@
|
||||
override BUILD_BIOS_PXE := @BUILD_BIOS_PXE@
|
||||
override BUILD_BIOS_CD := @BUILD_BIOS_CD@
|
||||
|
||||
override DEFAULT_CC := @CC@
|
||||
$(eval $(call DEFAULT_VAR,CC,$(DEFAULT_CC)))
|
||||
@ -108,76 +108,66 @@ all: $(call MKESCAPE,$(BINDIR))/Makefile
|
||||
$(MAKE) all1
|
||||
|
||||
.PHONY: all1
|
||||
all1: limine-version limine-enroll-config $(BUILD_UEFI_X86_64) $(BUILD_UEFI_IA32) $(BUILD_UEFI_AARCH64) $(BUILD_BIOS)
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin'
|
||||
all1: $(BUILD_UEFI_X86_64) $(BUILD_UEFI_IA32) $(BUILD_UEFI_AARCH64) $(BUILD_UEFI_RISCV64) $(BUILD_BIOS)
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine'
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin'
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/limine-hdd.h: $(call MKESCAPE,$(BINDIR))/limine-hdd.bin
|
||||
$(call MKESCAPE,$(BINDIR))/limine-bios-hdd.h: $(call MKESCAPE,$(BINDIR))/limine-bios-hdd.bin
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
|
||||
cd '$(call SHESCAPE,$(BINDIR))' && '$(call SHESCAPE,$(SRCDIR))/host/hgen.sh' >limine-hdd.h
|
||||
cd '$(call SHESCAPE,$(BINDIR))' && '$(call SHESCAPE,$(SRCDIR))/host/hgen.sh' >limine-bios-hdd.h
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/limine-deploy: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine-deploy.c $(call MKESCAPE,$(BINDIR))/limine-hdd.h
|
||||
cp '$(call SHESCAPE,$(SRCDIR))/host/limine-deploy.c' '$(call SHESCAPE,$(BINDIR))/'
|
||||
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-deploy
|
||||
ifeq ($(BUILD_BIOS),limine-bios)
|
||||
$(call MKESCAPE,$(BINDIR))/limine: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine.c $(call MKESCAPE,$(BINDIR))/limine-bios-hdd.h
|
||||
else
|
||||
override LIMINE_NO_BIOS := -DLIMINE_NO_BIOS
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/limine-version: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine-version.c
|
||||
$(SED) 's/@LIMINE_VERSION@/@PACKAGE_VERSION@/g' <'$(call SHESCAPE,$(SRCDIR))/host/limine-version.c' >'$(call SHESCAPE,$(BINDIR))/limine-version.c'
|
||||
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-version
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/limine-enroll-config: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine-enroll-config.c
|
||||
cp '$(call SHESCAPE,$(SRCDIR))/host/limine-enroll-config.c' '$(call SHESCAPE,$(BINDIR))/'
|
||||
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-enroll-config
|
||||
$(call MKESCAPE,$(BINDIR))/limine: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine.c
|
||||
endif
|
||||
$(SED) 's/%VERSION%/@PACKAGE_VERSION@/g;s/%COPYRIGHT%/@LIMINE_COPYRIGHT@/g' <'$(call SHESCAPE,$(SRCDIR))/host/limine.c' >'$(call SHESCAPE,$(BINDIR))/limine.c'
|
||||
CPPFLAGS="$(CPPFLAGS) $(LIMINE_NO_BIOS)" $(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/Makefile: $(call MKESCAPE,$(SRCDIR))/host/Makefile $(call MKESCAPE,$(SRCDIR))/host/.gitignore
|
||||
mkdir -p '$(call SHESCAPE,$(BINDIR))'
|
||||
cp '$(call SHESCAPE,$(SRCDIR))/host/Makefile' '$(call SHESCAPE,$(SRCDIR))/host/.gitignore' '$(call SHESCAPE,$(BINDIR))/'
|
||||
|
||||
.PHONY: limine-deploy
|
||||
limine-deploy:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-deploy'
|
||||
|
||||
.PHONY: limine-version
|
||||
limine-version:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-version'
|
||||
|
||||
.PHONY: limine-enroll-config
|
||||
limine-enroll-config:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-enroll-config'
|
||||
.PHONY: limine
|
||||
limine:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine'
|
||||
|
||||
.PHONY: clean
|
||||
clean: limine-bios-clean limine-uefi-ia32-clean limine-uefi-x86-64-clean limine-uefi-aarch64-clean
|
||||
clean: limine-bios-clean limine-uefi-ia32-clean limine-uefi-x86-64-clean limine-uefi-aarch64-clean limine-uefi-riscv64-clean
|
||||
rm -rf '$(call SHESCAPE,$(BINDIR))' '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp'
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(docdir))'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/LICENSE' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/COPYING' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/CONFIG.md' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/PROTOCOL.md' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/PHILOSOPHY.md' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/README.md' '$(call SHESCAPE,$(DESTDIR)$(docdir))/'
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BUILDDIR))/man/man1/limine-version.1' '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/'
|
||||
ifneq ($(BUILD_LIMINE_DEPLOY),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BUILDDIR))/man/man1/limine-deploy.1' '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/'
|
||||
endif
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BUILDDIR))/man/man1/limine-enroll-config.1' '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BUILDDIR))/man/man1/limine.1' '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/'
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(datarootdir))'
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine'
|
||||
ifeq ($(BUILD_BIOS),limine-bios)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine.sys' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-bios.sys' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifneq ($(BUILD_CD),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-cd.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
ifneq ($(BUILD_BIOS_CD),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-bios-cd.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifneq ($(BUILD_CD_EFI),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
ifneq ($(BUILD_UEFI_CD),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifneq ($(BUILD_PXE),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-pxe.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
ifneq ($(BUILD_BIOS_PXE),no)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/limine-bios-pxe.bin' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifeq ($(BUILD_UEFI_AARCH64),limine-uefi-aarch64)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/BOOTAA64.EFI' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifeq ($(BUILD_UEFI_RISCV64),limine-uefi-riscv64)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/BOOTRISCV64.EFI' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
ifeq ($(BUILD_UEFI_X86_64),limine-uefi-x86-64)
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(BINDIR))/BOOTX64.EFI' '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine/'
|
||||
endif
|
||||
@ -187,75 +177,62 @@ endif
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(includedir))'
|
||||
$(INSTALL_DATA) '$(call SHESCAPE,$(SRCDIR))/limine.h' '$(call SHESCAPE,$(DESTDIR)$(includedir))/'
|
||||
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(bindir))'
|
||||
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-version' '$(call SHESCAPE,$(DESTDIR)$(bindir))/'
|
||||
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-enroll-config' '$(call SHESCAPE,$(DESTDIR)$(bindir))/'
|
||||
ifneq ($(BUILD_LIMINE_DEPLOY),no)
|
||||
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-deploy' '$(call SHESCAPE,$(DESTDIR)$(bindir))/'
|
||||
endif
|
||||
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine' '$(call SHESCAPE,$(DESTDIR)$(bindir))/'
|
||||
|
||||
.PHONY: install-strip
|
||||
install-strip: install
|
||||
$(STRIP) '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-version'
|
||||
$(STRIP) '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-enroll-config'
|
||||
ifneq ($(BUILD_LIMINE_DEPLOY),no)
|
||||
$(STRIP) '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-deploy'
|
||||
endif
|
||||
$(STRIP) '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine'
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/LICENSE'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/COPYING'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/CONFIG.md'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/PROTOCOL.md'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/PHILOSOPHY.md'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(docdir))/README.md'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/limine-version.1'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/limine-deploy.1'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/limine-enroll-config.1'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-version'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-enroll-config'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine-deploy'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(mandir))/man1/limine.1'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(bindir))/limine'
|
||||
rm -rf '$(call SHESCAPE,$(DESTDIR)$(datarootdir))/limine'
|
||||
rm -f '$(call SHESCAPE,$(DESTDIR)$(includedir))/limine.h'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/stage1.stamp: $(STAGE1_FILES) $(call MKESCAPE,$(BUILDDIR))/decompressor-build/decompressor.bin $(call MKESCAPE,$(BUILDDIR))/common-bios/stage2.bin.gz
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/hdd' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-hdd.bin'
|
||||
ifneq ($(BUILD_CD),no)
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/cd' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-cd.bin'
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/hdd' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-bios-hdd.bin'
|
||||
ifneq ($(BUILD_BIOS_CD),no)
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/cd' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-bios-cd.bin'
|
||||
endif
|
||||
ifneq ($(BUILD_PXE),no)
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/pxe' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-pxe.bin'
|
||||
ifneq ($(BUILD_BIOS_PXE),no)
|
||||
cd '$(call SHESCAPE,$(SRCDIR))/stage1/pxe' && nasm bootsect.asm -Wall $(WERROR_FLAG) -fbin -DBUILDDIR="'"'$(call NASMESCAPE,$(BUILDDIR))'"'" -o '$(call SHESCAPE,$(BINDIR))/limine-bios-pxe.bin'
|
||||
endif
|
||||
cp '$(call SHESCAPE,$(BUILDDIR))/common-bios/limine.sys' '$(call SHESCAPE,$(BINDIR))/'
|
||||
cp '$(call SHESCAPE,$(BUILDDIR))/common-bios/limine-bios.sys' '$(call SHESCAPE,$(BINDIR))/'
|
||||
touch '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp'
|
||||
|
||||
.PHONY: limine-bios
|
||||
limine-bios: common-bios decompressor
|
||||
$(MAKE) '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp'
|
||||
ifneq ($(BUILD_LIMINE_DEPLOY),no)
|
||||
$(MAKE) limine-deploy
|
||||
endif
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/limine-cd-efi.bin: $(if $(BUILD_UEFI_IA32),$(call MKESCAPE,$(BUILDDIR))/common-uefi-ia32/BOOTIA32.EFI) $(if $(BUILD_UEFI_X86_64),$(call MKESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI) $(if $(BUILD_UEFI_AARCH64),$(call MKESCAPE,$(BUILDDIR))/common-uefi-aarch64/BOOTAA64.EFI)
|
||||
ifneq ($(BUILD_CD_EFI),no)
|
||||
$(call MKESCAPE,$(BINDIR))/limine-uefi-cd.bin: $(if $(BUILD_UEFI_IA32),$(call MKESCAPE,$(BUILDDIR))/common-uefi-ia32/BOOTIA32.EFI) $(if $(BUILD_UEFI_X86_64),$(call MKESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI) $(if $(BUILD_UEFI_AARCH64),$(call MKESCAPE,$(BUILDDIR))/common-uefi-aarch64/BOOTAA64.EFI) $(if $(BUILD_UEFI_RISCV64),$(call MKESCAPE,$(BUILDDIR))/common-uefi-riscv64/BOOTRISCV64.EFI)
|
||||
ifneq ($(BUILD_UEFI_CD),no)
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
|
||||
rm -f '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin'
|
||||
dd if=/dev/zero of='$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' bs=512 count=2880 2>/dev/null
|
||||
( mformat -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' -f 1440 :: && \
|
||||
mmd -D s -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' ::/EFI && \
|
||||
mmd -D s -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' ::/EFI/BOOT && \
|
||||
rm -f '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin'
|
||||
dd if=/dev/zero of='$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' bs=512 count=2880 2>/dev/null
|
||||
( mformat -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' -f 1440 :: && \
|
||||
mmd -D s -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' ::/EFI && \
|
||||
mmd -D s -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' ::/EFI/BOOT && \
|
||||
( ( [ -f '$(call SHESCAPE,$(BUILDDIR))/common-uefi-aarch64/BOOTAA64.EFI' ] && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-aarch64/BOOTAA64.EFI' ::/EFI/BOOT ) || true ) && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-aarch64/BOOTAA64.EFI' ::/EFI/BOOT ) || true ) && \
|
||||
( ( [ -f '$(call SHESCAPE,$(BUILDDIR))/common-uefi-riscv64/BOOTRISCV64.EFI' ] && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-riscv64/BOOTRISCV64.EFI' ::/EFI/BOOT ) || true ) && \
|
||||
( ( [ -f '$(call SHESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI' ] && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI' ::/EFI/BOOT ) || true ) && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI' ::/EFI/BOOT ) || true ) && \
|
||||
( ( [ -f '$(call SHESCAPE,$(BUILDDIR))/common-uefi-ia32/BOOTIA32.EFI' ] && \
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-ia32/BOOTIA32.EFI' ::/EFI/BOOT ) || true ) \
|
||||
) || rm -f '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin'
|
||||
mcopy -D o -i '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin' '$(call SHESCAPE,$(BUILDDIR))/common-uefi-ia32/BOOTIA32.EFI' ::/EFI/BOOT ) || true ) \
|
||||
) || rm -f '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin'
|
||||
endif
|
||||
|
||||
.PHONY: limine-cd-efi
|
||||
limine-cd-efi:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin'
|
||||
.PHONY: limine-uefi-cd
|
||||
limine-uefi-cd:
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-uefi-cd.bin'
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/BOOTX64.EFI: $(call MKESCAPE,$(BUILDDIR))/common-uefi-x86-64/BOOTX64.EFI
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
|
||||
@ -284,6 +261,15 @@ limine-uefi-aarch64:
|
||||
$(MAKE) common-uefi-aarch64
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/BOOTAA64.EFI'
|
||||
|
||||
$(call MKESCAPE,$(BINDIR))/BOOTRISCV64.EFI: $(call MKESCAPE,$(BUILDDIR))/common-uefi-riscv64/BOOTRISCV64.EFI
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
|
||||
cp '$(call SHESCAPE,$(BUILDDIR))/common-uefi-riscv64/BOOTRISCV64.EFI' '$(call SHESCAPE,$(BINDIR))/'
|
||||
|
||||
.PHONY: limine-uefi-riscv64
|
||||
limine-uefi-riscv64:
|
||||
$(MAKE) common-uefi-riscv64
|
||||
$(MAKE) '$(call SHESCAPE,$(BINDIR))/BOOTRISCV64.EFI'
|
||||
|
||||
.PHONY: limine-bios-clean
|
||||
limine-bios-clean: common-bios-clean decompressor-clean
|
||||
|
||||
@ -296,18 +282,22 @@ limine-uefi-ia32-clean: common-uefi-ia32-clean
|
||||
.PHONY: limine-uefi-aarch64-clean
|
||||
limine-uefi-aarch64-clean: common-uefi-aarch64-clean
|
||||
|
||||
.PHONY: limine-uefi-riscv64-clean
|
||||
limine-uefi-riscv64-clean: common-uefi-riscv64-clean
|
||||
|
||||
.PHONY: dist
|
||||
dist:
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)"
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)"
|
||||
cp -r '$(call SHESCAPE,$(SRCDIR))'/.git '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)"/
|
||||
cd '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)" && git checkout .
|
||||
cd '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)" && git log --oneline --decorate > ChangeLog
|
||||
cd '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)" && ./bootstrap
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/common/flanterm/.git"
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/freestanding-headers/.git"
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/libgcc-binaries/.git"
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/libgcc-binaries/.gitignore"
|
||||
libgcc_needed="i686 x86_64-no-red-zone aarch64"; \
|
||||
libgcc_needed="i686 x86_64-no-red-zone aarch64 riscv64-softfloat"; \
|
||||
for f in $$libgcc_needed; do \
|
||||
mv '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/libgcc-binaries/libgcc-$$f.a" '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/libgcc-binaries/libgcc-$$f.a.save"; \
|
||||
done; \
|
||||
@ -332,11 +322,11 @@ dist:
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
rm -rf ovmf* config.log config.status GNUmakefile config.h toolchain-files man/man1/limine-version.1 man/man1/limine-deploy.1 man/man1/limine-enroll-config.1
|
||||
rm -rf ovmf* config.log config.status GNUmakefile config.h toolchain-files man/man1/limine.1
|
||||
|
||||
.PHONY: maintainer-clean
|
||||
maintainer-clean: distclean
|
||||
cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf common/flanterm common/stb/stb_image.h decompressor/tinf freestanding-headers libgcc-binaries limine-efi freestanding-toolchain configure build-aux *'~' autom4te.cache aclocal.m4 *.tar.xz *.tar.gz
|
||||
cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf common/flanterm common/stb/stb_image.h decompressor/tinf freestanding-headers libgcc-binaries limine-efi freestanding-toolchain configure INSTALL build-aux *'~' autom4te.cache aclocal.m4 *.tar.xz *.tar.gz
|
||||
|
||||
.PHONY: common-uefi-x86-64
|
||||
common-uefi-x86-64:
|
||||
@ -360,6 +350,17 @@ common-uefi-aarch64:
|
||||
common-uefi-aarch64-clean:
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))/common-uefi-aarch64'
|
||||
|
||||
.PHONY: common-uefi-riscv64
|
||||
common-uefi-riscv64:
|
||||
$(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' all \
|
||||
TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-riscv64-toolchain.mk' \
|
||||
TARGET=uefi-riscv64 \
|
||||
BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-uefi-riscv64'
|
||||
|
||||
.PHONY: common-uefi-riscv64-clean
|
||||
common-uefi-riscv64-clean:
|
||||
rm -rf '$(call SHESCAPE,$(BUILDDIR))/common-uefi-riscv64'
|
||||
|
||||
.PHONY: common-uefi-ia32
|
||||
common-uefi-ia32:
|
||||
$(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' all \
|
||||
|
10
PROTOCOL.md
10
PROTOCOL.md
@ -168,8 +168,8 @@ everything is mapped with `PBMT=PMA`).
|
||||
### x86-64
|
||||
|
||||
`rip` will be the entry point as defined as part of the executable file format,
|
||||
unless the an Entry Point feature is requested (see below), in which case,
|
||||
the value of `rip` is going to be taken from there.
|
||||
unless the Entry Point feature is requested (see below), in which case, the value
|
||||
of `rip` is going to be taken from there.
|
||||
|
||||
At entry all segment registers are loaded as 64 bit code/data segments, limits
|
||||
and bases are ignored since this is 64-bit mode.
|
||||
@ -212,7 +212,7 @@ All other general purpose registers are set to 0.
|
||||
### aarch64
|
||||
|
||||
`PC` will be the entry point as defined as part of the executable file format,
|
||||
unless the an Entry Point feature is requested (see below), in which case,
|
||||
unless the Entry Point feature is requested (see below), in which case,
|
||||
the value of `PC` is going to be taken from there.
|
||||
|
||||
The contents of the `VBAR_EL1` register are undefined, and the kernel must load
|
||||
@ -253,8 +253,8 @@ Vector registers are in an undefined state.
|
||||
At entry the machine is executing in Supervisor mode.
|
||||
|
||||
`pc` will be the entry point as defined as part of the executable file format,
|
||||
unless the an Entry Point feature is requested (see below), in which case,
|
||||
the value of `pc` is going to be taken from there.
|
||||
unless the Entry Point feature is requested (see below), in which case, the
|
||||
value of `pc` is going to be taken from there.
|
||||
|
||||
`x1`(`ra`) is set to 0, the kernel must not return from the entry point.
|
||||
|
||||
|
71
README.md
71
README.md
@ -23,6 +23,7 @@ Donations welcome, but absolutely not mandatory!
|
||||
* IA-32 (32-bit x86)
|
||||
* x86-64
|
||||
* aarch64 (arm64)
|
||||
* riscv64
|
||||
|
||||
### Supported boot protocols
|
||||
* Linux
|
||||
@ -48,7 +49,7 @@ opening issues or pull requests related to this.
|
||||
For 32-bit x86 systems, support is only ensured starting with those with
|
||||
Pentium Pro (i686) class CPUs.
|
||||
|
||||
All x86-64 and aarch64 (UEFI) systems are supported.
|
||||
All x86-64, aarch64, and riscv64 (UEFI) systems are supported.
|
||||
|
||||
## Packaging status
|
||||
|
||||
@ -61,16 +62,16 @@ are shipped in the `-binary` branches and tags of this repository
|
||||
(see [branches](https://github.com/limine-bootloader/limine/branches/all) and
|
||||
[tags](https://github.com/limine-bootloader/limine/tags)).
|
||||
|
||||
For example, to clone the latest binary release of the `v4.x` branch one can do
|
||||
For example, to clone the latest binary release of the `v5.x` branch one can do
|
||||
```bash
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v4.x-branch-binary --depth=1
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v5.x-branch-binary --depth=1
|
||||
```
|
||||
or, to clone a specific binary point release (for example `v4.20231024.eol`)
|
||||
or, to clone a specific binary point release (for example `v5.20231024.0`)
|
||||
```bash
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v4.20231024.eol-binary --depth=1
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v5.20231024.0-binary --depth=1
|
||||
```
|
||||
|
||||
In order to rebuild host utilities like `limine-deploy`, simply run `make` in the binary
|
||||
In order to rebuild host utilities like `limine`, simply run `make` in the binary
|
||||
release directory.
|
||||
|
||||
Host utility binaries are provided for Windows.
|
||||
@ -85,7 +86,7 @@ Host utility binaries are provided for Windows.
|
||||
In order to build Limine, the following programs have to be installed:
|
||||
common UNIX tools (also known as `coreutils`),
|
||||
`GNU make`, `grep`, `sed`, `find`, `awk`, `gzip`, `nasm`, `mtools`
|
||||
(optional, necessary to build `limine-cd-efi.bin`).
|
||||
(optional, necessary to build `limine-uefi-cd.bin`).
|
||||
Furthermore, `gcc` or `llvm/clang` must also be installed, alongside
|
||||
the respective binutils.
|
||||
|
||||
@ -145,17 +146,17 @@ Limine can be booted with secure boot if the executable is signed and the key us
|
||||
sign it is added to the firmware's keychain. This should be done in combination with enrolling
|
||||
the BLAKE2B hash of the Limine config file into the Limine EFI executable image itself for
|
||||
verification purposes.
|
||||
For more information see the `limine-enroll-config` program and [the philosophy](/PHILOSOPHY.md).
|
||||
For more information see the `limine enroll-config` program and [the philosophy](/PHILOSOPHY.md).
|
||||
|
||||
### BIOS/MBR
|
||||
In order to install Limine on a MBR device (which can just be a raw image file),
|
||||
run `limine-deploy` as such:
|
||||
run `limine bios-install` as such:
|
||||
|
||||
```bash
|
||||
limine-deploy <path to device/image>
|
||||
limine bios-install <path to device/image>
|
||||
```
|
||||
|
||||
The boot device must contain the `limine.sys` and `limine.cfg` files in
|
||||
The boot device must contain the `limine-bios.sys` and `limine.cfg` files in
|
||||
either the root, `limine`, `boot`, or `boot/limine` directory of one of the
|
||||
partitions, formatted with a supported file system.
|
||||
|
||||
@ -163,30 +164,30 @@ partitions, formatted with a supported file system.
|
||||
If using a GPT formatted device, there are 2 options one can follow for
|
||||
installation:
|
||||
* Specifying a dedicated stage 2 partition.
|
||||
* Letting `limine-deploy` attempt to embed stage 2 within GPT structures.
|
||||
* Letting `limine bios-install` attempt to embed stage 2 within GPT structures.
|
||||
|
||||
In case one wants to specify a stage 2 partition, create a partition on the GPT
|
||||
device of at least 32KiB in size, and pass the 1-based number of the partition
|
||||
to `limine-deploy` as a second argument; such as:
|
||||
to `limine bios-install` as a second argument; such as:
|
||||
|
||||
```bash
|
||||
limine-deploy <path to device/image> <1-based stage 2 partition number>
|
||||
limine bios-install <path to device/image> <1-based stage 2 partition number>
|
||||
```
|
||||
|
||||
In case one wants to let `limine-deploy` embed stage 2 within GPT's structures,
|
||||
simply omit the partition number, and invoke `limine-deploy` the same as one
|
||||
In case one wants to let `limine bios-install` embed stage 2 within GPT's structures,
|
||||
simply omit the partition number, and invoke `limine bios-install` the same as one
|
||||
would do for an MBR partitioned device.
|
||||
|
||||
The boot device must contain the `limine.sys` and `limine.cfg` files in
|
||||
The boot device must contain the `limine-bios.sys` and `limine.cfg` files in
|
||||
either the root, `limine`, `boot`, or `boot/limine` directory of one of the
|
||||
partitions, formatted with a supported file system.
|
||||
|
||||
### BIOS/UEFI hybrid ISO creation
|
||||
In order to create a hybrid ISO with Limine, place the
|
||||
`limine-cd-efi.bin`, `limine-cd.bin`, `limine.sys`, and `limine.cfg` files
|
||||
`limine-uefi-cd.bin`, `limine-bios-cd.bin`, `limine-bios.sys`, and `limine.cfg` files
|
||||
into a directory which will serve as the root of the created ISO.
|
||||
(`limine.sys` and `limine.cfg` must either be in the root, `limine`, `boot`, or
|
||||
`boot/limine` directory; `limine-cd-efi.bin` and `limine-cd.bin` can reside
|
||||
(`limine-bios.sys` and `limine.cfg` must either be in the root, `limine`, `boot`, or
|
||||
`boot/limine` directory; `limine-uefi-cd.bin` and `limine-bios-cd.bin` can reside
|
||||
anywhere).
|
||||
|
||||
After that, create a `<ISO root directory>/EFI/BOOT` directory and copy the
|
||||
@ -195,43 +196,43 @@ relevant Limine EFI executables over (such as `BOOTX64.EFI`).
|
||||
Place any other file you want to be on the final ISO in said directory, then
|
||||
run:
|
||||
```
|
||||
xorriso -as mkisofs -b <relative path of limine-cd.bin> \
|
||||
xorriso -as mkisofs -b <relative path of limine-bios-cd.bin> \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
--efi-boot <relative path of limine-cd-efi.bin> \
|
||||
--efi-boot <relative path of limine-uefi-cd.bin> \
|
||||
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
||||
<root directory> -o image.iso
|
||||
```
|
||||
|
||||
*Note: `xorriso` is required.*
|
||||
|
||||
And do not forget to also run `limine-deploy` on the generated image:
|
||||
And do not forget to also run `limine bios-install` on the generated image:
|
||||
```
|
||||
limine-deploy image.iso
|
||||
limine bios-install image.iso
|
||||
```
|
||||
|
||||
`<relative path of limine-cd.bin>` is the relative path of
|
||||
`limine-cd.bin` inside the root directory.
|
||||
For example, if it was copied in `<root directory>/boot/limine-cd.bin`,
|
||||
it would be `boot/limine-cd.bin`.
|
||||
`<relative path of limine-bios-cd.bin>` is the relative path of
|
||||
`limine-bios-cd.bin` inside the root directory.
|
||||
For example, if it was copied in `<root directory>/boot/limine-bios-cd.bin`,
|
||||
it would be `boot/limine-bios-cd.bin`.
|
||||
|
||||
`<relative path of limine-cd-efi.bin>` is the relative path of
|
||||
`limine-cd-efi.bin` inside the root directory.
|
||||
`<relative path of limine-uefi-cd.bin>` is the relative path of
|
||||
`limine-uefi-cd.bin` inside the root directory.
|
||||
For example, if it was copied in
|
||||
`<root directory>/boot/limine-cd-efi.bin`, it would be
|
||||
`boot/limine-cd-efi.bin`.
|
||||
`<root directory>/boot/limine-uefi-cd.bin`, it would be
|
||||
`boot/limine-uefi-cd.bin`.
|
||||
|
||||
### BIOS/PXE boot
|
||||
The `limine-pxe.bin` binary is a valid PXE boot image.
|
||||
The `limine-bios-pxe.bin` binary is a valid PXE boot image.
|
||||
In order to boot Limine from PXE it is necessary to setup a DHCP server with
|
||||
support for PXE booting. This can either be accomplished using a single DHCP
|
||||
server or your existing DHCP server and a proxy DHCP server such as dnsmasq.
|
||||
|
||||
`limine.cfg` and `limine.sys` are expected to be on the server used for boot.
|
||||
`limine.cfg` and `limine-bios.sys` are expected to be on the server used for boot.
|
||||
|
||||
### UEFI/PXE boot
|
||||
The `BOOT*.EFI` files are compatible with UEFI PXE.
|
||||
The steps needed to boot Limine are the same as with BIOS PXE,
|
||||
except that the `limine.sys` file is not needed on the server.
|
||||
except that the `limine-bios.sys` file is not needed on the server.
|
||||
|
||||
### Configuration
|
||||
The `limine.cfg` file contains Limine's configuration.
|
||||
|
@ -26,7 +26,9 @@ fi
|
||||
[ -d limine-efi ] || git clone https://github.com/limine-bootloader/limine-efi.git $SHALLOW_CLONE_FLAG
|
||||
[ -d libgcc-binaries ] || git clone https://github.com/mintsuki/libgcc-binaries.git $SHALLOW_CLONE_FLAG
|
||||
|
||||
AUTOMAKE_LIBDIR="$(automake --print-libdir)"
|
||||
cp "${AUTOMAKE_LIBDIR}/INSTALL" ./
|
||||
mkdir -p build-aux
|
||||
cp "$(automake --print-libdir)/install-sh" build-aux
|
||||
cp "${AUTOMAKE_LIBDIR}/install-sh" build-aux/
|
||||
|
||||
autoreconf -fvi -Wall
|
||||
|
@ -35,7 +35,6 @@ override CFLAGS_FOR_TARGET += \
|
||||
-Wextra \
|
||||
-Wshadow \
|
||||
-Wvla \
|
||||
-Wno-deprecated-declarations \
|
||||
$(WERROR_FLAG) \
|
||||
-std=gnu11 \
|
||||
-nostdinc \
|
||||
@ -116,6 +115,29 @@ ifeq ($(TARGET),uefi-aarch64)
|
||||
-DUEFI
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
override CFLAGS_FOR_TARGET += \
|
||||
-fPIE \
|
||||
-fshort-wchar
|
||||
|
||||
ifeq ($(CC_FOR_TARGET_IS_CLANG),yes)
|
||||
override CFLAGS_FOR_TARGET += -march=rv64imac
|
||||
else
|
||||
override CFLAGS_FOR_TARGET += -march=rv64imac_zicsr_zifencei
|
||||
endif
|
||||
|
||||
override CFLAGS_FOR_TARGET += \
|
||||
-mabi=lp64 \
|
||||
-mno-relax
|
||||
|
||||
override CPPFLAGS_FOR_TARGET := \
|
||||
-I'$(call SHESCAPE,$(BUILDDIR))/limine-efi/inc' \
|
||||
-I'$(call SHESCAPE,$(BUILDDIR))/limine-efi/inc/riscv64' \
|
||||
$(CPPFLAGS_FOR_TARGET) \
|
||||
-DUEFI \
|
||||
-D__riscv64
|
||||
endif
|
||||
|
||||
override LDFLAGS_FOR_TARGET += \
|
||||
-nostdlib \
|
||||
-z max-page-size=0x1000
|
||||
@ -158,6 +180,16 @@ ifeq ($(TARGET),uefi-aarch64)
|
||||
-z text
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
override LDFLAGS_FOR_TARGET += \
|
||||
-m elf64lriscv \
|
||||
--no-relax \
|
||||
-static \
|
||||
-pie \
|
||||
--no-dynamic-linker \
|
||||
-z text
|
||||
endif
|
||||
|
||||
override C_FILES := $(shell find . -type f -name '*.c')
|
||||
ifeq ($(TARGET),bios)
|
||||
override ASMX86_FILES := $(shell find . -type f -name '*.asm_x86')
|
||||
@ -187,19 +219,27 @@ ifeq ($(TARGET),uefi-aarch64)
|
||||
|
||||
override OBJ := $(addprefix $(call MKESCAPE,$(BUILDDIR))/, $(C_FILES:.c=.o) $(ASM64_FILES:.asm_aarch64=.o) $(ASM64U_FILES:.asm_uefi_aarch64=.o))
|
||||
endif
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
override ASM64_FILES := $(shell find . -type f -name '*.asm_riscv64')
|
||||
override ASM64U_FILES := $(shell find . -type f -name '*.asm_uefi_riscv64')
|
||||
|
||||
override OBJ := $(addprefix $(call MKESCAPE,$(BUILDDIR))/, $(C_FILES:.c=.o) $(ASM64_FILES:.asm_riscv64=.o) $(ASM64U_FILES:.asm_uefi_riscv64=.o))
|
||||
endif
|
||||
|
||||
override HEADER_DEPS := $(addprefix $(call MKESCAPE,$(BUILDDIR))/, $(C_FILES:.c=.d))
|
||||
|
||||
.PHONY: all
|
||||
|
||||
ifeq ($(TARGET),bios)
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/limine.sys $(call MKESCAPE,$(BUILDDIR))/stage2.bin.gz
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/limine-bios.sys $(call MKESCAPE,$(BUILDDIR))/stage2.bin.gz
|
||||
else ifeq ($(TARGET),uefi-x86-64)
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/BOOTX64.EFI
|
||||
else ifeq ($(TARGET),uefi-ia32)
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/BOOTIA32.EFI
|
||||
else ifeq ($(TARGET),uefi-aarch64)
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/BOOTAA64.EFI
|
||||
else ifeq ($(TARGET),uefi-riscv64)
|
||||
all: $(call MKESCAPE,$(BUILDDIR))/BOOTRISCV64.EFI
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),bios)
|
||||
@ -207,7 +247,7 @@ ifeq ($(TARGET),bios)
|
||||
$(call MKESCAPE,$(BUILDDIR))/stage2.bin.gz: $(call MKESCAPE,$(BUILDDIR))/stage2.bin
|
||||
gzip -n -9 < '$(call SHESCAPE,$<)' > '$(call SHESCAPE,$@)'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/stage2.bin: $(call MKESCAPE,$(BUILDDIR))/limine.sys
|
||||
$(call MKESCAPE,$(BUILDDIR))/stage2.bin: $(call MKESCAPE,$(BUILDDIR))/limine-bios.sys
|
||||
dd if='$(call SHESCAPE,$<)' bs=$$(( 0x$$("$(READELF_FOR_TARGET)" -S '$(call SHESCAPE,$(BUILDDIR))/limine.elf' | $(GREP) '\.text\.stage3' | $(SED) 's/^.*] //' | $(AWK) '{print $$3}' | $(SED) 's/^0*//') - 0xf000 )) count=1 of='$(call SHESCAPE,$@)' 2>/dev/null
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/stage2.map.o: $(call MKESCAPE,$(BUILDDIR))/limine_nomap.elf
|
||||
@ -222,7 +262,7 @@ $(call MKESCAPE,$(BUILDDIR))/full.map.o: $(call MKESCAPE,$(BUILDDIR))/limine_nos
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -c '$(call SHESCAPE,$(BUILDDIR))/full.map.S' -o '$(call SHESCAPE,$@)'
|
||||
rm -f '$(call SHESCAPE,$(BUILDDIR))/full.map.S' '$(call SHESCAPE,$(BUILDDIR))/full.map.d'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine.sys: $(call MKESCAPE,$(BUILDDIR))/limine_stage2only.elf $(call MKESCAPE,$(BUILDDIR))/limine.elf
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine-bios.sys: $(call MKESCAPE,$(BUILDDIR))/limine_stage2only.elf $(call MKESCAPE,$(BUILDDIR))/limine.elf
|
||||
$(OBJCOPY_FOR_TARGET) -O binary '$(call SHESCAPE,$(BUILDDIR))/limine.elf' '$(call SHESCAPE,$@)'
|
||||
chmod -x '$(call SHESCAPE,$@)'
|
||||
|
||||
@ -390,6 +430,51 @@ $(call MKESCAPE,$(BUILDDIR))/limine.elf: $(call MKESCAPE,$(BUILDDIR))/limine-efi
|
||||
'$(call OBJESCAPE,$^)' $(LDFLAGS_FOR_TARGET) -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/full.map.o: $(call MKESCAPE,$(BUILDDIR))/limine_nomap.elf
|
||||
cd '$(call SHESCAPE,$(BUILDDIR))' && \
|
||||
'$(call SHESCAPE,$(SRCDIR))/gensyms.sh' '$(call SHESCAPE,$<)' full 64 '\.text'
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -c '$(call SHESCAPE,$(BUILDDIR))/full.map.S' -o '$(call SHESCAPE,$@)'
|
||||
rm -f '$(call SHESCAPE,$(BUILDDIR))/full.map.S' '$(call SHESCAPE,$(BUILDDIR))/full.map.d'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/BOOTRISCV64.EFI: $(call MKESCAPE,$(BUILDDIR))/limine.elf
|
||||
$(OBJCOPY_FOR_TARGET) -O binary '$(call SHESCAPE,$<)' '$(call SHESCAPE,$@)'
|
||||
chmod -x '$(call SHESCAPE,$@)'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/crt0-efi-riscv64.S.o: limine-efi
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/reloc_riscv64.c.o: limine-efi
|
||||
|
||||
.PHONY: limine-efi
|
||||
limine-efi: $(call MKESCAPE,$(BUILDDIR))/limine-efi
|
||||
$(MAKE) -C '$(call SHESCAPE,$(BUILDDIR))/limine-efi/gnuefi' \
|
||||
CC="$(CC_FOR_TARGET)" \
|
||||
CFLAGS="$(BASE_CFLAGS)" \
|
||||
CPPFLAGS='-nostdinc -I$(call SHESCAPE,$(SRCDIR))/../freestanding-headers' \
|
||||
ARCH=riscv64
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/linker_nomap.ld: linker_uefi_riscv64.ld.in
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BUILDDIR))'
|
||||
$(CC_FOR_TARGET) -x c -E -P -undef -DLINKER_NOMAP linker_uefi_riscv64.ld.in -o '$(call SHESCAPE,$(BUILDDIR))/linker_nomap.ld'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine_nomap.elf: $(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/crt0-efi-riscv64.S.o $(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/reloc_riscv64.c.o $(OBJ) ../libgcc-binaries/libgcc-riscv64-softfloat.a
|
||||
$(MAKE) '$(call SHESCAPE,$(BUILDDIR))/linker_nomap.ld'
|
||||
$(LD_FOR_TARGET) \
|
||||
-T'$(call SHESCAPE,$(BUILDDIR))/linker_nomap.ld' \
|
||||
'$(call OBJESCAPE,$^)' $(LDFLAGS_FOR_TARGET) -o '$(call SHESCAPE,$@)'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/linker.ld: linker_uefi_riscv64.ld.in
|
||||
$(MKDIR_P) '$(call SHESCAPE,$(BUILDDIR))'
|
||||
$(CC_FOR_TARGET) -x c -E -P -undef linker_uefi_riscv64.ld.in -o '$(call SHESCAPE,$(BUILDDIR))/linker.ld'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/limine.elf: $(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/crt0-efi-riscv64.S.o $(call MKESCAPE,$(BUILDDIR))/limine-efi/gnuefi/reloc_riscv64.c.o $(OBJ) ../libgcc-binaries/libgcc-riscv64-softfloat.a $(call MKESCAPE,$(BUILDDIR))/full.map.o
|
||||
$(MAKE) '$(call SHESCAPE,$(BUILDDIR))/linker.ld'
|
||||
$(LD_FOR_TARGET) \
|
||||
-T'$(call SHESCAPE,$(BUILDDIR))/linker.ld' \
|
||||
'$(call OBJESCAPE,$^)' $(LDFLAGS_FOR_TARGET) -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-ia32)
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/full.map.o: $(call MKESCAPE,$(BUILDDIR))/limine_nomap.elf
|
||||
@ -450,6 +535,12 @@ $(call MKESCAPE,$(BUILDDIR))/%.o: %.c $(call MKESCAPE,$(BUILDDIR))/limine-efi
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
$(call MKESCAPE,$(BUILDDIR))/%.o: %.c $(call MKESCAPE,$(BUILDDIR))/limine-efi
|
||||
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-ia32)
|
||||
$(call MKESCAPE,$(BUILDDIR))/%.o: %.c $(call MKESCAPE,$(BUILDDIR))/limine-efi
|
||||
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
|
||||
@ -510,6 +601,16 @@ $(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_uefi_aarch64
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -x assembler-with-cpp -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-riscv64)
|
||||
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_riscv64
|
||||
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -x assembler-with-cpp -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@)'
|
||||
|
||||
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_uefi_riscv64
|
||||
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
|
||||
$(CC_FOR_TARGET) $(CFLAGS_FOR_TARGET) $(CPPFLAGS_FOR_TARGET) -x assembler-with-cpp -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@)'
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),uefi-ia32)
|
||||
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_ia32
|
||||
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
|
||||
|
11
common/efi_thunk.asm_uefi_riscv64
Normal file
11
common/efi_thunk.asm_uefi_riscv64
Normal file
@ -0,0 +1,11 @@
|
||||
.section .text
|
||||
|
||||
.global efi_main
|
||||
.extern uefi_entry
|
||||
efi_main:
|
||||
.option norelax
|
||||
mv fp, zero
|
||||
mv ra, zero
|
||||
j uefi_entry
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
@ -32,7 +32,7 @@ bool stage3_loaded = false;
|
||||
static bool stage3_found = false;
|
||||
|
||||
extern symbol stage3_addr;
|
||||
extern symbol limine_sys_size;
|
||||
extern symbol limine_bios_sys_size;
|
||||
extern symbol build_id_s2;
|
||||
extern symbol build_id_s3;
|
||||
|
||||
@ -41,10 +41,10 @@ static bool stage3_init(struct volume *part) {
|
||||
|
||||
bool old_cif = case_insensitive_fopen;
|
||||
case_insensitive_fopen = true;
|
||||
if ((stage3 = fopen(part, "/limine.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/limine/limine.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/boot/limine.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/boot/limine/limine.sys")) == NULL) {
|
||||
if ((stage3 = fopen(part, "/limine-bios.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/limine/limine-bios.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/boot/limine-bios.sys")) == NULL
|
||||
&& (stage3 = fopen(part, "/boot/limine/limine-bios.sys")) == NULL) {
|
||||
case_insensitive_fopen = old_cif;
|
||||
return false;
|
||||
}
|
||||
@ -52,8 +52,8 @@ static bool stage3_init(struct volume *part) {
|
||||
|
||||
stage3_found = true;
|
||||
|
||||
if (stage3->size != (size_t)limine_sys_size) {
|
||||
print("limine.sys size incorrect.\n");
|
||||
if (stage3->size != (size_t)limine_bios_sys_size) {
|
||||
print("limine-bios.sys size incorrect.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ static bool stage3_init(struct volume *part) {
|
||||
fclose(stage3);
|
||||
|
||||
if (memcmp(build_id_s2 + 16, build_id_s3 + 16, 20) != 0) {
|
||||
print("limine.sys build ID mismatch.\n");
|
||||
print("limine-bios.sys build ID mismatch.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ noreturn void entry(uint8_t boot_drive, int boot_from) {
|
||||
if (!stage3_found) {
|
||||
print("\n"
|
||||
"!! Stage 3 file not found!\n"
|
||||
"!! Have you copied limine.sys to the root, /boot, /limine, or /boot/limine\n"
|
||||
"!! Have you copied limine-bios.sys to the root, /boot, /limine, or /boot/limine\n"
|
||||
"!! directories of one of the partitions on the boot device?\n\n");
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <drivers/disk.h>
|
||||
#include <sys/lapic.h>
|
||||
#include <lib/readline.h>
|
||||
#include <sys/cpu.h>
|
||||
|
||||
void stage3_common(void);
|
||||
|
||||
@ -130,6 +131,18 @@ noreturn void stage3_common(void) {
|
||||
init_io_apics();
|
||||
#endif
|
||||
|
||||
#if defined (__riscv)
|
||||
#if defined (UEFI)
|
||||
RISCV_EFI_BOOT_PROTOCOL *rv_proto = get_riscv_boot_protocol();
|
||||
if (rv_proto == NULL || rv_proto->GetBootHartId(rv_proto, &bsp_hartid) != EFI_SUCCESS) {
|
||||
panic(false, "failed to get BSP's hartid");
|
||||
}
|
||||
#else
|
||||
#error riscv: only UEFI is supported
|
||||
#endif
|
||||
init_riscv();
|
||||
#endif
|
||||
|
||||
term_notready();
|
||||
|
||||
menu(true);
|
||||
|
@ -196,6 +196,8 @@ int init_config(size_t config_size) {
|
||||
}
|
||||
#elif defined (__aarch64__)
|
||||
strcpy(arch_macro->value, "aarch64");
|
||||
#elif defined (__riscv64)
|
||||
strcpy(arch_macro->value, "riscv64");
|
||||
#else
|
||||
#error "Unspecified architecture"
|
||||
#endif
|
||||
@ -251,10 +253,17 @@ int init_config(size_t config_size) {
|
||||
panic(true, "config: Malformed macro usage");
|
||||
}
|
||||
}
|
||||
if (config_addr[i] != '=') {
|
||||
if (config_addr[i++] != '=') {
|
||||
i = orig_i;
|
||||
goto next;
|
||||
}
|
||||
while (config_addr[i] != '\n' && config_addr[i] != 0) {
|
||||
i++;
|
||||
if (i >= config_size) {
|
||||
bad_config = true;
|
||||
panic(true, "config: Malformed macro usage");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,14 @@
|
||||
#define ARCH_X86_64 0x3e
|
||||
#define ARCH_X86_32 0x03
|
||||
#define ARCH_AARCH64 0xb7
|
||||
#define ARCH_RISCV 0xf3
|
||||
#define BITS_LE 0x01
|
||||
#define ELFCLASS64 0x02
|
||||
#define ET_DYN 0x0003
|
||||
#define SHT_RELA 0x00000004
|
||||
#define R_X86_64_RELATIVE 0x00000008
|
||||
#define R_AARCH64_RELATIVE 0x00000403
|
||||
#define R_RISCV_RELATIVE 0x00000003
|
||||
|
||||
/* Indices into identification array */
|
||||
#define EI_CLASS 4
|
||||
@ -103,6 +106,8 @@ int elf_bits(uint8_t *elf) {
|
||||
case ARCH_X86_64:
|
||||
case ARCH_AARCH64:
|
||||
return 64;
|
||||
case ARCH_RISCV:
|
||||
return (hdr->ident[EI_CLASS] == ELFCLASS64) ? 64 : 32;
|
||||
case ARCH_X86_32:
|
||||
return 32;
|
||||
default:
|
||||
@ -226,6 +231,8 @@ static bool elf64_apply_relocations(uint8_t *elf, struct elf64_hdr *hdr, void *b
|
||||
case R_X86_64_RELATIVE:
|
||||
#elif defined (__aarch64__)
|
||||
case R_AARCH64_RELATIVE:
|
||||
#elif defined (__riscv64)
|
||||
case R_RISCV_RELATIVE:
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
@ -281,6 +288,11 @@ bool elf64_load_section(uint8_t *elf, void *buffer, const char *name, size_t lim
|
||||
printv("elf: Not an aarch64 ELF file.\n");
|
||||
return false;
|
||||
}
|
||||
#elif defined (__riscv64)
|
||||
if (hdr->machine != ARCH_RISCV && hdr->ident[EI_CLASS] == ELFCLASS64) {
|
||||
printv("elf: Not a riscv64 ELF file.\n");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
@ -420,6 +432,10 @@ bool elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *_slide, uint32_t
|
||||
if (hdr->machine != ARCH_AARCH64) {
|
||||
panic(true, "elf: Not an aarch64 ELF file.\n");
|
||||
}
|
||||
#elif defined (__riscv64)
|
||||
if (hdr->machine != ARCH_RISCV && hdr->ident[EI_CLASS] == ELFCLASS64) {
|
||||
panic(true, "elf: Not a riscv64 ELF file.\n");
|
||||
}
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -110,6 +110,46 @@ uint32_t hex2bin(uint8_t *str, uint32_t size) {
|
||||
|
||||
#if defined (UEFI)
|
||||
|
||||
#if defined (__riscv)
|
||||
|
||||
RISCV_EFI_BOOT_PROTOCOL *get_riscv_boot_protocol(void) {
|
||||
EFI_GUID boot_proto_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
|
||||
RISCV_EFI_BOOT_PROTOCOL *proto;
|
||||
|
||||
// LocateProtocol() is available from EFI version 1.1
|
||||
if (gBS->Hdr.Revision >= ((1 << 16) | 10)) {
|
||||
if (gBS->LocateProtocol(&boot_proto_guid, NULL, (void **)&proto) == EFI_SUCCESS) {
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
UINTN bufsz = 0;
|
||||
if (gBS->LocateHandle(ByProtocol, &boot_proto_guid, NULL, &bufsz, NULL) != EFI_BUFFER_TOO_SMALL)
|
||||
return NULL;
|
||||
|
||||
EFI_HANDLE *handles_buf = ext_mem_alloc(bufsz);
|
||||
if (handles_buf == NULL)
|
||||
return NULL;
|
||||
|
||||
if (bufsz < sizeof(EFI_HANDLE))
|
||||
goto error;
|
||||
|
||||
if (gBS->LocateHandle(ByProtocol, &boot_proto_guid, NULL, &bufsz, handles_buf) != EFI_SUCCESS)
|
||||
goto error;
|
||||
|
||||
if (gBS->HandleProtocol(handles_buf[0], &boot_proto_guid, (void **)&proto) != EFI_SUCCESS)
|
||||
goto error;
|
||||
|
||||
pmm_free(handles_buf, bufsz);
|
||||
return proto;
|
||||
|
||||
error:
|
||||
pmm_free(handles_buf, bufsz);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
no_unwind bool efi_boot_services_exited = false;
|
||||
|
||||
bool efi_exit_boot_services(void) {
|
||||
@ -163,6 +203,8 @@ retry:
|
||||
asm volatile ("cli" ::: "memory");
|
||||
#elif defined (__aarch64__)
|
||||
asm volatile ("msr daifset, #15" ::: "memory");
|
||||
#elif defined (__riscv64)
|
||||
asm volatile ("csrci sstatus, 0x2" ::: "memory");
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include <lib/libc.h>
|
||||
#if defined (UEFI)
|
||||
# include <efi.h>
|
||||
# if defined (__riscv64)
|
||||
# include <protocol/riscv/efiboot.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (UEFI)
|
||||
@ -57,7 +60,7 @@ uint64_t strtoui(const char *s, const char **end, int base);
|
||||
|
||||
#if defined (__i386__)
|
||||
void memcpy32to64(uint64_t, uint64_t, uint64_t);
|
||||
#elif defined (__x86_64__) || defined (__aarch64__)
|
||||
#elif defined (__x86_64__) || defined (__aarch64__) || defined(__riscv64)
|
||||
# define memcpy32to64(X, Y, Z) memcpy((void *)(uintptr_t)(X), (void *)(uintptr_t)(Y), Z)
|
||||
#else
|
||||
#error Unknown architecture
|
||||
@ -95,6 +98,11 @@ noreturn void common_spinup(void *fnptr, int args, ...);
|
||||
noreturn void enter_in_el1(uint64_t entry, uint64_t sp, uint64_t sctlr,
|
||||
uint64_t mair, uint64_t tcr, uint64_t ttbr0,
|
||||
uint64_t ttbr1, uint64_t target_x0);
|
||||
#elif defined (__riscv64)
|
||||
noreturn void riscv_spinup(uint64_t entry, uint64_t sp, uint64_t satp);
|
||||
#if defined (UEFI)
|
||||
RISCV_EFI_BOOT_PROTOCOL *get_riscv_boot_protocol(void);
|
||||
#endif
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -74,7 +74,7 @@ noreturn void panic(bool allow_menu, const char *fmt, ...) {
|
||||
for (;;) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
asm ("hlt");
|
||||
#elif defined (__aarch64__)
|
||||
#elif defined (__aarch64__) || defined (__riscv64)
|
||||
asm ("wfi");
|
||||
#else
|
||||
#error Unknown architecture
|
||||
|
47
common/lib/spinup.asm_riscv64
Normal file
47
common/lib/spinup.asm_riscv64
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
.section .text
|
||||
|
||||
.global riscv_spinup
|
||||
riscv_spinup:
|
||||
.option norelax
|
||||
csrci sstatus, 0x2
|
||||
csrw sie, zero
|
||||
csrw stvec, zero
|
||||
|
||||
mv t0, a0
|
||||
mv sp, a1
|
||||
csrw satp, a2
|
||||
|
||||
mv a0, zero
|
||||
mv a1, zero
|
||||
mv a2, zero
|
||||
mv a3, zero
|
||||
mv a4, zero
|
||||
mv a5, zero
|
||||
mv a6, zero
|
||||
mv a7, zero
|
||||
mv s0, zero
|
||||
mv s1, zero
|
||||
mv s2, zero
|
||||
mv s3, zero
|
||||
mv s4, zero
|
||||
mv s5, zero
|
||||
mv s6, zero
|
||||
mv s7, zero
|
||||
mv s8, zero
|
||||
mv s9, zero
|
||||
mv s10, zero
|
||||
mv s11, zero
|
||||
mv t1, zero
|
||||
mv t2, zero
|
||||
mv t3, zero
|
||||
mv t4, zero
|
||||
mv t5, zero
|
||||
mv t6, zero
|
||||
mv tp, zero
|
||||
mv gp, zero
|
||||
mv ra, zero
|
||||
|
||||
jr t0
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
@ -346,7 +346,7 @@ void _term_write(struct flanterm_context *term, uint64_t buf, uint64_t count) {
|
||||
}
|
||||
|
||||
bool native = false;
|
||||
#if defined (__x86_64__) || defined (__aarch64__)
|
||||
#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
|
||||
native = true;
|
||||
#elif !defined (__i386__)
|
||||
#error Unknown architecture
|
||||
|
@ -54,6 +54,8 @@ void print_stacktrace(size_t *base_ptr) {
|
||||
"movq %%rbp, %0"
|
||||
#elif defined (__aarch64__)
|
||||
"mov %0, x29"
|
||||
#elif defined (__riscv64)
|
||||
"mv %0, fp; addi %0, %0, -16"
|
||||
#endif
|
||||
: "=r"(base_ptr)
|
||||
:: "memory"
|
||||
@ -73,7 +75,11 @@ void print_stacktrace(size_t *base_ptr) {
|
||||
print(" [%p]\n", ret_addr);
|
||||
if (!old_bp)
|
||||
break;
|
||||
#if defined (__riscv)
|
||||
base_ptr = (void *)(old_bp - 16);
|
||||
#else
|
||||
base_ptr = (void*)old_bp;
|
||||
#endif
|
||||
}
|
||||
print("End of trace. ");
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ SECTIONS
|
||||
|
||||
.note.gnu.build-id : {
|
||||
*(.note.gnu.build-id)
|
||||
limine_sys_size = . - 0xf000;
|
||||
limine_bios_sys_size = . - 0xf000;
|
||||
} :data_s3
|
||||
|
||||
.bss : {
|
||||
|
81
common/linker_uefi_riscv64.ld.in
Normal file
81
common/linker_uefi_riscv64.ld.in
Normal file
@ -0,0 +1,81 @@
|
||||
OUTPUT_FORMAT(elf64-littleriscv)
|
||||
OUTPUT_ARCH(riscv:rv64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ;
|
||||
rodata PT_LOAD FLAGS((1 << 2)) ;
|
||||
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ;
|
||||
dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
__slide = .;
|
||||
__image_base = ABSOLUTE(.);
|
||||
__image_size = ABSOLUTE(__image_end - __image_base);
|
||||
|
||||
.text : {
|
||||
*(.pe_header)
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
__text_start = ABSOLUTE(.);
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
__text_end = ABSOLUTE(.);
|
||||
__text_size = ABSOLUTE(__text_end - __text_start);
|
||||
|
||||
.rodata : {
|
||||
__reloc_start = ABSOLUTE(.);
|
||||
*(.dummy_reloc)
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
__reloc_end = ABSOLUTE(.);
|
||||
__reloc_size = ABSOLUTE(__reloc_end - __reloc_start);
|
||||
|
||||
__data_start = ABSOLUTE(.);
|
||||
*(.rodata .rodata.*)
|
||||
|
||||
#ifdef LINKER_NOMAP
|
||||
full_map = .;
|
||||
#else
|
||||
*(.full_map)
|
||||
#endif
|
||||
} :rodata
|
||||
|
||||
.data : {
|
||||
data_begin = .;
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.*)
|
||||
*(.sbss .sbss.*)
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
data_end = .;
|
||||
|
||||
*(.no_unwind)
|
||||
} :data
|
||||
|
||||
.got : {
|
||||
*(.got .got.*)
|
||||
} :data
|
||||
|
||||
.dynamic : {
|
||||
*(.dynamic)
|
||||
. = ALIGN(0x1000);
|
||||
} :data :dynamic
|
||||
|
||||
__data_end = ABSOLUTE(.);
|
||||
__data_size = ABSOLUTE(__data_end - __data_start);
|
||||
|
||||
__image_end = ABSOLUTE(.);
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
@ -977,21 +977,21 @@ noreturn void boot(char *config) {
|
||||
linux_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("TODO: Linux is not available on aarch64.\n\n");
|
||||
print("TODO: Linux is not available on aarch64 or riscv64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "multiboot1") || !strcmp(proto, "multiboot")) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
multiboot1_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("Multiboot 1 is not available on aarch64.\n\n");
|
||||
print("Multiboot 1 is not available on aarch64 or riscv64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "multiboot2")) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
multiboot2_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("Multiboot 2 is not available on aarch64.\n\n");
|
||||
print("Multiboot 2 is not available on aarch64 or riscv64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "chainload_next")) {
|
||||
chainload_next(config, cmdline);
|
||||
|
24
common/menu_thunk.asm_riscv64
Normal file
24
common/menu_thunk.asm_riscv64
Normal file
@ -0,0 +1,24 @@
|
||||
.section .data
|
||||
|
||||
.p2align 3
|
||||
stack_at_first_entry:
|
||||
.8byte 0
|
||||
|
||||
.section .text
|
||||
|
||||
.global menu
|
||||
.extern _menu
|
||||
|
||||
menu:
|
||||
.option norelax
|
||||
lla t0, stack_at_first_entry
|
||||
ld t1, (t0)
|
||||
beqz t1, 1f
|
||||
mv sp, t1
|
||||
j 2f
|
||||
1: sd sp, (t0)
|
||||
2: mv fp, zero
|
||||
mv ra, zero
|
||||
j _menu
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
146
common/mm/vmm.c
146
common/mm/vmm.c
@ -243,6 +243,152 @@ level4:
|
||||
pml1[pml1_entry] = (pt_entry_t)(phys_addr | real_flags | PT_FLAG_4K_PAGE);
|
||||
}
|
||||
|
||||
#elif defined (__riscv64)
|
||||
|
||||
#define PT_FLAG_VALID ((uint64_t)1 << 0)
|
||||
#define PT_FLAG_READ ((uint64_t)1 << 1)
|
||||
#define PT_FLAG_WRITE ((uint64_t)1 << 2)
|
||||
#define PT_FLAG_EXEC ((uint64_t)1 << 3)
|
||||
#define PT_FLAG_USER ((uint64_t)1 << 4)
|
||||
#define PT_FLAG_ACCESSED ((uint64_t)1 << 6)
|
||||
#define PT_FLAG_DIRTY ((uint64_t)1 << 7)
|
||||
#define PT_FLAG_PBMT_NC ((uint64_t)1 << 62)
|
||||
#define PT_PADDR_MASK ((uint64_t)0x003ffffffffffc00)
|
||||
|
||||
#define PT_FLAG_RWX (PT_FLAG_READ | PT_FLAG_WRITE | PT_FLAG_EXEC)
|
||||
|
||||
#define PT_TABLE_FLAGS PT_FLAG_VALID
|
||||
#define PT_IS_TABLE(x) (((x) & (PT_FLAG_VALID | PT_FLAG_RWX)) == PT_FLAG_VALID)
|
||||
#define PT_IS_LARGE(x) (((x) & (PT_FLAG_VALID | PT_FLAG_RWX)) > PT_FLAG_VALID)
|
||||
#define PT_TO_VMM_FLAGS(x) (pt_to_vmm_flags_internal(x))
|
||||
|
||||
#define pte_new(addr, flags) (((pt_entry_t)(addr) >> 2) | (flags))
|
||||
#define pte_addr(pte) (((pte) & PT_PADDR_MASK) << 2)
|
||||
|
||||
static uint64_t pt_to_vmm_flags_internal(pt_entry_t entry) {
|
||||
uint64_t flags = 0;
|
||||
|
||||
if (entry & PT_FLAG_WRITE)
|
||||
flags |= VMM_FLAG_WRITE;
|
||||
if (!(entry & PT_FLAG_EXEC))
|
||||
flags |= VMM_FLAG_NOEXEC;
|
||||
if (entry & PT_FLAG_PBMT_NC)
|
||||
flags |= VMM_FLAG_FB;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint64_t paging_mode_higher_half(int paging_mode) {
|
||||
switch (paging_mode) {
|
||||
case PAGING_MODE_RISCV_SV39:
|
||||
return 0xffffffc000000000;
|
||||
case PAGING_MODE_RISCV_SV48:
|
||||
return 0xffff800000000000;
|
||||
case PAGING_MODE_RISCV_SV57:
|
||||
return 0xff00000000000000;
|
||||
default:
|
||||
panic(false, "paging_mode_higher_half: invalid mode");
|
||||
}
|
||||
}
|
||||
|
||||
int paging_mode_va_bits(int paging_mode) {
|
||||
switch (paging_mode) {
|
||||
case PAGING_MODE_RISCV_SV39:
|
||||
return 39;
|
||||
case PAGING_MODE_RISCV_SV48:
|
||||
return 48;
|
||||
case PAGING_MODE_RISCV_SV57:
|
||||
return 57;
|
||||
default:
|
||||
panic(false, "paging_mode_va_bits: invalid mode");
|
||||
}
|
||||
}
|
||||
|
||||
int vmm_max_paging_mode(void)
|
||||
{
|
||||
static int max_level;
|
||||
if (max_level > 0)
|
||||
goto done;
|
||||
|
||||
pt_entry_t *table = ext_mem_alloc(PT_SIZE);
|
||||
|
||||
// Test each paging mode starting with Sv57.
|
||||
// Since writes to `satp` with an invalid MODE have no effect, and pages can be mapped at
|
||||
// any level, we can identity map the entire lower half (very likely guaranteeing everything
|
||||
// this code needs will be mapped) and check if enabling the paging mode succeeds.
|
||||
int lvl = 4;
|
||||
for (; lvl >= 2; lvl--) {
|
||||
pt_entry_t entry = PT_FLAG_ACCESSED | PT_FLAG_DIRTY | PT_FLAG_RWX | PT_FLAG_VALID;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
table[i] = entry;
|
||||
entry += page_sizes[lvl] >> 2;
|
||||
}
|
||||
|
||||
uint64_t satp = ((uint64_t)(6 + lvl) << 60) | ((uint64_t)table >> 12);
|
||||
csr_write("satp", satp);
|
||||
if (csr_read("satp") == satp) {
|
||||
max_level = lvl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
csr_write("satp", 0);
|
||||
pmm_free(table, PT_SIZE);
|
||||
|
||||
if (max_level == 0)
|
||||
panic(false, "vmm: paging is not supported");
|
||||
done:
|
||||
return 6 + max_level;
|
||||
}
|
||||
|
||||
static pt_entry_t pbmt_nc = 0;
|
||||
|
||||
pagemap_t new_pagemap(int paging_mode) {
|
||||
pagemap_t pagemap;
|
||||
pagemap.paging_mode = paging_mode;
|
||||
pagemap.max_page_size = paging_mode - 6;
|
||||
pagemap.top_level = ext_mem_alloc(PT_SIZE);
|
||||
|
||||
if (riscv_check_isa_extension("svpbmt", NULL, NULL)) {
|
||||
printv("riscv: Svpbmt extension is supported.\n");
|
||||
pbmt_nc = PT_FLAG_PBMT_NC;
|
||||
}
|
||||
|
||||
return pagemap;
|
||||
}
|
||||
|
||||
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size) {
|
||||
// Truncate the requested page size to the maximum supported.
|
||||
if (page_size > pagemap.max_page_size)
|
||||
page_size = pagemap.max_page_size;
|
||||
|
||||
// Convert VMM_FLAG_* into PT_FLAG_*.
|
||||
// Set the ACCESSED and DIRTY flags to avoid faults.
|
||||
pt_entry_t ptflags = PT_FLAG_VALID | PT_FLAG_READ | PT_FLAG_ACCESSED | PT_FLAG_DIRTY;
|
||||
if (flags & VMM_FLAG_WRITE)
|
||||
ptflags |= PT_FLAG_WRITE;
|
||||
if (!(flags & VMM_FLAG_NOEXEC))
|
||||
ptflags |= PT_FLAG_EXEC;
|
||||
if (flags & VMM_FLAG_FB)
|
||||
ptflags |= pbmt_nc;
|
||||
|
||||
// Start at the highest level.
|
||||
// The values of `enum page_size` map to the level index at which that size is mapped.
|
||||
int level = pagemap.max_page_size;
|
||||
pt_entry_t *table = pagemap.top_level;
|
||||
for (;;) {
|
||||
int index = (virt_addr >> (12 + 9 * level)) & 0x1ff;
|
||||
|
||||
// Stop when we reach the level for the requested page size.
|
||||
if (level == (int)page_size) {
|
||||
table[index] = pte_new(phys_addr, ptflags);
|
||||
break;
|
||||
}
|
||||
|
||||
table = get_next_level(pagemap, table, virt_addr, page_size, level, index);
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -77,8 +77,45 @@ void vmm_assert_4k_pages(void);
|
||||
pagemap_t new_pagemap(int lv);
|
||||
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
|
||||
|
||||
#elif defined (__riscv64)
|
||||
|
||||
// We use fake flags here because these don't properly map onto the
|
||||
// RISC-V flags.
|
||||
#define VMM_FLAG_WRITE ((uint64_t)1 << 0)
|
||||
#define VMM_FLAG_NOEXEC ((uint64_t)1 << 1)
|
||||
#define VMM_FLAG_FB ((uint64_t)1 << 2)
|
||||
|
||||
#define VMM_MAX_LEVEL 5
|
||||
|
||||
#define PAGING_MODE_RISCV_SV39 8
|
||||
#define PAGING_MODE_RISCV_SV48 9
|
||||
#define PAGING_MODE_RISCV_SV57 10
|
||||
|
||||
int paging_mode_va_bits(int paging_mode);
|
||||
|
||||
enum page_size {
|
||||
Size4KiB,
|
||||
Size2MiB,
|
||||
Size1GiB,
|
||||
Size512GiB,
|
||||
Size256TiB
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum page_size max_page_size;
|
||||
int paging_mode;
|
||||
void *top_level;
|
||||
} pagemap_t;
|
||||
|
||||
uint64_t paging_mode_higher_half(int paging_mode);
|
||||
int vmm_max_paging_mode(void);
|
||||
pagemap_t new_pagemap(int paging_mode);
|
||||
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
int vmm_max_paging_mode(void);
|
||||
|
||||
#endif
|
||||
|
@ -180,7 +180,7 @@ extern symbol limine_spinup_32;
|
||||
| ((uint64_t)1 << 8) /* TTBR0 Inner WB RW-Allocate */ \
|
||||
| ((uint64_t)(tsz) << 0)) /* Address bits in TTBR0 */
|
||||
|
||||
#else
|
||||
#elif !defined (__riscv64)
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
@ -279,28 +279,6 @@ static void *_get_request(uint64_t id[4]) {
|
||||
#define FEAT_START do {
|
||||
#define FEAT_END } while (0);
|
||||
|
||||
#if defined (__i386__)
|
||||
extern symbol limine_term_write_entry;
|
||||
void *limine_rt_stack = NULL;
|
||||
uint64_t limine_term_callback_ptr = 0;
|
||||
uint64_t limine_term_write_ptr = 0;
|
||||
void limine_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
#endif
|
||||
|
||||
static uint64_t term_arg;
|
||||
static void (*actual_callback)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
|
||||
static void callback_shim(struct flanterm_context *ctx, uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
|
||||
(void)ctx;
|
||||
actual_callback(term_arg, a, b, c, d);
|
||||
}
|
||||
|
||||
// TODO pair with specific terminal
|
||||
static void term_write_shim(uint64_t context, uint64_t buf, uint64_t count) {
|
||||
(void)context;
|
||||
_term_write(terms[0], buf, count);
|
||||
}
|
||||
|
||||
noreturn void limine_load(char *config, char *cmdline) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
@ -428,20 +406,27 @@ noreturn void limine_load(char *config, char *cmdline) {
|
||||
paging_mode = max_paging_mode = PAGING_MODE_AARCH64_4LVL;
|
||||
// TODO(qookie): aarch64 also has optional 5 level paging when using 4K pages
|
||||
|
||||
#elif defined (__riscv64)
|
||||
max_paging_mode = vmm_max_paging_mode();
|
||||
paging_mode = max_paging_mode >= PAGING_MODE_RISCV_SV48 ? PAGING_MODE_RISCV_SV48 : PAGING_MODE_RISCV_SV39;
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
#if defined (__riscv64)
|
||||
#define paging_mode_limine_to_vmm(x) (PAGING_MODE_RISCV_SV39 + (x))
|
||||
#define paging_mode_vmm_to_limine(x) ((x) - PAGING_MODE_RISCV_SV39)
|
||||
#else
|
||||
#define paging_mode_limine_to_vmm(x) (x)
|
||||
#define paging_mode_vmm_to_limine(x) (x)
|
||||
#endif
|
||||
|
||||
bool have_paging_mode_request = false;
|
||||
bool paging_mode_set = false;
|
||||
FEAT_START
|
||||
struct limine_paging_mode_request *pm_request = get_request(LIMINE_PAGING_MODE_REQUEST);
|
||||
if (pm_request == NULL)
|
||||
break;
|
||||
have_paging_mode_request = true;
|
||||
|
||||
if (pm_request->mode > LIMINE_PAGING_MODE_MAX) {
|
||||
print("warning: ignoring invalid mode in paging mode request\n");
|
||||
@ -461,35 +446,6 @@ FEAT_START
|
||||
pm_response->mode = paging_mode_vmm_to_limine(paging_mode);
|
||||
pm_request->response = reported_addr(pm_response);
|
||||
|
||||
FEAT_END
|
||||
|
||||
// 5 level paging feature & HHDM slide
|
||||
FEAT_START
|
||||
struct limine_5_level_paging_request *lv5pg_request = get_request(LIMINE_5_LEVEL_PAGING_REQUEST);
|
||||
if (lv5pg_request == NULL)
|
||||
break;
|
||||
|
||||
if (have_paging_mode_request) {
|
||||
print("paging: ignoring 5-level paging request in favor of paging mode request\n");
|
||||
break;
|
||||
}
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
if (max_paging_mode < PAGING_MODE_X86_64_5LVL)
|
||||
break;
|
||||
paging_mode = PAGING_MODE_X86_64_5LVL;
|
||||
#elif defined (__aarch64__)
|
||||
if (max_paging_mode < PAGING_MODE_AARCH64_5LVL)
|
||||
break;
|
||||
paging_mode = PAGING_MODE_AARCH64_5LVL;
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
set_paging_mode(paging_mode, kaslr);
|
||||
paging_mode_set = true;
|
||||
|
||||
void *lv5pg_response = ext_mem_alloc(sizeof(struct limine_5_level_paging_response));
|
||||
lv5pg_request->response = reported_addr(lv5pg_response);
|
||||
FEAT_END
|
||||
|
||||
if (!paging_mode_set) {
|
||||
@ -812,92 +768,9 @@ FEAT_END
|
||||
parse_resolution(&req_width, &req_height, &req_bpp, resolution);
|
||||
}
|
||||
|
||||
uint64_t *term_fb_ptr = NULL;
|
||||
uint64_t term_fb_addr;
|
||||
|
||||
struct fb_info *fbs;
|
||||
size_t fbs_count;
|
||||
|
||||
// Terminal feature
|
||||
FEAT_START
|
||||
struct limine_terminal_request *terminal_request = get_request(LIMINE_TERMINAL_REQUEST);
|
||||
if (terminal_request == NULL) {
|
||||
break; // next feature
|
||||
}
|
||||
|
||||
struct limine_terminal_response *terminal_response =
|
||||
ext_mem_alloc(sizeof(struct limine_terminal_response));
|
||||
|
||||
terminal_response->revision = 1;
|
||||
|
||||
struct limine_terminal *terminal = ext_mem_alloc(sizeof(struct limine_terminal));
|
||||
|
||||
quiet = false;
|
||||
serial = false;
|
||||
|
||||
char *term_conf_override_s = config_get_value(config, 0, "TERM_CONFIG_OVERRIDE");
|
||||
if (term_conf_override_s != NULL && strcmp(term_conf_override_s, "yes") == 0) {
|
||||
if (!gterm_init(&fbs, &fbs_count, config, req_width, req_height)) {
|
||||
goto term_fail;
|
||||
}
|
||||
} else {
|
||||
if (!gterm_init(&fbs, &fbs_count, NULL, req_width, req_height)) {
|
||||
goto term_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (0) {
|
||||
term_fail:
|
||||
pmm_free(terminal, sizeof(struct limine_terminal));
|
||||
pmm_free(terminal_response, sizeof(struct limine_terminal_response));
|
||||
break; // next feature
|
||||
}
|
||||
|
||||
if (terminal_request->callback != 0) {
|
||||
terms[0]->callback = callback_shim;
|
||||
|
||||
#if defined (__i386__)
|
||||
actual_callback = (void *)limine_term_callback;
|
||||
limine_term_callback_ptr = terminal_request->callback;
|
||||
#elif defined (__x86_64__) || defined (__aarch64__)
|
||||
actual_callback = (void *)terminal_request->callback;
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
}
|
||||
|
||||
term_arg = reported_addr(terminal);
|
||||
|
||||
#if defined (__i386__)
|
||||
if (limine_rt_stack == NULL) {
|
||||
limine_rt_stack = ext_mem_alloc(16384) + 16384;
|
||||
}
|
||||
|
||||
limine_term_write_ptr = (uintptr_t)term_write_shim;
|
||||
terminal_response->write = (uintptr_t)(void *)limine_term_write_entry;
|
||||
#elif defined (__x86_64__) || defined (__aarch64__)
|
||||
terminal_response->write = (uintptr_t)term_write_shim;
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
term_fb_ptr = &terminal->framebuffer;
|
||||
term_fb_addr = reported_addr((void *)(((struct flanterm_fb_context *)terms[0])->framebuffer));
|
||||
|
||||
terminal->columns = terms[0]->cols;
|
||||
terminal->rows = terms[0]->rows;
|
||||
|
||||
uint64_t *term_list = ext_mem_alloc(1 * sizeof(uint64_t));
|
||||
term_list[0] = reported_addr(terminal);
|
||||
|
||||
terminal_response->terminal_count = 1;
|
||||
terminal_response->terminals = reported_addr(term_list);
|
||||
|
||||
terminal_request->response = reported_addr(terminal_response);
|
||||
|
||||
goto skip_fb_init;
|
||||
FEAT_END
|
||||
|
||||
term_notready();
|
||||
|
||||
fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
|
||||
@ -905,7 +778,6 @@ FEAT_END
|
||||
goto no_fb;
|
||||
}
|
||||
|
||||
skip_fb_init:
|
||||
for (size_t i = 0; i < fbs_count; i++) {
|
||||
memmap_alloc_range(fbs[i].framebuffer_addr,
|
||||
(uint64_t)fbs[i].framebuffer_pitch * fbs[i].framebuffer_height,
|
||||
@ -915,7 +787,7 @@ skip_fb_init:
|
||||
// Framebuffer feature
|
||||
FEAT_START
|
||||
struct limine_framebuffer_request *framebuffer_request = get_request(LIMINE_FRAMEBUFFER_REQUEST);
|
||||
if (framebuffer_request == NULL && term_fb_ptr == NULL) {
|
||||
if (framebuffer_request == NULL) {
|
||||
break; // next feature
|
||||
}
|
||||
|
||||
@ -964,14 +836,6 @@ FEAT_START
|
||||
if (framebuffer_request != NULL) {
|
||||
framebuffer_request->response = reported_addr(framebuffer_response);
|
||||
}
|
||||
if (term_fb_ptr != NULL) {
|
||||
for (size_t i = 0; i < fbs_count; i++) {
|
||||
if (fbp[i].address == term_fb_addr) {
|
||||
*term_fb_ptr = reported_addr(&fbp[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
FEAT_END
|
||||
|
||||
no_fb:
|
||||
@ -1094,6 +958,8 @@ FEAT_START
|
||||
|
||||
smp_info = init_smp(&cpu_count, &bsp_mpidr,
|
||||
pagemap, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa), LIMINE_SCTLR);
|
||||
#elif defined (__riscv64)
|
||||
smp_info = init_smp(&cpu_count, pagemap);
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
@ -1115,6 +981,8 @@ FEAT_START
|
||||
smp_response->bsp_lapic_id = bsp_lapic_id;
|
||||
#elif defined (__aarch64__)
|
||||
smp_response->bsp_mpidr = bsp_mpidr;
|
||||
#elif defined (__riscv64)
|
||||
smp_response->bsp_hartid = bsp_hartid;
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
@ -1197,9 +1065,6 @@ FEAT_START
|
||||
memmap_request->response = reported_addr(memmap_response);
|
||||
FEAT_END
|
||||
|
||||
// Clear terminal for kernels that will use the Limine terminal
|
||||
FOR_TERM(flanterm_write(TERM, "\e[2J\e[H", 7));
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
#if defined (BIOS)
|
||||
// If we're going 64, we might as well call this BIOS interrupt
|
||||
@ -1241,6 +1106,11 @@ FEAT_END
|
||||
enter_in_el1(entry_point, reported_stack, LIMINE_SCTLR, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa),
|
||||
(uint64_t)pagemap.top_level[0],
|
||||
(uint64_t)pagemap.top_level[1], 0);
|
||||
#elif defined (__riscv64)
|
||||
uint64_t reported_stack = reported_addr(stack);
|
||||
uint64_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
|
||||
|
||||
riscv_spinup(entry_point, reported_stack, satp);
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -1,120 +0,0 @@
|
||||
section .bss
|
||||
|
||||
user_stack:
|
||||
resq 1
|
||||
|
||||
user_cs: resq 1
|
||||
user_ds: resq 1
|
||||
user_es: resq 1
|
||||
user_ss: resq 1
|
||||
|
||||
section .text
|
||||
|
||||
extern term_write
|
||||
extern limine_rt_stack
|
||||
extern limine_term_callback_ptr
|
||||
extern limine_term_write_ptr
|
||||
|
||||
global limine_term_callback
|
||||
limine_term_callback:
|
||||
bits 32
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
; Go 64
|
||||
push 0x28
|
||||
push .mode64
|
||||
retfd
|
||||
bits 64
|
||||
.mode64:
|
||||
mov eax, 0x30
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
mov rdi, [rbp + 8]
|
||||
mov rsi, [rbp + 16]
|
||||
mov rdx, [rbp + 24]
|
||||
mov rcx, [rbp + 32]
|
||||
mov r8, [rbp + 40]
|
||||
|
||||
mov rbx, rsp
|
||||
mov rsp, [user_stack]
|
||||
call [limine_term_callback_ptr]
|
||||
mov rsp, rbx
|
||||
|
||||
; Go 32
|
||||
push 0x18
|
||||
push .mode32
|
||||
retfq
|
||||
bits 32
|
||||
.mode32:
|
||||
mov eax, 0x20
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
||||
global limine_term_write_entry
|
||||
limine_term_write_entry:
|
||||
bits 64
|
||||
push rbx
|
||||
push rbp
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov [user_stack], rsp
|
||||
mov esp, [limine_rt_stack]
|
||||
|
||||
mov word [user_cs], cs
|
||||
mov word [user_ds], ds
|
||||
mov word [user_es], es
|
||||
mov word [user_ss], ss
|
||||
|
||||
push rdx
|
||||
push rsi
|
||||
push rdi
|
||||
|
||||
push 0x18
|
||||
push .mode32
|
||||
retfq
|
||||
bits 32
|
||||
.mode32:
|
||||
mov eax, 0x20
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
call [limine_term_write_ptr]
|
||||
add esp, 24
|
||||
|
||||
push dword [user_cs]
|
||||
push .mode64
|
||||
retfd
|
||||
bits 64
|
||||
.mode64:
|
||||
mov ds, word [user_ds]
|
||||
mov es, word [user_es]
|
||||
mov ss, word [user_ss]
|
||||
mov rsp, [user_stack]
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbp
|
||||
pop rbx
|
||||
|
||||
ret
|
@ -1,140 +0,0 @@
|
||||
extern _GLOBAL_OFFSET_TABLE_
|
||||
|
||||
section .bss
|
||||
|
||||
user_stack:
|
||||
resq 1
|
||||
|
||||
user_cs: resq 1
|
||||
user_ds: resq 1
|
||||
user_es: resq 1
|
||||
user_ss: resq 1
|
||||
|
||||
section .text
|
||||
|
||||
extern term_write
|
||||
extern limine_rt_stack
|
||||
extern limine_term_callback_ptr
|
||||
extern limine_term_write_ptr
|
||||
|
||||
global limine_term_callback
|
||||
limine_term_callback:
|
||||
bits 32
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
; Go 64
|
||||
push 0x28
|
||||
call .p1
|
||||
.p1:
|
||||
add dword [esp], .mode64 - .p1
|
||||
retfd
|
||||
bits 64
|
||||
.mode64:
|
||||
mov eax, 0x30
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
mov rdi, [rbp + 8]
|
||||
mov rsi, [rbp + 16]
|
||||
mov rdx, [rbp + 24]
|
||||
mov rcx, [rbp + 32]
|
||||
mov r8, [rbp + 40]
|
||||
|
||||
call .get_got
|
||||
.get_got:
|
||||
pop rax
|
||||
add rax, _GLOBAL_OFFSET_TABLE_ + $$ - .get_got wrt ..gotpc
|
||||
|
||||
mov rbx, rsp
|
||||
mov rsp, [rax + user_stack wrt ..gotoff]
|
||||
call [rax + limine_term_callback_ptr wrt ..gotoff]
|
||||
mov rsp, rbx
|
||||
|
||||
; Go 32
|
||||
push 0x18
|
||||
call .p2
|
||||
.p2:
|
||||
add qword [rsp], .mode32 - .p2
|
||||
retfq
|
||||
bits 32
|
||||
.mode32:
|
||||
mov eax, 0x20
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
||||
bits 64
|
||||
global limine_term_write_entry
|
||||
limine_term_write_entry:
|
||||
push rbx
|
||||
push rbp
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
call .get_got
|
||||
.get_got:
|
||||
pop rbx
|
||||
add ebx, _GLOBAL_OFFSET_TABLE_ + $$ - .get_got wrt ..gotpc
|
||||
|
||||
mov [rbx + user_stack wrt ..gotoff], rsp
|
||||
mov esp, [rbx + limine_rt_stack wrt ..gotoff]
|
||||
|
||||
mov word [rbx + user_cs wrt ..gotoff], cs
|
||||
mov word [rbx + user_ds wrt ..gotoff], ds
|
||||
mov word [rbx + user_es wrt ..gotoff], es
|
||||
mov word [rbx + user_ss wrt ..gotoff], ss
|
||||
|
||||
push rdx
|
||||
push rsi
|
||||
push rdi
|
||||
|
||||
push 0x18
|
||||
call .p1
|
||||
.p1:
|
||||
add qword [rsp], .mode32 - .p1
|
||||
retfq
|
||||
bits 32
|
||||
.mode32:
|
||||
mov eax, 0x20
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
|
||||
call [ebx + limine_term_write_ptr wrt ..gotoff]
|
||||
add esp, 24
|
||||
|
||||
push dword [ebx + user_cs wrt ..gotoff]
|
||||
call .p2
|
||||
.p2:
|
||||
add dword [esp], .mode64 - .p2
|
||||
retfd
|
||||
bits 64
|
||||
.mode64:
|
||||
mov ds, word [rbx + user_ds wrt ..gotoff]
|
||||
mov es, word [rbx + user_es wrt ..gotoff]
|
||||
mov ss, word [rbx + user_ss wrt ..gotoff]
|
||||
mov rsp, [rbx + user_stack wrt ..gotoff]
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbp
|
||||
pop rbx
|
||||
|
||||
ret
|
@ -287,6 +287,63 @@ inline int current_el(void) {
|
||||
return v;
|
||||
}
|
||||
|
||||
#elif defined (__riscv64)
|
||||
|
||||
inline uint64_t rdtsc(void) {
|
||||
uint64_t v;
|
||||
asm ("rdtime %0" : "=r"(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
#define csr_read(csr) ({\
|
||||
size_t v;\
|
||||
asm volatile ("csrr %0, " csr : "=r"(v));\
|
||||
v;\
|
||||
})
|
||||
|
||||
#define csr_write(csr, v) ({\
|
||||
size_t old;\
|
||||
asm volatile ("csrrw %0, " csr ", %1" : "=r"(old) : "r"(v));\
|
||||
old;\
|
||||
})
|
||||
|
||||
#define make_satp(mode, ppn) (((size_t)(mode) << 60) | ((size_t)(ppn) >> 12))
|
||||
|
||||
#define locked_read(var) ({ \
|
||||
typeof(*var) locked_read__ret; \
|
||||
asm volatile ( \
|
||||
"ld %0, (%1); fence r, rw" \
|
||||
: "=r"(locked_read__ret) \
|
||||
: "r"(var) \
|
||||
: "memory" \
|
||||
); \
|
||||
locked_read__ret; \
|
||||
})
|
||||
|
||||
extern size_t bsp_hartid;
|
||||
|
||||
struct riscv_hart {
|
||||
struct riscv_hart *next;
|
||||
const char *isa_string;
|
||||
size_t hartid;
|
||||
uint32_t acpi_uid;
|
||||
uint8_t mmu_type;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
#define RISCV_HART_COPROC ((uint8_t)1 << 0) // is a coprocessor
|
||||
#define RISCV_HART_HAS_MMU ((uint8_t)1 << 1) // `mmu_type` field is valid
|
||||
|
||||
extern struct riscv_hart *hart_list;
|
||||
|
||||
bool riscv_check_isa_extension_for(size_t hartid, const char *ext, size_t *maj, size_t *min);
|
||||
|
||||
static inline bool riscv_check_isa_extension(const char *ext, size_t *maj, size_t *min) {
|
||||
return riscv_check_isa_extension_for(bsp_hartid, ext, maj, min);
|
||||
}
|
||||
|
||||
void init_riscv(void);
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
261
common/sys/cpu_riscv.c
Normal file
261
common/sys/cpu_riscv.c
Normal file
@ -0,0 +1,261 @@
|
||||
|
||||
#if defined(__riscv)
|
||||
|
||||
#include <lib/acpi.h>
|
||||
#include <lib/misc.h>
|
||||
#include <lib/print.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// ACPI RISC-V Hart Capabilities Table
|
||||
struct rhct {
|
||||
struct sdt header;
|
||||
uint32_t flags;
|
||||
uint64_t time_base_frequency;
|
||||
uint32_t nodes_len;
|
||||
uint32_t nodes_offset;
|
||||
uint8_t nodes[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define RHCT_ISA_STRING 0
|
||||
#define RHCT_CMO 1
|
||||
#define RHCT_MMU 2
|
||||
#define RHCT_HART_INFO 65535
|
||||
|
||||
struct rhct_header {
|
||||
uint16_t type; // node type
|
||||
uint16_t size; // node size (bytes)
|
||||
uint16_t revision; // node revision
|
||||
} __attribute__((packed));
|
||||
|
||||
// One `struct rhct_hart_info` structure exists per hart in the system.
|
||||
// The `offsets` array points to other entries in the RHCT associated with the
|
||||
// hart.
|
||||
struct rhct_hart_info {
|
||||
struct rhct_header header;
|
||||
uint16_t offsets_len;
|
||||
uint32_t acpi_processor_uid;
|
||||
uint32_t offsets[];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct rhct_isa_string {
|
||||
struct rhct_header header;
|
||||
uint16_t isa_string_len;
|
||||
const char isa_string[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define RISCV_MMU_TYPE_SV39 0
|
||||
#define RISCV_MMU_TYPE_SV48 1
|
||||
#define RISCV_MMU_TYPE_SV57 2
|
||||
|
||||
struct rhct_mmu {
|
||||
struct rhct_header header;
|
||||
uint8_t reserved0;
|
||||
uint8_t mmu_type;
|
||||
} __attribute__((packed));
|
||||
|
||||
size_t bsp_hartid;
|
||||
struct riscv_hart *hart_list;
|
||||
static struct riscv_hart *bsp_hart;
|
||||
|
||||
static struct riscv_hart *riscv_get_hart(size_t hartid) {
|
||||
for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
|
||||
if (hart->hartid == hartid) {
|
||||
return hart;
|
||||
}
|
||||
}
|
||||
panic(false, "no `struct riscv_hart` for hartid %u", hartid);
|
||||
}
|
||||
|
||||
static inline struct rhct_hart_info *rhct_get_hart_info(struct rhct *rhct, uint32_t acpi_uid) {
|
||||
uint32_t offset = rhct->nodes_offset;
|
||||
for (uint32_t i = 0; i < rhct->nodes_len; i++) {
|
||||
struct rhct_hart_info *node = (void *)((uintptr_t)rhct + offset);
|
||||
if (node->header.type == RHCT_HART_INFO && node->acpi_processor_uid == acpi_uid) {
|
||||
return node;
|
||||
}
|
||||
offset += node->header.size;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void init_riscv(void) {
|
||||
struct madt *madt = acpi_get_table("APIC", 0);
|
||||
struct rhct *rhct = acpi_get_table("RHCT", 0);
|
||||
if (madt == NULL || rhct == NULL) {
|
||||
panic(false, "riscv: requires acpi");
|
||||
}
|
||||
|
||||
for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin;
|
||||
(uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length; madt_ptr += *(madt_ptr + 1)) {
|
||||
if (*madt_ptr != 0x18) {
|
||||
continue;
|
||||
}
|
||||
struct madt_riscv_intc *intc = (struct madt_riscv_intc *)madt_ptr;
|
||||
|
||||
// Ignore harts we can't do anything with.
|
||||
if (!(intc->flags & MADT_RISCV_INTC_ENABLED ||
|
||||
intc->flags & MADT_RISCV_INTC_ONLINE_CAPABLE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t acpi_uid = intc->acpi_processor_uid;
|
||||
size_t hartid = intc->hartid;
|
||||
|
||||
struct rhct_hart_info *hart_info = rhct_get_hart_info(rhct, acpi_uid);
|
||||
if (hart_info == NULL) {
|
||||
panic(false, "riscv: missing rhct node for hartid %u", hartid);
|
||||
}
|
||||
|
||||
const char *isa_string = NULL;
|
||||
uint8_t mmu_type = 0;
|
||||
uint8_t flags = 0;
|
||||
|
||||
for (uint32_t i = 0; i < hart_info->offsets_len; i++) {
|
||||
const struct rhct_header *node = (void *)((uintptr_t)rhct + hart_info->offsets[i]);
|
||||
switch (node->type) {
|
||||
case RHCT_ISA_STRING:
|
||||
isa_string = ((struct rhct_isa_string *)node)->isa_string;
|
||||
break;
|
||||
case RHCT_MMU:
|
||||
mmu_type = ((struct rhct_mmu *)node)->mmu_type;
|
||||
flags |= RISCV_HART_HAS_MMU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isa_string == NULL) {
|
||||
print("riscv: missing isa string for hartid %u, skipping.\n", hartid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp("rv64", isa_string, 4) && strncmp("rv32", isa_string, 4)) {
|
||||
print("riscv: skipping hartid %u with invalid isa string: %s", hartid, isa_string);
|
||||
}
|
||||
|
||||
struct riscv_hart *hart = ext_mem_alloc(sizeof(struct riscv_hart));
|
||||
if (hart == NULL) {
|
||||
panic(false, "out of memory");
|
||||
}
|
||||
|
||||
hart->hartid = hartid;
|
||||
hart->acpi_uid = acpi_uid;
|
||||
hart->isa_string = isa_string;
|
||||
hart->mmu_type = mmu_type;
|
||||
hart->flags = flags;
|
||||
|
||||
hart->next = hart_list;
|
||||
hart_list = hart;
|
||||
|
||||
if (hart->hartid == bsp_hartid) {
|
||||
bsp_hart = hart;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsp_hart == NULL) {
|
||||
panic(false, "riscv: missing `struct riscv_hart` for BSP");
|
||||
}
|
||||
|
||||
if (strncasecmp(bsp_hart->isa_string, "rv64i", 5)) {
|
||||
panic(false, "unsupported cpu: %s", bsp_hart->isa_string);
|
||||
}
|
||||
|
||||
for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
|
||||
if (hart != bsp_hart && strcmp(bsp_hart->isa_string, hart->isa_string)) {
|
||||
hart->flags |= RISCV_HART_COPROC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct isa_extension {
|
||||
const char *name;
|
||||
size_t name_len;
|
||||
uint32_t ver_maj;
|
||||
uint32_t ver_min;
|
||||
};
|
||||
|
||||
// Parse the next sequence of digit characters into an integer.
|
||||
static bool parse_number(const char **s, size_t *_n) {
|
||||
size_t n = 0;
|
||||
bool parsed = false;
|
||||
while (isdigit(**s)) {
|
||||
n *= 10;
|
||||
n += *(*s)++ - '0';
|
||||
parsed = true;
|
||||
}
|
||||
*_n = n;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
// Parse the next extension from an ISA string.
|
||||
static bool parse_extension(const char **s, struct isa_extension *ext) {
|
||||
if (**s == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *name = *s;
|
||||
size_t name_len = 1;
|
||||
if (**s == 's' || **s == 'S' || **s == 'x' || **s == 'X' || **s == 'z' || **s == 'Z') {
|
||||
while (isalpha((*s)[name_len])) {
|
||||
name_len++;
|
||||
}
|
||||
}
|
||||
*s += name_len;
|
||||
|
||||
size_t maj = 0, min = 0;
|
||||
if (parse_number(s, &maj)) {
|
||||
if (**s == 'p') {
|
||||
*s += 1;
|
||||
parse_number(s, &min);
|
||||
}
|
||||
}
|
||||
|
||||
while (**s == '_') {
|
||||
*s += 1;
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
ext->name = name;
|
||||
ext->name_len = name_len;
|
||||
ext->ver_maj = maj;
|
||||
ext->ver_min = min;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool extension_matches(const struct isa_extension *ext, const char *name) {
|
||||
for (size_t i = 0; i < ext->name_len; i++) {
|
||||
const char c1 = tolower(ext->name[i]);
|
||||
const char c2 = tolower(*name++);
|
||||
if (c2 == '\0' || c1 != c2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Make sure `name` is not longer.
|
||||
return *name == '\0';
|
||||
}
|
||||
|
||||
bool riscv_check_isa_extension_for(size_t hartid, const char *name, size_t *maj, size_t *min) {
|
||||
// Skip the `rv{32,64}` prefix so it's not parsed as extensions.
|
||||
const char *isa_string = riscv_get_hart(hartid)->isa_string + 4;
|
||||
|
||||
struct isa_extension ext;
|
||||
while (parse_extension(&isa_string, &ext)) {
|
||||
if (!extension_matches(&ext, name)) {
|
||||
continue;
|
||||
}
|
||||
if (maj) {
|
||||
*maj = ext.ver_maj;
|
||||
}
|
||||
if (min) {
|
||||
*min = ext.ver_min;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
19
common/sys/sbi.asm_riscv64
Normal file
19
common/sys/sbi.asm_riscv64
Normal file
@ -0,0 +1,19 @@
|
||||
.section .text
|
||||
|
||||
.global sbicall
|
||||
sbicall:
|
||||
.option norelax
|
||||
mv t0, a0
|
||||
mv t1, a1
|
||||
mv a0, a2
|
||||
mv a1, a3
|
||||
mv a2, a4
|
||||
mv a3, a5
|
||||
mv a4, a6
|
||||
mv a5, a7
|
||||
mv a7, t0
|
||||
mv a6, t1
|
||||
ecall
|
||||
ret
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
32
common/sys/sbi.h
Normal file
32
common/sys/sbi.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __SYS__SBI_H__
|
||||
#define __SYS__SBI_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct sbiret {
|
||||
long error;
|
||||
long value;
|
||||
};
|
||||
|
||||
#define SBI_SUCCESS ((long)0)
|
||||
#define SBI_ERR_FAILED ((long)-1)
|
||||
#define SBI_ERR_NOT_SUPPORTED ((long)-2)
|
||||
#define SBI_ERR_INVALID_PARAM ((long)-3)
|
||||
#define SBI_ERR_DENIED ((long)-4)
|
||||
#define SBI_ERR_INVALID_ADDRESS ((long)-5)
|
||||
#define SBI_ERR_ALREADY_AVAILABLE ((long)-6)
|
||||
#define SBI_ERR_ALREADY_STARTED ((long)-7)
|
||||
#define SBI_ERR_ALREADY_STOPPED ((long)-8)
|
||||
|
||||
extern struct sbiret sbicall(int eid, int fid, ...);
|
||||
|
||||
#define SBI_EID_HSM 0x48534d
|
||||
|
||||
static inline struct sbiret sbi_hart_start(unsigned long hartid,
|
||||
unsigned long start_addr,
|
||||
unsigned long opaque) {
|
||||
return sbicall(SBI_EID_HSM, 0, hartid, start_addr, opaque);
|
||||
}
|
||||
|
||||
#endif
|
@ -13,6 +13,9 @@
|
||||
#include <mm/pmm.h>
|
||||
#define LIMINE_NO_POINTERS
|
||||
#include <limine.h>
|
||||
#if defined (__riscv64)
|
||||
#include <sys/sbi.h>
|
||||
#endif
|
||||
|
||||
extern symbol smp_trampoline_start;
|
||||
extern size_t smp_trampoline_size;
|
||||
@ -507,6 +510,80 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#elif defined (__riscv64)
|
||||
|
||||
struct trampoline_passed_info {
|
||||
uint64_t smp_tpl_booted_flag;
|
||||
uint64_t smp_tpl_satp;
|
||||
uint64_t smp_tpl_info_struct;
|
||||
};
|
||||
|
||||
static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *info_struct) {
|
||||
static struct trampoline_passed_info passed_info;
|
||||
|
||||
passed_info.smp_tpl_booted_flag = 0;
|
||||
passed_info.smp_tpl_satp = satp;
|
||||
passed_info.smp_tpl_info_struct = (uint64_t)info_struct;
|
||||
|
||||
asm volatile ("" ::: "memory");
|
||||
|
||||
struct sbiret ret = sbi_hart_start(hartid, (size_t)smp_trampoline_start, (size_t)&passed_info);
|
||||
if (ret.error != SBI_SUCCESS)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
if (locked_read(&passed_info.smp_tpl_booted_flag) == 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct limine_smp_info *init_smp(size_t *cpu_count, pagemap_t pagemap) {
|
||||
size_t num_cpus = 0;
|
||||
for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
|
||||
if (!(hart->flags & RISCV_HART_COPROC)) {
|
||||
num_cpus += 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct limine_smp_info *ret = ext_mem_alloc(num_cpus * sizeof(struct limine_smp_info));
|
||||
if (ret == NULL) {
|
||||
panic(false, "out of memory");
|
||||
}
|
||||
|
||||
*cpu_count = 0;
|
||||
for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
|
||||
if (hart->flags & RISCV_HART_COPROC) {
|
||||
continue;
|
||||
}
|
||||
struct limine_smp_info *info_struct = &ret[*cpu_count];
|
||||
|
||||
info_struct->hartid = hart->hartid;
|
||||
info_struct->processor_id = hart->acpi_uid;
|
||||
|
||||
// Don't try to start the BSP.
|
||||
if (hart->hartid == bsp_hartid) {
|
||||
*cpu_count += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", hart->hartid);
|
||||
|
||||
// Try to start the AP.
|
||||
size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
|
||||
if (!smp_start_ap(hart->hartid, satp, info_struct)) {
|
||||
print("smp: FAILED to bring-up AP\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
(*cpu_count)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
@ -27,6 +27,12 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
|
||||
uint64_t mair,
|
||||
uint64_t tcr,
|
||||
uint64_t sctlr);
|
||||
|
||||
#elif defined (__riscv64)
|
||||
|
||||
struct limine_smp_info *init_smp(size_t *cpu_count,
|
||||
pagemap_t pagemap);
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
67
common/sys/smp_trampoline.asm_riscv64
Normal file
67
common/sys/smp_trampoline.asm_riscv64
Normal file
@ -0,0 +1,67 @@
|
||||
.section .text
|
||||
|
||||
.global smp_trampoline_start
|
||||
smp_trampoline_start:
|
||||
.option norelax
|
||||
// The AP begins executing here with the following state:
|
||||
// satp = 0
|
||||
// sstatus.SIE = 0
|
||||
// a0 = hartid
|
||||
// a1 = struct trampoline_passed_info *
|
||||
//
|
||||
// All other registers are undefined.
|
||||
|
||||
ld a0, 16(a1)
|
||||
ld t0, 8(a1)
|
||||
csrw satp, t0
|
||||
|
||||
// Tell the BSP we've started.
|
||||
li t0, 1
|
||||
fence rw, w
|
||||
sd t0, (a1)
|
||||
|
||||
// Zero all the things.
|
||||
// Preserve a0
|
||||
mv a1, zero
|
||||
mv a2, zero
|
||||
mv a3, zero
|
||||
mv a4, zero
|
||||
mv a5, zero
|
||||
mv a6, zero
|
||||
mv a7, zero
|
||||
mv s0, zero
|
||||
mv s1, zero
|
||||
mv s2, zero
|
||||
mv s3, zero
|
||||
mv s4, zero
|
||||
mv s5, zero
|
||||
mv s6, zero
|
||||
mv s7, zero
|
||||
mv s8, zero
|
||||
mv s9, zero
|
||||
mv s10, zero
|
||||
mv s11, zero
|
||||
mv t1, zero
|
||||
mv t2, zero
|
||||
mv t3, zero
|
||||
mv t4, zero
|
||||
mv t5, zero
|
||||
mv t6, zero
|
||||
mv tp, zero
|
||||
mv ra, zero
|
||||
|
||||
csrw sie, zero
|
||||
csrw stvec, zero
|
||||
|
||||
// Wait for kernel to tell us where to go.
|
||||
0: .4byte 0x0100000f // pause
|
||||
ld t0, 24(a0)
|
||||
fence r, rw
|
||||
beqz t0, 0b
|
||||
|
||||
// Load sp from reserved field of info struct
|
||||
ld sp, 16(a0)
|
||||
|
||||
jr t0
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
69
configure.ac
69
configure.ac
@ -120,21 +120,21 @@ AC_ARG_ENABLE([all],
|
||||
[AS_HELP_STRING([--enable-all], [enable ALL ports and targets])],
|
||||
[BUILD_ALL="$enableval"])
|
||||
|
||||
BUILD_CD="$BUILD_ALL"
|
||||
BUILD_BIOS_CD="$BUILD_ALL"
|
||||
|
||||
AC_ARG_ENABLE([bios-cd],
|
||||
[AS_HELP_STRING([--enable-bios-cd], [enable building the x86 BIOS CD image])],
|
||||
[BUILD_CD="$enableval"])
|
||||
[BUILD_BIOS_CD="$enableval"])
|
||||
|
||||
AC_SUBST([BUILD_CD])
|
||||
AC_SUBST([BUILD_BIOS_CD])
|
||||
|
||||
BUILD_PXE="$BUILD_ALL"
|
||||
BUILD_BIOS_PXE="$BUILD_ALL"
|
||||
|
||||
AC_ARG_ENABLE([bios-pxe],
|
||||
[AS_HELP_STRING([--enable-bios-pxe], [enable building the x86 BIOS PXE image])],
|
||||
[BUILD_PXE="$enableval"])
|
||||
[BUILD_BIOS_PXE="$enableval"])
|
||||
|
||||
AC_SUBST([BUILD_PXE])
|
||||
AC_SUBST([BUILD_BIOS_PXE])
|
||||
|
||||
BUILD_BIOS="$BUILD_ALL"
|
||||
|
||||
@ -142,13 +142,11 @@ AC_ARG_ENABLE([bios],
|
||||
[AS_HELP_STRING([--enable-bios], [enable building the x86 BIOS port])],
|
||||
[BUILD_BIOS="$enableval"])
|
||||
|
||||
BUILD_LIMINE_DEPLOY="$BUILD_BIOS"
|
||||
|
||||
if test "x$BUILD_BIOS" = "xno"; then
|
||||
if test "x$BUILD_CD" = "xyes"; then
|
||||
if test "x$BUILD_BIOS_CD" = "xyes"; then
|
||||
BUILD_BIOS="yes"
|
||||
fi
|
||||
if test "x$BUILD_PXE" = "xyes"; then
|
||||
if test "x$BUILD_BIOS_PXE" = "xyes"; then
|
||||
BUILD_BIOS="yes"
|
||||
fi
|
||||
fi
|
||||
@ -178,7 +176,6 @@ else
|
||||
fi
|
||||
|
||||
AC_SUBST([BUILD_BIOS])
|
||||
AC_SUBST([BUILD_LIMINE_DEPLOY])
|
||||
|
||||
BUILD_UEFI_IA32="$BUILD_ALL"
|
||||
|
||||
@ -266,24 +263,52 @@ fi
|
||||
|
||||
AC_SUBST([BUILD_UEFI_AARCH64])
|
||||
|
||||
BUILD_CD_EFI="$BUILD_ALL"
|
||||
BUILD_UEFI_RISCV64="$BUILD_ALL"
|
||||
|
||||
AC_ARG_ENABLE([uefi-riscv64],
|
||||
[AS_HELP_STRING([--enable-uefi-riscv64], [enable building the riscv64 UEFI port])],
|
||||
[BUILD_UEFI_RISCV64="$enableval"])
|
||||
|
||||
if test "x$BUILD_UEFI_RISCV64" = "xno"; then
|
||||
BUILD_UEFI_RISCV64=""
|
||||
else
|
||||
mkdir -p toolchain-files
|
||||
CC="$CC" \
|
||||
ARCHITECTURE=riscv64 \
|
||||
FREESTANDING_TOOLCHAIN_SUFFIX="_FOR_TARGET" \
|
||||
FREESTANDING_TOOLCHAIN="$TOOLCHAIN_FOR_TARGET" \
|
||||
WANT_FREESTANDING_CC=yes \
|
||||
FREESTANDING_CC="$CC_FOR_TARGET" \
|
||||
WANT_FREESTANDING_LD=yes \
|
||||
FREESTANDING_LD="$LD_FOR_TARGET" \
|
||||
WANT_FREESTANDING_OBJCOPY=yes \
|
||||
FREESTANDING_OBJCOPY="$OBJCOPY_FOR_TARGET" \
|
||||
WANT_FREESTANDING_OBJDUMP=yes \
|
||||
FREESTANDING_OBJDUMP="$OBJDUMP_FOR_TARGET" \
|
||||
"$SRCDIR/freestanding-toolchain" >"toolchain-files/uefi-riscv64-toolchain.mk" || exit 1
|
||||
BUILD_UEFI_RISCV64="limine-uefi-riscv64"
|
||||
fi
|
||||
|
||||
AC_SUBST([BUILD_UEFI_RISCV64])
|
||||
|
||||
BUILD_UEFI_CD="$BUILD_ALL"
|
||||
|
||||
AC_ARG_ENABLE([uefi-cd],
|
||||
[AS_HELP_STRING([--enable-uefi-cd], [enable building limine-cd-efi.bin])],
|
||||
[BUILD_CD_EFI="$enableval"])
|
||||
[AS_HELP_STRING([--enable-uefi-cd], [enable building limine-uefi-cd.bin])],
|
||||
[BUILD_UEFI_CD="$enableval"])
|
||||
|
||||
if ! test "x$BUILD_CD_EFI" = "xno"; then
|
||||
if ! test "x$BUILD_UEFI_CD" = "xno"; then
|
||||
AC_CHECK_PROG([MTOOLS_FOUND], [mcopy], [yes])
|
||||
if ! test "x$MTOOLS_FOUND" = "xyes"; then
|
||||
if test "x$BUILD_CD_EFI" = "xyes"; then
|
||||
AC_MSG_ERROR([mtools not found, install mtools to build limine-cd-efi.bin])
|
||||
if test "x$BUILD_UEFI_CD" = "xyes"; then
|
||||
AC_MSG_ERROR([mtools not found, install mtools to build limine-uefi-cd.bin])
|
||||
fi
|
||||
AC_MSG_WARN([mtools not found, install mtools to build limine-cd-efi.bin])
|
||||
BUILD_CD_EFI="no"
|
||||
AC_MSG_WARN([mtools not found, install mtools to build limine-uefi-cd.bin])
|
||||
BUILD_UEFI_CD="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([BUILD_CD_EFI])
|
||||
AC_SUBST([BUILD_UEFI_CD])
|
||||
|
||||
if test "x$NEED_NASM" = "xyes"; then
|
||||
AC_CHECK_PROG([NASM_FOUND], [nasm], [yes])
|
||||
@ -311,7 +336,7 @@ m4_define([DEFAULT_LDFLAGS_FOR_TARGET], [])
|
||||
AC_ARG_VAR([LDFLAGS_FOR_TARGET], [linker flags for Limine @<:@default: ]DEFAULT_LDFLAGS_FOR_TARGET[@:>@])
|
||||
test "x$LDFLAGS_FOR_TARGET" = "x" && LDFLAGS_FOR_TARGET="DEFAULT_LDFLAGS_FOR_TARGET"
|
||||
|
||||
LIMINE_COPYRIGHT=$($GREP Copyright "$SRCDIR/LICENSE")
|
||||
LIMINE_COPYRIGHT=$($GREP Copyright "$SRCDIR/COPYING")
|
||||
AC_SUBST([LIMINE_COPYRIGHT])
|
||||
|
||||
AC_PREFIX_DEFAULT([/usr/local])
|
||||
@ -320,5 +345,5 @@ if ! test -f limine.h; then
|
||||
cp "$SRCDIR/limine.h" ./
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([man/man1/limine-version.1 man/man1/limine-deploy.1 man/man1/limine-enroll-config.1 GNUmakefile config.h])
|
||||
AC_CONFIG_FILES([man/man1/limine.1 GNUmakefile config.h])
|
||||
AC_OUTPUT
|
||||
|
8
host/.gitignore
vendored
8
host/.gitignore
vendored
@ -1,6 +1,2 @@
|
||||
limine-deploy
|
||||
limine-deploy.exe
|
||||
limine-version
|
||||
limine-version.exe
|
||||
limine-enroll-config
|
||||
limine-enroll-config.exe
|
||||
limine
|
||||
limine.exe
|
||||
|
@ -7,43 +7,32 @@ PREFIX ?= /usr/local
|
||||
CFLAGS ?= -g -O2 -pipe
|
||||
|
||||
.PHONY: all
|
||||
all: limine-deploy limine-version limine-enroll-config
|
||||
all: limine
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share'
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine'
|
||||
$(INSTALL) -m 644 limine.sys '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-cd-efi.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-pxe.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-bios.sys '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-bios-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-uefi-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 limine-bios-pxe.bin '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 BOOTX64.EFI '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 BOOTIA32.EFI '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 BOOTAA64.EFI '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -m 644 BOOTRISCV64.EFI '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/include'
|
||||
$(INSTALL) -m 644 limine.h '$(DESTDIR)$(PREFIX)/include/'
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
|
||||
$(INSTALL) limine-deploy '$(DESTDIR)$(PREFIX)/bin/'
|
||||
$(INSTALL) limine-version '$(DESTDIR)$(PREFIX)/bin/'
|
||||
$(INSTALL) limine-enroll-config '$(DESTDIR)$(PREFIX)/bin/'
|
||||
$(INSTALL) limine '$(DESTDIR)$(PREFIX)/bin/'
|
||||
|
||||
.PHONY: install-strip
|
||||
install-strip: install
|
||||
$(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine-deploy'
|
||||
$(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine-version'
|
||||
$(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine-enroll-config'
|
||||
$(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine'
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f limine-deploy limine-deploy.exe
|
||||
rm -f limine-version limine-version.exe
|
||||
rm -f limine-enroll-config limine-enroll-config.exe
|
||||
rm -f limine limine.exe
|
||||
|
||||
limine-deploy: limine-deploy.c limine-hdd.h
|
||||
$(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine-deploy.c $(LIBS) -o $@
|
||||
|
||||
limine-version: limine-version.c
|
||||
$(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine-version.c $(LIBS) -o $@
|
||||
|
||||
limine-enroll-config: limine-enroll-config.c
|
||||
$(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine-enroll-config.c $(LIBS) -o $@
|
||||
limine: limine.c
|
||||
$(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine.c $(LIBS) -o $@
|
||||
|
@ -9,7 +9,7 @@ cat <<EOF
|
||||
const uint8_t binary_limine_hdd_bin_data[] = {
|
||||
EOF
|
||||
|
||||
od -v -An -t x1 <limine-hdd.bin | "$SED" '/^$/d;s/ */ /g;s/ *$//g;s/ /, 0x/g;s/^, / /g;s/$/,/g;s/^ , / /g'
|
||||
od -v -An -t x1 <limine-bios-hdd.bin | "$SED" '/^$/d;s/ */ /g;s/ *$//g;s/ /, 0x/g;s/^, / /g;s/$/,/g;s/^ , / /g'
|
||||
|
||||
cat <<EOF
|
||||
};
|
||||
|
@ -1,143 +0,0 @@
|
||||
#undef IS_WINDOWS
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
|
||||
#define IS_WINDOWS 1
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++"
|
||||
|
||||
static void usage(const char *name) {
|
||||
printf("Usage: %s <Limine executable> <BLAKE2B of config file>\n", name);
|
||||
printf("\n");
|
||||
printf(" --reset Remove enrolled BLAKE2B, will not check config integrity\n");
|
||||
printf("\n");
|
||||
printf(" --quiet Do not print verbose diagnostic messages\n");
|
||||
printf("\n");
|
||||
printf(" --help | -h Display this help message\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void remove_arg(int *argc, char *argv[], int index) {
|
||||
for (int i = index; i < *argc - 1; i++) {
|
||||
argv[i] = argv[i + 1];
|
||||
}
|
||||
|
||||
(*argc)--;
|
||||
|
||||
argv[*argc] = NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
char *bootloader = NULL;
|
||||
FILE *bootloader_file = NULL;
|
||||
bool quiet = false;
|
||||
bool reset = false;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[i], "--quiet") == 0) {
|
||||
remove_arg(&argc, argv, i);
|
||||
quiet = true;
|
||||
} else if (strcmp(argv[i], "--reset") == 0) {
|
||||
remove_arg(&argc, argv, i);
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= (reset ? 1 : 2)) {
|
||||
usage(argv[0]);
|
||||
#ifdef IS_WINDOWS
|
||||
system("pause");
|
||||
#endif
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!reset && strlen(argv[2]) != 128) {
|
||||
fprintf(stderr, "ERROR: BLAKE2B specified is not 128 characters long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
bootloader_file = fopen(argv[1], "r+b");
|
||||
if (bootloader_file == NULL) {
|
||||
perror("ERROR");
|
||||
goto cleanup;;
|
||||
}
|
||||
|
||||
if (fseek(bootloader_file, 0, SEEK_END) != 0) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
size_t bootloader_size = ftell(bootloader_file);
|
||||
rewind(bootloader_file);
|
||||
|
||||
bootloader = malloc(bootloader_size);
|
||||
if (bootloader == NULL) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char *checksum_loc = NULL;
|
||||
size_t checked_count = 0;
|
||||
const char *config_b2sum_sign = CONFIG_B2SUM_SIGNATURE;
|
||||
for (size_t i = 0; i < bootloader_size - ((sizeof(CONFIG_B2SUM_SIGNATURE) - 1) + 128) + 1; i++) {
|
||||
if (bootloader[i] != config_b2sum_sign[checked_count]) {
|
||||
checked_count = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
checked_count++;
|
||||
|
||||
if (checked_count == sizeof(CONFIG_B2SUM_SIGNATURE) - 1) {
|
||||
checksum_loc = &bootloader[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (checksum_loc == NULL) {
|
||||
fprintf(stderr, "ERROR: Checksum location not found in provided executable\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!reset) {
|
||||
memcpy(checksum_loc, argv[2], 128);
|
||||
} else {
|
||||
memset(checksum_loc, '0', 128);
|
||||
}
|
||||
|
||||
if (fseek(bootloader_file, 0, SEEK_SET) != 0) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Config file BLAKE2B successfully %s!\n", reset ? "reset" : "enrolled");
|
||||
}
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (bootloader != NULL) {
|
||||
free(bootloader);
|
||||
}
|
||||
if (bootloader_file != NULL) {
|
||||
fclose(bootloader_file);
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define LIMINE_VERSION "@LIMINE_VERSION@"
|
||||
|
||||
int main(void) {
|
||||
puts(LIMINE_VERSION);
|
||||
}
|
@ -12,7 +12,21 @@
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "limine-hdd.h"
|
||||
#ifndef LIMINE_NO_BIOS
|
||||
#include "limine-bios-hdd.h"
|
||||
#endif
|
||||
|
||||
static void remove_arg(int *argc, char *argv[], int index) {
|
||||
for (int i = index; i < *argc - 1; i++) {
|
||||
argv[i] = argv[i + 1];
|
||||
}
|
||||
|
||||
(*argc)--;
|
||||
|
||||
argv[*argc] = NULL;
|
||||
}
|
||||
|
||||
#ifndef LIMINE_NO_BIOS
|
||||
|
||||
static bool quiet = false;
|
||||
|
||||
@ -277,37 +291,37 @@ static bool device_cache_block(uint64_t block) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct undeploy_data {
|
||||
struct uninstall_data {
|
||||
void *data;
|
||||
uint64_t loc;
|
||||
uint64_t count;
|
||||
};
|
||||
|
||||
#define UNDEPLOY_DATA_MAX 256
|
||||
#define UNINSTALL_DATA_MAX 256
|
||||
|
||||
static bool undeploying = false;
|
||||
static struct undeploy_data undeploy_data[UNDEPLOY_DATA_MAX];
|
||||
static struct undeploy_data undeploy_data_rev[UNDEPLOY_DATA_MAX];
|
||||
static uint64_t undeploy_data_i = 0;
|
||||
static const char *undeploy_file = NULL;
|
||||
static bool uninstalling = false;
|
||||
static struct uninstall_data uninstall_data[UNINSTALL_DATA_MAX];
|
||||
static struct uninstall_data uninstall_data_rev[UNINSTALL_DATA_MAX];
|
||||
static uint64_t uninstall_data_i = 0;
|
||||
static const char *uninstall_file = NULL;
|
||||
|
||||
static void reverse_undeploy_data(void) {
|
||||
for (size_t i = 0, j = undeploy_data_i - 1; i < undeploy_data_i; i++, j--) {
|
||||
undeploy_data_rev[j] = undeploy_data[i];
|
||||
static void reverse_uninstall_data(void) {
|
||||
for (size_t i = 0, j = uninstall_data_i - 1; i < uninstall_data_i; i++, j--) {
|
||||
uninstall_data_rev[j] = uninstall_data[i];
|
||||
}
|
||||
|
||||
memcpy(undeploy_data, undeploy_data_rev, undeploy_data_i * sizeof(struct undeploy_data));
|
||||
memcpy(uninstall_data, uninstall_data_rev, uninstall_data_i * sizeof(struct uninstall_data));
|
||||
}
|
||||
|
||||
static void free_undeploy_data(void) {
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
free(undeploy_data[i].data);
|
||||
static void free_uninstall_data(void) {
|
||||
for (size_t i = 0; i < uninstall_data_i; i++) {
|
||||
free(uninstall_data[i].data);
|
||||
}
|
||||
}
|
||||
|
||||
static bool store_undeploy_data(const char *filename) {
|
||||
static bool store_uninstall_data(const char *filename) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Storing undeploy data to file: `%s`...\n", filename);
|
||||
fprintf(stderr, "Storing uninstall data to file: `%s`...\n", filename);
|
||||
}
|
||||
|
||||
FILE *udfile = fopen(filename, "wb");
|
||||
@ -315,18 +329,18 @@ static bool store_undeploy_data(const char *filename) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fwrite(&undeploy_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
if (fwrite(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
if (fwrite(&undeploy_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
for (size_t i = 0; i < uninstall_data_i; i++) {
|
||||
if (fwrite(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(&undeploy_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
if (fwrite(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(undeploy_data[i].data, undeploy_data[i].count, 1, udfile) != 1) {
|
||||
if (fwrite(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -342,9 +356,9 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_undeploy_data(const char *filename) {
|
||||
static bool load_uninstall_data(const char *filename) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Loading undeploy data from file: `%s`...\n", filename);
|
||||
fprintf(stderr, "Loading uninstall data from file: `%s`...\n", filename);
|
||||
}
|
||||
|
||||
FILE *udfile = fopen(filename, "rb");
|
||||
@ -352,22 +366,22 @@ static bool load_undeploy_data(const char *filename) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fread(&undeploy_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
if (fread(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
if (fread(&undeploy_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
for (size_t i = 0; i < uninstall_data_i; i++) {
|
||||
if (fread(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fread(&undeploy_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
if (fread(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
undeploy_data[i].data = malloc(undeploy_data[i].count);
|
||||
if (undeploy_data[i].data == NULL) {
|
||||
uninstall_data[i].data = malloc(uninstall_data[i].count);
|
||||
if (uninstall_data[i].data == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (fread(undeploy_data[i].data, undeploy_data[i].count, 1, udfile) != 1) {
|
||||
if (fread(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -407,16 +421,16 @@ static bool _device_read(void *_buffer, uint64_t loc, size_t count) {
|
||||
}
|
||||
|
||||
static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
|
||||
if (undeploying) {
|
||||
if (uninstalling) {
|
||||
goto skip_save;
|
||||
}
|
||||
|
||||
if (undeploy_data_i >= UNDEPLOY_DATA_MAX) {
|
||||
fprintf(stderr, "Internal error: Too many undeploy data entries!\n");
|
||||
if (uninstall_data_i >= UNINSTALL_DATA_MAX) {
|
||||
fprintf(stderr, "Internal error: Too many uninstall data entries!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct undeploy_data *ud = &undeploy_data[undeploy_data_i];
|
||||
struct uninstall_data *ud = &uninstall_data[uninstall_data_i];
|
||||
|
||||
ud->data = malloc(count);
|
||||
if (ud->data == NULL) {
|
||||
@ -453,31 +467,31 @@ skip_save:;
|
||||
progress += chunk;
|
||||
}
|
||||
|
||||
if (!undeploying) {
|
||||
undeploy_data_i++;
|
||||
if (!uninstalling) {
|
||||
uninstall_data_i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void undeploy(void) {
|
||||
undeploying = true;
|
||||
static void uninstall(void) {
|
||||
uninstalling = true;
|
||||
|
||||
cache_state = CACHE_CLEAN;
|
||||
cached_block = (uint64_t)-1;
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
struct undeploy_data *ud = &undeploy_data[i];
|
||||
for (size_t i = 0; i < uninstall_data_i; i++) {
|
||||
struct uninstall_data *ud = &uninstall_data[i];
|
||||
bool retry = false;
|
||||
while (!_device_write(ud->data, ud->loc, ud->count)) {
|
||||
if (retry) {
|
||||
fprintf(stderr, "ERROR: Undeploy data index %zu failed to write. Undeploy may be incomplete!\n", i);
|
||||
fprintf(stderr, "ERROR: Uninstall data index %zu failed to write. Uninstall may be incomplete!\n", i);
|
||||
break;
|
||||
}
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Warning: Undeploy data index %zu failed to write, retrying...\n", i);
|
||||
fprintf(stderr, "Warning: Uninstall data index %zu failed to write, retrying...\n", i);
|
||||
}
|
||||
if (!device_flush_cache()) {
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Undeploy may be incomplete!\n");
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Uninstall may be incomplete!\n");
|
||||
}
|
||||
cache_state = CACHE_CLEAN;
|
||||
cached_block = (uint64_t)-1;
|
||||
@ -486,11 +500,11 @@ static void undeploy(void) {
|
||||
}
|
||||
|
||||
if (!device_flush_cache()) {
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Undeploy may be incomplete!\n");
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Uninstall may be incomplete!\n");
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Undeploy data restored successfully. Limine undeployed!\n");
|
||||
fprintf(stderr, "Uninstall data restored successfully. Limine uninstalled!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,17 +520,17 @@ static void undeploy(void) {
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
static void usage(const char *name) {
|
||||
printf("Usage: %s <device> [GPT partition index]\n", name);
|
||||
static void bios_install_usage(const char *name) {
|
||||
printf("Usage: %s bios-install <device> [GPT partition index]\n", name);
|
||||
printf("\n");
|
||||
printf(" --force-mbr Force MBR detection to work even if the\n");
|
||||
printf(" safety checks fail (DANGEROUS!)\n");
|
||||
printf("\n");
|
||||
printf(" --undeploy Reverse the entire deployment procedure\n");
|
||||
printf(" --uninstall Reverse the entire install procedure\n");
|
||||
printf("\n");
|
||||
printf(" --undeploy-data-file=<filename>\n");
|
||||
printf(" Set the input (for --undeploy) or output file\n");
|
||||
printf(" name of the file which contains undeploy data\n");
|
||||
printf(" --uninstall-data-file=<filename>\n");
|
||||
printf(" Set the input (for --uninstall) or output file\n");
|
||||
printf(" name of the file which contains uninstall data\n");
|
||||
printf("\n");
|
||||
printf(" --quiet Do not print verbose diagnostic messages\n");
|
||||
printf("\n");
|
||||
@ -524,10 +538,10 @@ static void usage(const char *name) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
static int bios_install(int argc, char *argv[]) {
|
||||
int ok = EXIT_FAILURE;
|
||||
int force_mbr = 0;
|
||||
bool undeploy_mode = false;
|
||||
bool uninstall_mode = false;
|
||||
const uint8_t *bootloader_img = binary_limine_hdd_bin_data;
|
||||
size_t bootloader_file_size = sizeof(binary_limine_hdd_bin_data);
|
||||
uint8_t orig_mbr[70], timestamp[6];
|
||||
@ -540,7 +554,7 @@ int main(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
bios_install_usage(argv[-1]);
|
||||
#ifdef IS_WINDOWS
|
||||
system("pause");
|
||||
#endif
|
||||
@ -549,7 +563,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
bios_install_usage(argv[-1]);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[i], "--quiet") == 0) {
|
||||
quiet = true;
|
||||
@ -558,18 +572,18 @@ int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "Warning: --force-mbr already set.\n");
|
||||
}
|
||||
force_mbr = 1;
|
||||
} else if (strcmp(argv[i], "--undeploy") == 0) {
|
||||
if (undeploy_mode && !quiet) {
|
||||
fprintf(stderr, "Warning: --undeploy already set.\n");
|
||||
} else if (strcmp(argv[i], "--uninstall") == 0) {
|
||||
if (uninstall_mode && !quiet) {
|
||||
fprintf(stderr, "Warning: --uninstall already set.\n");
|
||||
}
|
||||
undeploy_mode = true;
|
||||
} else if (memcmp(argv[i], "--undeploy-data-file=", 21) == 0) {
|
||||
if (undeploy_file != NULL && !quiet) {
|
||||
fprintf(stderr, "Warning: --undeploy-data-file already set. Overriding...\n");
|
||||
uninstall_mode = true;
|
||||
} else if (memcmp(argv[i], "--uninstall-data-file=", 21) == 0) {
|
||||
if (uninstall_file != NULL && !quiet) {
|
||||
fprintf(stderr, "Warning: --uninstall-data-file already set. Overriding...\n");
|
||||
}
|
||||
undeploy_file = argv[i] + 21;
|
||||
if (strlen(undeploy_file) == 0) {
|
||||
fprintf(stderr, "ERROR: Undeploy data file has a zero-length name!\n");
|
||||
uninstall_file = argv[i] + 21;
|
||||
if (strlen(uninstall_file) == 0) {
|
||||
fprintf(stderr, "ERROR: Uninstall data file has a zero-length name!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
@ -584,28 +598,28 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (device == NULL) {
|
||||
fprintf(stderr, "ERROR: No device specified\n");
|
||||
usage(argv[0]);
|
||||
bios_install_usage(argv[-1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!device_init()) {
|
||||
goto undeploy_mode_cleanup;
|
||||
goto uninstall_mode_cleanup;
|
||||
}
|
||||
|
||||
if (undeploy_mode) {
|
||||
if (undeploy_file == NULL) {
|
||||
fprintf(stderr, "ERROR: Undeploy mode set but no --undeploy-data-file=... passed.\n");
|
||||
goto undeploy_mode_cleanup;
|
||||
if (uninstall_mode) {
|
||||
if (uninstall_file == NULL) {
|
||||
fprintf(stderr, "ERROR: Uninstall mode set but no --uninstall-data-file=... passed.\n");
|
||||
goto uninstall_mode_cleanup;
|
||||
}
|
||||
|
||||
if (!load_undeploy_data(undeploy_file)) {
|
||||
goto undeploy_mode_cleanup;
|
||||
if (!load_uninstall_data(uninstall_file)) {
|
||||
goto uninstall_mode_cleanup;
|
||||
}
|
||||
|
||||
undeploy();
|
||||
uninstall();
|
||||
|
||||
ok = EXIT_SUCCESS;
|
||||
goto undeploy_mode_cleanup;
|
||||
goto uninstall_mode_cleanup;
|
||||
}
|
||||
|
||||
// Probe for GPT and logical block size
|
||||
@ -620,7 +634,7 @@ int main(int argc, char *argv[]) {
|
||||
if (!force_mbr) {
|
||||
gpt = 1;
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Deploying to GPT. Logical block size of %" PRIu64 " bytes.\n",
|
||||
fprintf(stderr, "Installing to GPT. Logical block size of %" PRIu64 " bytes.\n",
|
||||
lb_guesses[i]);
|
||||
}
|
||||
} else {
|
||||
@ -810,7 +824,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "GPT partition specified. Deploying there instead of embedding.\n");
|
||||
fprintf(stderr, "GPT partition specified. Installing there instead of embedding.\n");
|
||||
}
|
||||
|
||||
stage2_loc_a = ENDSWAP(gpt_entry.starting_lba) * lb_size;
|
||||
@ -912,7 +926,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
} else {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Deploying to MBR.\n");
|
||||
fprintf(stderr, "Installing to MBR.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,25 +969,25 @@ int main(int argc, char *argv[]) {
|
||||
goto cleanup;
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Reminder: Remember to copy the limine.sys file in either\n"
|
||||
fprintf(stderr, "Reminder: Remember to copy the limine-bios.sys file in either\n"
|
||||
" the root, /boot, /limine, or /boot/limine directories of\n"
|
||||
" one of the partitions on the device, or boot will fail!\n");
|
||||
|
||||
fprintf(stderr, "Limine deployed successfully!\n");
|
||||
fprintf(stderr, "Limine BIOS stages installed successfully!\n");
|
||||
}
|
||||
|
||||
ok = EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
reverse_undeploy_data();
|
||||
reverse_uninstall_data();
|
||||
if (ok != EXIT_SUCCESS) {
|
||||
// If we failed, attempt to reverse deploy process
|
||||
undeploy();
|
||||
} else if (undeploy_file != NULL) {
|
||||
store_undeploy_data(undeploy_file);
|
||||
// If we failed, attempt to reverse install process
|
||||
uninstall();
|
||||
} else if (uninstall_file != NULL) {
|
||||
store_uninstall_data(uninstall_file);
|
||||
}
|
||||
undeploy_mode_cleanup:
|
||||
free_undeploy_data();
|
||||
uninstall_mode_cleanup:
|
||||
free_uninstall_data();
|
||||
if (cache)
|
||||
free(cache);
|
||||
if (device != NULL)
|
||||
@ -981,3 +995,173 @@ undeploy_mode_cleanup:
|
||||
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++"
|
||||
|
||||
static void enroll_config_usage(const char *name) {
|
||||
printf("Usage: %s enroll-config <Limine executable> <BLAKE2B of config file>\n", name);
|
||||
printf("\n");
|
||||
printf(" --reset Remove enrolled BLAKE2B, will not check config integrity\n");
|
||||
printf("\n");
|
||||
printf(" --quiet Do not print verbose diagnostic messages\n");
|
||||
printf("\n");
|
||||
printf(" --help | -h Display this help message\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static int enroll_config(int argc, char *argv[]) {
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
char *bootloader = NULL;
|
||||
FILE *bootloader_file = NULL;
|
||||
bool quiet = false;
|
||||
bool reset = false;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||
enroll_config_usage(argv[-1]);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[i], "--quiet") == 0) {
|
||||
remove_arg(&argc, argv, i);
|
||||
quiet = true;
|
||||
} else if (strcmp(argv[i], "--reset") == 0) {
|
||||
remove_arg(&argc, argv, i);
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= (reset ? 1 : 2)) {
|
||||
enroll_config_usage(argv[-1]);
|
||||
#ifdef IS_WINDOWS
|
||||
system("pause");
|
||||
#endif
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!reset && strlen(argv[2]) != 128) {
|
||||
fprintf(stderr, "ERROR: BLAKE2B specified is not 128 characters long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
bootloader_file = fopen(argv[1], "r+b");
|
||||
if (bootloader_file == NULL) {
|
||||
perror("ERROR");
|
||||
goto cleanup;;
|
||||
}
|
||||
|
||||
if (fseek(bootloader_file, 0, SEEK_END) != 0) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
size_t bootloader_size = ftell(bootloader_file);
|
||||
rewind(bootloader_file);
|
||||
|
||||
bootloader = malloc(bootloader_size);
|
||||
if (bootloader == NULL) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char *checksum_loc = NULL;
|
||||
size_t checked_count = 0;
|
||||
const char *config_b2sum_sign = CONFIG_B2SUM_SIGNATURE;
|
||||
for (size_t i = 0; i < bootloader_size - ((sizeof(CONFIG_B2SUM_SIGNATURE) - 1) + 128) + 1; i++) {
|
||||
if (bootloader[i] != config_b2sum_sign[checked_count]) {
|
||||
checked_count = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
checked_count++;
|
||||
|
||||
if (checked_count == sizeof(CONFIG_B2SUM_SIGNATURE) - 1) {
|
||||
checksum_loc = &bootloader[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (checksum_loc == NULL) {
|
||||
fprintf(stderr, "ERROR: Checksum location not found in provided executable\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!reset) {
|
||||
memcpy(checksum_loc, argv[2], 128);
|
||||
} else {
|
||||
memset(checksum_loc, '0', 128);
|
||||
}
|
||||
|
||||
if (fseek(bootloader_file, 0, SEEK_SET) != 0) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Config file BLAKE2B successfully %s!\n", reset ? "reset" : "enrolled");
|
||||
}
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (bootloader != NULL) {
|
||||
free(bootloader);
|
||||
}
|
||||
if (bootloader_file != NULL) {
|
||||
fclose(bootloader_file);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define LIMINE_VERSION "%VERSION%"
|
||||
#define LIMINE_COPYRIGHT "%COPYRIGHT%"
|
||||
|
||||
static int version(void) {
|
||||
puts("Limine " LIMINE_VERSION);
|
||||
puts(LIMINE_COPYRIGHT);
|
||||
puts("Limine is distributed under the terms of the BSD-2-Clause license.");
|
||||
puts("There is ABSOLUTELY NO WARRANTY, to the extent permitted by law.");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void general_usage(const char *name) {
|
||||
printf("Usage: %s <command> <args...>\n", name);
|
||||
printf("\n");
|
||||
printf("Valid commands: help, version, bios-install, enroll-config\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc <= 1) {
|
||||
general_usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "help") == 0
|
||||
|| strcmp(argv[1], "--help") == 0
|
||||
|| strcmp(argv[1], "-h") == 0) {
|
||||
general_usage(argv[0]);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[1], "bios-install") == 0) {
|
||||
#ifndef LIMINE_NO_BIOS
|
||||
return bios_install(argc - 1, &argv[1]);
|
||||
#else
|
||||
fprintf(stderr, "ERROR: Limine has been compiled without BIOS support.\n");
|
||||
return EXIT_FAILURE;
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "enroll-config") == 0) {
|
||||
return enroll_config(argc - 1, &argv[1]);
|
||||
} else if (strcmp(argv[1], "version") == 0
|
||||
|| strcmp(argv[1], "--version") == 0) {
|
||||
return version();
|
||||
}
|
||||
|
||||
general_usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
.TH LIMINE-DEPLOY 1 "version @PACKAGE_VERSION@" "@REGEN_DATE@"
|
||||
|
||||
.SH NAME
|
||||
limine-deploy \- install BIOS port's early stages to device
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B limine-deploy
|
||||
.RI "<device> [ GPT partition index ]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBlimine-deploy\fR installs the BIOS port's early stages to the specified device.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Show the available command-line options and exit
|
||||
.TP
|
||||
.BR \-\-force-mbr
|
||||
Force MBR detection to work even if the safety checks fail (\fIDANGEROUS\fR!)
|
||||
.TP
|
||||
.BR \-\-undeploy
|
||||
Reverse the entire deployment procedure
|
||||
.TP
|
||||
.BR \-\-undeploy-data-file= \fIfilename
|
||||
Set the input (for --undeploy) or output file name of the file which contains undeploy data
|
||||
.TP
|
||||
.BR \-\-quiet
|
||||
Do not print verbose diagnostic messages
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via
|
||||
.IR @PACKAGE_BUGREPORT@ .
|
||||
|
||||
.SH HOMEPAGE
|
||||
.I @PACKAGE_URL@
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR limine-version (1)
|
||||
.BR limine-enroll-config (1)
|
@ -1,34 +0,0 @@
|
||||
.TH LIMINE-ENROLL-CONFIG 1 "version @PACKAGE_VERSION@" "@REGEN_DATE@"
|
||||
|
||||
.SH NAME
|
||||
limine-enroll-config \- embed config hash into Limine executable
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B limine-enroll-config
|
||||
.RI "<Limine executable> <BLAKE2B of config file>"
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBlimine-enroll-config\fR embeds the config file's BLAKE2B hash into a valid Limine bootloader
|
||||
executable, such as its EFI executable or limine.sys, for tampering prevention purposes.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Show the available command-line options and exit
|
||||
.TP
|
||||
.BR \-\-reset
|
||||
Remove enrolled BLAKE2B, will not check config intergrity
|
||||
.TP
|
||||
.BR \-\-quiet
|
||||
Do not print verbose diagnostic messages
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via
|
||||
.IR @PACKAGE_BUGREPORT@ .
|
||||
|
||||
.SH HOMEPAGE
|
||||
.I @PACKAGE_URL@
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR limine-version (1)
|
||||
.BR limine-deploy (1)
|
@ -1,22 +0,0 @@
|
||||
.TH LIMINE-VERSION 1 "version @PACKAGE_VERSION@" "@REGEN_DATE@"
|
||||
|
||||
.SH NAME
|
||||
limine-version \- print Limine version
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B limine-version
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBlimine-version\fR prints the version number of the installed copy of Limine
|
||||
to standard output.
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via
|
||||
.IR @PACKAGE_BUGREPORT@ .
|
||||
|
||||
.SH HOMEPAGE
|
||||
.I https://limine-bootloader.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR limine-deploy (1)
|
||||
.BR limine-enroll-config (1)
|
18
man/man1/limine.1.in
Normal file
18
man/man1/limine.1.in
Normal file
@ -0,0 +1,18 @@
|
||||
.TH LIMINE 1 "version @PACKAGE_VERSION@" "@REGEN_DATE@"
|
||||
|
||||
.SH NAME
|
||||
limine \- Multiplexer to several Limine-related utilities.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B limine
|
||||
.RI "<command> <args...>"
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBlimine\fR provides a series of Limine-related utilities condensed in a single executable.
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via
|
||||
.IR @PACKAGE_BUGREPORT@ .
|
||||
|
||||
.SH HOMEPAGE
|
||||
.I @PACKAGE_URL@
|
56
test.mk
56
test.mk
@ -11,6 +11,10 @@ ovmf-aa64:
|
||||
$(MKDIR_P) ovmf-aa64
|
||||
cd ovmf-aa64 && curl -o OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASEAARCH64_QEMU_EFI.fd
|
||||
|
||||
ovmf-rv64:
|
||||
$(MKDIR_P) ovmf-rv64
|
||||
cd ovmf-rv64 && curl -o OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASERISCV64_VIRT_CODE.fd && dd if=/dev/zero of=OVMF.fd bs=1 count=0 seek=33554432
|
||||
|
||||
ovmf-ia32:
|
||||
$(MKDIR_P) ovmf-ia32
|
||||
cd ovmf-ia32 && curl -o OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASEIa32_OVMF.fd
|
||||
@ -33,7 +37,7 @@ ext2-test:
|
||||
$(MAKE) test-clean
|
||||
$(MAKE) test.hdd
|
||||
$(MAKE) limine-bios
|
||||
$(MAKE) limine-deploy
|
||||
$(MAKE) limine
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-x86_64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
@ -48,7 +52,7 @@ ext2-test:
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
$(BINDIR)/limine-deploy test.hdd
|
||||
$(BINDIR)/limine bios-install test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
|
||||
|
||||
.PHONY: fat12-test
|
||||
@ -56,7 +60,7 @@ fat12-test:
|
||||
$(MAKE) test-clean
|
||||
$(MAKE) test.hdd
|
||||
$(MAKE) limine-bios
|
||||
$(MAKE) limine-deploy
|
||||
$(MAKE) limine
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-x86_64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
@ -71,7 +75,7 @@ fat12-test:
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
$(BINDIR)/limine-deploy test.hdd
|
||||
$(BINDIR)/limine bios-install test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
|
||||
|
||||
.PHONY: fat16-test
|
||||
@ -79,7 +83,7 @@ fat16-test:
|
||||
$(MAKE) test-clean
|
||||
$(MAKE) test.hdd
|
||||
$(MAKE) limine-bios
|
||||
$(MAKE) limine-deploy
|
||||
$(MAKE) limine
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-x86_64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
@ -94,7 +98,7 @@ fat16-test:
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
$(BINDIR)/limine-deploy test.hdd
|
||||
$(BINDIR)/limine bios-install test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
|
||||
|
||||
.PHONY: legacy-fat16-test
|
||||
@ -103,7 +107,7 @@ legacy-fat16-test:
|
||||
$(MAKE) mbrtest.hdd
|
||||
fdisk -l mbrtest.hdd
|
||||
$(MAKE) limine-bios
|
||||
$(MAKE) limine-deploy
|
||||
$(MAKE) limine
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-x86_64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
@ -118,7 +122,7 @@ legacy-fat16-test:
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
$(BINDIR)/limine-deploy mbrtest.hdd
|
||||
$(BINDIR)/limine bios-install mbrtest.hdd
|
||||
qemu-system-i386 -cpu pentium2 -m 16M -M isapc -net none -hda mbrtest.hdd -debugcon stdio
|
||||
|
||||
.PHONY: fat32-test
|
||||
@ -126,7 +130,7 @@ fat32-test:
|
||||
$(MAKE) test-clean
|
||||
$(MAKE) test.hdd
|
||||
$(MAKE) limine-bios
|
||||
$(MAKE) limine-deploy
|
||||
$(MAKE) limine
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-x86_64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
@ -141,7 +145,7 @@ fat32-test:
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
$(BINDIR)/limine-deploy test.hdd
|
||||
$(BINDIR)/limine bios-install test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
|
||||
|
||||
.PHONY: iso9660-test
|
||||
@ -154,7 +158,7 @@ iso9660-test:
|
||||
$(MKDIR_P) test_image/boot
|
||||
sudo cp -rv $(BINDIR)/* test_image/boot/
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
xorriso -as mkisofs -b boot/limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table test_image/ -o test.iso
|
||||
xorriso -as mkisofs -b boot/limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table test_image/ -o test.iso
|
||||
qemu-system-x86_64 -net none -smp 4 -cdrom test.iso -debugcon stdio
|
||||
|
||||
.PHONY: full-hybrid-test
|
||||
@ -168,8 +172,8 @@ full-hybrid-test:
|
||||
$(MKDIR_P) test_image/boot
|
||||
sudo cp -rv $(BINDIR)/* test_image/boot/
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
xorriso -as mkisofs -b boot/limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine-cd-efi.bin -efi-boot-part --efi-boot-image --protective-msdos-label test_image/ -o test.iso
|
||||
$(BINDIR)/limine-deploy test.iso
|
||||
xorriso -as mkisofs -b boot/limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine-uefi-cd.bin -efi-boot-part --efi-boot-image --protective-msdos-label test_image/ -o test.iso
|
||||
$(BINDIR)/limine bios-install test.iso
|
||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -hda test.iso -debugcon stdio
|
||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-ia32/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
||||
@ -186,7 +190,7 @@ pxe-test:
|
||||
$(MKDIR_P) test_image/boot
|
||||
sudo cp -rv $(BINDIR)/* test_image/boot/
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
qemu-system-x86_64 -smp 4 -netdev user,id=n0,tftp=./test_image,bootfile=boot/limine-pxe.bin -device rtl8139,netdev=n0,mac=00:00:00:11:11:11 -debugcon stdio
|
||||
qemu-system-x86_64 -smp 4 -netdev user,id=n0,tftp=./test_image,bootfile=boot/limine-bios-pxe.bin -device rtl8139,netdev=n0,mac=00:00:00:11:11:11 -debugcon stdio
|
||||
|
||||
.PHONY: uefi-x86-64-test
|
||||
uefi-x86-64-test:
|
||||
@ -236,6 +240,30 @@ uefi-aa64-test:
|
||||
rm -rf test_image loopback_dev
|
||||
qemu-system-aarch64 -m 512M -M virt -cpu cortex-a72 -bios ovmf-aa64/OVMF.fd -net none -smp 4 -device ramfb -device qemu-xhci -device usb-kbd -hda test.hdd -serial stdio
|
||||
|
||||
.PHONY: uefi-rv64-test
|
||||
uefi-rv64-test:
|
||||
$(MAKE) ovmf-rv64
|
||||
$(MAKE) test-clean
|
||||
$(MAKE) test.hdd
|
||||
$(MAKE) limine-uefi-riscv64
|
||||
$(MAKE) -C test TOOLCHAIN_FILE='$(call SHESCAPE,$(BUILDDIR))/toolchain-files/uefi-riscv64-toolchain.mk'
|
||||
rm -rf test_image/
|
||||
mkdir test_image
|
||||
sudo losetup -Pf --show test.hdd > loopback_dev
|
||||
sudo partprobe `cat loopback_dev`
|
||||
sudo mkfs.fat -F 32 `cat loopback_dev`p1
|
||||
sudo mount `cat loopback_dev`p1 test_image
|
||||
sudo mkdir test_image/boot
|
||||
sudo cp -rv $(BINDIR)/* test_image/boot/
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
sudo $(MKDIR_P) test_image/EFI/BOOT
|
||||
sudo cp $(BINDIR)/BOOTRISCV64.EFI test_image/EFI/BOOT/
|
||||
sync
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
qemu-system-riscv64 -m 512M -M virt -cpu rv64 -drive if=pflash,unit=0,format=raw,file=ovmf-rv64/OVMF.fd -net none -smp 4 -device ramfb -device qemu-xhci -device usb-kbd -device virtio-blk-device,drive=hd0 -drive id=hd0,format=raw,file=test.hdd -serial stdio
|
||||
|
||||
.PHONY: uefi-ia32-test
|
||||
uefi-ia32-test:
|
||||
$(MAKE) ovmf-ia32
|
||||
|
1
test/.gitignore
vendored
1
test/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
test.o
|
||||
test.elf
|
||||
flanterm
|
||||
limine.h
|
||||
|
@ -20,6 +20,10 @@ ifneq ($(findstring aarch64,$(shell $(CC_FOR_TARGET) -dumpmachine)),)
|
||||
override LDFLAGS += \
|
||||
-m aarch64elf
|
||||
endif
|
||||
ifneq ($(findstring riscv64,$(shell $(CC_FOR_TARGET) -dumpmachine)),)
|
||||
override LDFLAGS += \
|
||||
-m elf64lriscv
|
||||
endif
|
||||
|
||||
override LDFLAGS += \
|
||||
-Tlinker.ld \
|
||||
@ -69,6 +73,15 @@ override CFLAGS += \
|
||||
-mgeneral-regs-only
|
||||
endif
|
||||
|
||||
ifneq ($(findstring riscv64,$(shell $(CC_FOR_TARGET) -dumpmachine)),)
|
||||
override CFLAGS += \
|
||||
-march=rv64imac \
|
||||
-mabi=lp64 \
|
||||
-mno-relax
|
||||
override LDFLAGS += \
|
||||
--no-relax
|
||||
endif
|
||||
|
||||
override CFLAGS_MB := \
|
||||
-std=c11 \
|
||||
-nostdinc \
|
||||
@ -91,10 +104,14 @@ else
|
||||
all: test.elf
|
||||
endif
|
||||
|
||||
flanterm:
|
||||
mkdir -p flanterm
|
||||
cp -rv ../common/flanterm/* ./flanterm/
|
||||
|
||||
limine.h:
|
||||
cp -v ../limine.h ./
|
||||
|
||||
test.elf: limine.o e9print.o memory.o
|
||||
test.elf: limine.o e9print.o memory.o flanterm/flanterm.o flanterm/backends/fb.o
|
||||
$(LD) $^ $(LDFLAGS) -o $@
|
||||
|
||||
multiboot2.elf: multiboot2_trampoline.o
|
||||
@ -109,7 +126,7 @@ multiboot.elf: multiboot_trampoline.o
|
||||
$(CC) $(CFLAGS_MB) -c e9print.c -o e9print.o
|
||||
$(LD) $^ memory.o multiboot.o e9print.o $(LDFLAGS_MB1) -o $@
|
||||
|
||||
%.o: %.c limine.h
|
||||
%.o: %.c flanterm limine.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.asm
|
||||
@ -119,4 +136,4 @@ clean:
|
||||
rm -rf test.elf limine.o e9print.o memory.o
|
||||
rm -rf multiboot2.o multiboot2.elf multiboot2_trampoline.o
|
||||
rm -rf multiboot.o multiboot_trampoline.o multiboot.elf
|
||||
rm -rf limine.h
|
||||
rm -rf flanterm limine.h
|
||||
|
@ -2,16 +2,22 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void (*limine_print)(const char *buf, size_t size) = NULL;
|
||||
#if defined (_LIMINE_PROTO)
|
||||
#include <flanterm/flanterm.h>
|
||||
extern struct flanterm_context *ft_ctx;
|
||||
#endif
|
||||
|
||||
static const char CONVERSION_TABLE[] = "0123456789abcdef";
|
||||
|
||||
void e9_putc(char c) {
|
||||
if (limine_print != NULL)
|
||||
limine_print(&c, 1);
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
__asm__ __volatile__ ("outb %0, %1" :: "a" (c), "Nd" (0xe9) : "memory");
|
||||
#endif
|
||||
#if defined (_LIMINE_PROTO)
|
||||
if (ft_ctx != NULL) {
|
||||
flanterm_write(ft_ctx, &c, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void e9_print(const char *msg) {
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
extern void (*limine_print)(const char *buf, size_t size);
|
||||
|
||||
void e9_putc(char c);
|
||||
void e9_print(const char *msg);
|
||||
void e9_puts(const char *msg);
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <stddef.h>
|
||||
#include <limine.h>
|
||||
#include <e9print.h>
|
||||
#include <flanterm/flanterm.h>
|
||||
#include <flanterm/backends/fb.h>
|
||||
|
||||
static void limine_main(void);
|
||||
|
||||
@ -135,14 +137,6 @@ struct limine_smp_request _smp_request = {
|
||||
__attribute__((section(".limine_reqs")))
|
||||
void *smp_req = &_smp_request;
|
||||
|
||||
struct limine_terminal_request _terminal_request = {
|
||||
.id = LIMINE_TERMINAL_REQUEST,
|
||||
.revision = 0, .response = NULL
|
||||
};
|
||||
|
||||
__attribute__((section(".limine_reqs")))
|
||||
void *terminal_req = &_terminal_request;
|
||||
|
||||
struct limine_dtb_request _dtb_request = {
|
||||
.id = LIMINE_DTB_REQUEST,
|
||||
.revision = 0, .response = NULL
|
||||
@ -226,6 +220,8 @@ void ap_entry(struct limine_smp_info *info) {
|
||||
#elif defined (__aarch64__)
|
||||
e9_printf("My GIC CPU Interface no.: %x", info->gic_iface_no);
|
||||
e9_printf("My MPIDR: %x", info->mpidr);
|
||||
#elif defined (__riscv)
|
||||
e9_printf("My Hart ID: %x", info->hartid);
|
||||
#endif
|
||||
|
||||
__atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST);
|
||||
@ -238,19 +234,26 @@ void ap_entry(struct limine_smp_info *info) {
|
||||
|
||||
extern char kernel_start[];
|
||||
|
||||
static void write_shim(const char *s, uint64_t l) {
|
||||
struct limine_terminal *terminal = _terminal_request.response->terminals[0];
|
||||
|
||||
_terminal_request.response->write(terminal, s, l);
|
||||
}
|
||||
struct flanterm_context *ft_ctx = NULL;
|
||||
|
||||
static void limine_main(void) {
|
||||
if (_terminal_request.response) {
|
||||
limine_print = write_shim;
|
||||
}
|
||||
|
||||
e9_printf("\nWe're alive");
|
||||
|
||||
struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0];
|
||||
|
||||
ft_ctx = flanterm_fb_simple_init(
|
||||
fb->address,
|
||||
fb->width,
|
||||
fb->height,
|
||||
fb->pitch,
|
||||
fb->red_mask_size,
|
||||
fb->red_mask_shift,
|
||||
fb->green_mask_size,
|
||||
fb->green_mask_shift,
|
||||
fb->blue_mask_size,
|
||||
fb->blue_mask_shift
|
||||
);
|
||||
|
||||
uint64_t kernel_slide = (uint64_t)kernel_start - 0xffffffff80000000;
|
||||
|
||||
e9_printf("Kernel slide: %x", kernel_slide);
|
||||
@ -422,6 +425,8 @@ FEAT_START
|
||||
e9_printf("BSP LAPIC ID: %x", smp_response->bsp_lapic_id);
|
||||
#elif defined (__aarch64__)
|
||||
e9_printf("BSP MPIDR: %x", smp_response->bsp_mpidr);
|
||||
#elif defined (__riscv)
|
||||
e9_printf("BSP Hart ID: %x", smp_response->bsp_hartid);
|
||||
#endif
|
||||
e9_printf("CPU count: %d", smp_response->cpu_count);
|
||||
for (size_t i = 0; i < smp_response->cpu_count; i++) {
|
||||
@ -432,6 +437,8 @@ FEAT_START
|
||||
#elif defined (__aarch64__)
|
||||
e9_printf("GIC CPU Interface no.: %x", cpu->gic_iface_no);
|
||||
e9_printf("MPIDR: %x", cpu->mpidr);
|
||||
#elif defined (__riscv)
|
||||
e9_printf("Hart ID: %x", cpu->hartid);
|
||||
#endif
|
||||
|
||||
|
||||
@ -439,6 +446,8 @@ FEAT_START
|
||||
if (cpu->lapic_id != smp_response->bsp_lapic_id) {
|
||||
#elif defined (__aarch64__)
|
||||
if (cpu->mpidr != smp_response->bsp_mpidr) {
|
||||
#elif defined (__riscv)
|
||||
if (cpu->hartid != smp_response->bsp_hartid) {
|
||||
#endif
|
||||
uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST);
|
||||
|
||||
@ -450,24 +459,6 @@ FEAT_START
|
||||
}
|
||||
FEAT_END
|
||||
|
||||
FEAT_START
|
||||
e9_printf("");
|
||||
if (_terminal_request.response == NULL) {
|
||||
e9_printf("Terminal not passed");
|
||||
break;
|
||||
}
|
||||
struct limine_terminal_response *term_response = _terminal_request.response;
|
||||
e9_printf("Terminal feature, revision %d", term_response->revision);
|
||||
e9_printf("%d terminal(s)", term_response->terminal_count);
|
||||
for (size_t i = 0; i < term_response->terminal_count; i++) {
|
||||
struct limine_terminal *terminal = term_response->terminals[i];
|
||||
e9_printf("Columns: %d", terminal->columns);
|
||||
e9_printf("Rows: %d", terminal->rows);
|
||||
e9_printf("Using framebuffer: %x", terminal->framebuffer);
|
||||
}
|
||||
e9_printf("Write function at: %x", term_response->write);
|
||||
FEAT_END
|
||||
|
||||
FEAT_START
|
||||
e9_printf("");
|
||||
if (_dtb_request.response == NULL) {
|
||||
|
@ -30,6 +30,7 @@ SECTIONS
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.*)
|
||||
} :data
|
||||
|
||||
.dynamic : {
|
||||
@ -37,6 +38,7 @@ SECTIONS
|
||||
} :data :dynamic
|
||||
|
||||
.bss : {
|
||||
*(.sbss .sbss.*)
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
Loading…
x
Reference in New Issue
Block a user