From a4dce7f4d920e492d38c32ad3e42efdcfef3b3f1 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 12 Jul 2026 01:19:32 +0000 Subject: 🌭 plan9-kencc-linux: кросс-Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½ Plan9 (cc/as/ld) + EFI-Π±ΠΎΠ»Π²Π°Π½ΠΊΠ° MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - build_arch.sh / build_al.sh: сборка kencc-компиляторов, ассСмблСров, Π»ΠΈΠ½ΠΊΠ΅Ρ€ΠΎΠ² всСх Π°Ρ€ΠΎΠΊ (5/6/8/v/q/k) Π½Π° Linux-хостС Ρ‡Π΅Ρ€Π΅Π· plan9port. - ΠΏΠ°Ρ‚Ρ‡ΠΈ ΠΏΠΎΠ΄ musl/gcc: sbrk->mmap, round/log2->p9*, Runemask, swcmp const, -fcommon, machcap/omachcap, /sys Ρ€Π°Π½Ρ‚Π°ΠΉΠΌ-Ρ„Π°ΠΉΠ»Ρ‹. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Π² PATCHES.md. - bin/: Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ 8c 6c 5c vc qc kc + 6a 6l (Linux/musl x86_64). - efi/: Π±ΠΎΠ»Π²Π°Π½ΠΎΡ‡Π½Ρ‹ΠΉ bootx64.efi (PE32+) Ρ‚Π΅ΠΌ ΠΆΠ΅ Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½ΠΎΠΌ (6a+6c+6l+dd), рСфСрСнс β€” 9legacy nboot/efi; ESP-ΠΎΠ±Ρ€Π°Π· Ρ‡Π΅Ρ€Π΅Π· mkesp.py. Co-Authored-By: Claude Opus 4.8 --- .gitignore | 15 +++++++ NOTICE | 22 ++++++++++ PATCHES.md | 58 +++++++++++++++++++++++++++ README.md | 75 +++++++++++++++++++++++++++++++++++ bin/5c | Bin 0 -> 1006072 bytes bin/6a | Bin 0 -> 408832 bytes bin/6c | Bin 0 -> 1094136 bytes bin/6l | Bin 0 -> 546056 bytes bin/8c | Bin 0 -> 1135776 bytes bin/kc | Bin 0 -> 979568 bytes bin/qc | Bin 0 -> 1053832 bytes bin/vc | Bin 0 -> 981056 bytes efi/README.md | 35 ++++++++++++++++ efi/efi_build.sh | 32 +++++++++++++++ efi/fetch_ref.sh | 24 +++++++++++ efi/hello.c | 52 ++++++++++++++++++++++++ efi/mkesp.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ scripts/build_al.sh | 57 ++++++++++++++++++++++++++ scripts/build_all.sh | 19 +++++++++ scripts/build_arch.sh | 68 +++++++++++++++++++++++++++++++ scripts/setup.sh | 30 ++++++++++++++ 21 files changed, 595 insertions(+) create mode 100644 .gitignore create mode 100644 NOTICE create mode 100644 PATCHES.md create mode 100644 README.md create mode 100755 bin/5c create mode 100755 bin/6a create mode 100755 bin/6c create mode 100755 bin/6l create mode 100755 bin/8c create mode 100755 bin/kc create mode 100755 bin/qc create mode 100755 bin/vc create mode 100644 efi/README.md create mode 100644 efi/efi_build.sh create mode 100644 efi/fetch_ref.sh create mode 100644 efi/hello.c create mode 100644 efi/mkesp.py create mode 100644 scripts/build_al.sh create mode 100644 scripts/build_all.sh create mode 100644 scripts/build_arch.sh create mode 100644 scripts/setup.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65f10ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# зависимости, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ тянутся скриптами +deps/ +efi/nboot.diff +efi/pe64.s +efi/pe64min.s +efi/efi.h +efi/mem.h +# Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ сборки +build/ +*.o +*.6 *.5 *.8 *.v *.q *.k +*.out +efi/bootx64.efi +efi/*.img +y.tab.* diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..d00feff --- /dev/null +++ b/NOTICE @@ -0,0 +1,22 @@ +plan9-kencc-linux β€” авторство ΠΈ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ +======================================== + +Наш ΠΊΠΎΠ΄ (сборочныС скрипты, efi/hello.c, efi/efi_build.sh, efi/mkesp.py, +efi/fetch_ref.sh, докумСнтация) β€” свободно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅. + +БобираСтся ΠΈΠ· стороннСго ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ НЕ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ, Π° тянСтся +скриптами: + +* ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€Ρ‹/ассСмблСры/Π»ΠΈΠ½ΠΊΠ΅Ρ€Ρ‹ Plan 9 (kencc) ΠΈ систСмныС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ β€” + ΠΈΠ· Π΄Π΅Ρ€Π΅Π²Π° исходников Plan 9 (plan9foundation / совмСстимого). + ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ Plan 9 (MIT-style, Ρ€Π°Π½Π΅Π΅ Lucent Public License). + +* Π’ΡƒΠ»Ρ‡Π΅ΠΉΠ½-обвязка lib9/libbio/libmach ΠΈ 9c/9l/9ar/yacc β€” plan9port + (https://github.com/9fans/plan9port), Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ plan9port. + +* РСфСрСнсный EFI-Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ (pe64.s, efi.h, mem.h) β€” 9legacy, nboot/efi + (http://9legacy.org/9legacy/patch/nboot.diff). ВянСтся efi/fetch_ref.sh, + Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ НЕ хранится. ЛицСнзия β€” ΠΊΠ°ΠΊ Ρƒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° Plan 9. + +Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Π±ΠΈΠ½Π°Ρ€ΠΈ Π² bin/ собраны ΠΈΠ· Π²Ρ‹ΡˆΠ΅ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… исходников нашими скриптами +ΠΈ Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ ΠΈΡ… Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ. diff --git a/PATCHES.md b/PATCHES.md new file mode 100644 index 0000000..f8b20aa --- /dev/null +++ b/PATCHES.md @@ -0,0 +1,58 @@ +# ΠŸΠ°Ρ‚Ρ‡ΠΈ ΠΏΠΎΠ΄ сборку kencc Π½Π° Linux-хостС + +ВсС ΠΏΡ€Π°Π²ΠΊΠΈ автоматичСски Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°ΡŽΡ‚ΡΡ `scripts/build_arch.sh` ΠΈ `build_al.sh` +Π½Π° свСТиС ΠΊΠΎΠΏΠΈΠΈ исходников (ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ Π½Π΅ трогаСтся). НиТС β€” Ρ‡Ρ‚ΠΎ ΠΈ Π·Π°Ρ‡Π΅ΠΌ. + +## 1. `round` / `log2` β†’ `p9round` / `p9log2` +`cc/` опрСдСляСт свои `round()` ΠΈ `log2()`, ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ с ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ°ΠΌΠΈ +ΠΈΠ· musl `math.h`. ΠŸΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Ρ‹Π²Π°Π΅ΠΌ опрСдСлСния ΠΈ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π²ΠΎ всСх Ρ„Π°ΠΉΠ»Π°Ρ… (ΠΈ Π² +сгСнСрённом `y.tab.c`). Π€Π°ΠΉΠ»Ρ‹: `cc/dcl.c`, `cc/pgen.c`, `cc/sub.c`, `cc/cc.h`, +`Xc/swt.c`, `Xc/cgen.c`. + +## 2. ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ ΠΈ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½ΠΎΡΡ‚ΡŒ `#include "y.tab.h"` +`y.tab.h` (Π³Π΅Π½Π΅Ρ€ΠΈΡ‚ yacc) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ `Node`, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ Π² `cc.h`, ΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ +include-guard. Π—Π½Π°Ρ‡ΠΈΡ‚: Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ строго ΠŸΠžΠ‘Π›Π• `cc.h` ΠΈ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· (ΠΈΠ½Π°Ρ‡Π΅ +ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ пСрСопрСдСлСния `YYSTYPE`/`yylval`). Π’ свСТСм `lex.c` порядок ΡƒΠΆΠ΅ +Π²Π΅Ρ€Π½Ρ‹ΠΉ β€” ΠΏΡ€Π°Π²ΠΊΠ° Π½ΡƒΠΆΠ½Π° Π±Ρ‹Π»Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Ρ€ΡƒΡ‡Π½ΠΎΠΉ Π²ΠΎΠ·Π½Π΅. + +## 3. Плоская раскладка include +Π˜ΡΡ…ΠΎΠ΄Π½ΠΈΠΊΠΈ ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ Π½Π° сосСдниС ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ: `#include "../cc/cc.h"`, +`"../6c/6.out.h"`, `"../8l/elf.h"`, extension-less `"compat"`, `"macbody"`, +`"lexbody"`. Π‘ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅ΠΌ всё Π² ΠΎΠ΄ΠΈΠ½ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ сборки ΠΈ срСзаСм `../*/` ΠΈΠ· include. +Extension-less Ρ„Π°ΠΉΠ»Ρ‹ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ явно. + +## 4. `Runemask` +Плановская libc-константа `Runemask` (маска 21-Π±ΠΈΡ‚Π½ΠΎΠΉ Ρ€ΡƒΠ½Ρ‹) Π΅ΡΡ‚ΡŒ Π² Ρ€ΠΎΠ΄Π½ΠΎΠΉ Plan9, +Π½ΠΎ НЕ Π² plan9port. ДобавляСм `#define Runemask 0x1FFFFF` Π² `lex.c`. + +## 5. ΠŸΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ `swcmp` β†’ `const` +`swcmp` β€” ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€ для `qsort`. Π£ musl сигнатура `int(const void*, const void*)`, +Π° плановский ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π² `gc.h` β€” `int(void*, void*)`. ΠŸΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ ΠΊ `const`. + +## 6. `-fcommon` +Π‘Ρ‚Π°Ρ€Ρ‹ΠΉ ΠΊΠΎΠ΄ Π΄Π΅Ρ€ΠΆΠΈΡ‚ tentative-Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΠΈ Π³Π»ΠΎΠ±Π°Π»ΠΎΠ² (Π½Π°ΠΏΡ€. `hintabsize` Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… +`.c` Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±Ρ‰ΠΈΠΉ `gc.h`). Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ gcc ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ `-fno-common` ΠΈ ругаСтся Π½Π° +multiple definition. ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌ с `-fcommon` (ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅). + +## 7. `mysbrk`: `sbrk()` β†’ `mmap()` ← ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΉ +Hunk-Π°Π»Π»ΠΎΠΊΠ°Ρ‚ΠΎΡ€ kencc Π±Π΅Ρ€Ρ‘Ρ‚ ΠΏΠ°ΠΌΡΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `mysbrk` β†’ `sbrk()`. На musl `sbrk()` +Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ `-1` (Π½Π΅ поддСрТиваСтся совмСстно с malloc), ΠΈΠ·-Π·Π° Ρ‡Π΅Π³ΠΎ `gethunk()` +ΠΏΠ°Π΄Π°Π» Π² Β«out of memoryΒ» β†’ `exits`, ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ диагностика ΡƒΡ…ΠΎΠ΄ΠΈΠ»Π° Π² Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ +Bio-Π±ΡƒΡ„Π΅Ρ€ ΠΈ Ρ‚Π΅Ρ€ΡΠ»Π°ΡΡŒ (компилятор ΠΌΠΎΠ»Ρ‡Π° Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠ» с ΠΊΠΎΠ΄ΠΎΠΌ 1). ЗамСняСм Ρ‚Π΅Π»ΠΎ `mysbrk` +Π½Π° Π°Π½ΠΎΠ½ΠΈΠΌΠ½Ρ‹ΠΉ `mmap`. Π‘Π΅Π· этого ΠΏΠ°Ρ‚Ρ‡Π° компиляторы Π»ΠΈΠ½ΠΊΡƒΡŽΡ‚ΡΡ, Π½ΠΎ Π½Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚. + +## 8. Π”ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚ `machcap` / `omachcap` +`cc/omachcap.c` (старый machcap) ΠΈ `Xc/machcap.c` (Π½ΠΎΠ²Ρ‹ΠΉ) ΠΎΠ±Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ `machcap`. +Π’ Ρ€ΠΎΠ΄Π½ΠΎΠΉ сборкС `omachcap.o` Π΄Ρ€Π΅ΠΌΠ»Π΅Ρ‚ Π² Π°Ρ€Ρ…ΠΈΠ²Π΅ `cc.a` ΠΈ Π½Π΅ тянСтся. Π£ нас β€” Π»ΠΈΠ½ΠΊΡƒΠ΅ΠΌ +плоско, поэтому: Ссли Ρƒ Π°Ρ€ΠΊΠΈ Π΅ΡΡ‚ΡŒ свой `machcap.o` (6c/8c/qc) β€” Π²Ρ‹ΠΊΠΈΠ΄Ρ‹Π²Π°Π΅ΠΌ +`omachcap.o`; Ссли Π½Π΅Ρ‚ (5c/vc/kc) β€” `omachcap.o` ΠΈ прСдоставляСт `machcap`. + +## 9. ПлановскиС Ρ€Π°Π½Ρ‚Π°ΠΉΠΌ-Ρ„Π°ΠΉΠ»Ρ‹ Π²ΠΎΠ½ +Π€Π°ΠΉΠ»Ρ‹ Π²Ρ€ΠΎΠ΄Π΅ `Xc/sys.c` тянут `#include "/sys/src/libc/9syscall/sys.h"` β€” это +Ρ€Π°Π½Ρ‚Π°ΠΉΠΌ ОБ, Π½Π΅ Ρ‡Π°ΡΡ‚ΡŒ компилятора, ΠΈ Π² `OFILES` mkfile ΠΈΡ… Π½Π΅Ρ‚. Π’Ρ‹ΠΊΠΈΠ΄Ρ‹Π²Π°Π΅ΠΌ Π»ΡŽΠ±Ρ‹Π΅ +`.c` с include ΠΏΠΎ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠΌΡƒ `/sys/...`. + +## 10. ΠΠ²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΎΡΡ‚ΡŒ `cc/` ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π΅ ΠΈΠΌΡ‘Π½ (kc) +Π£ `kc` завалялся собствСнный ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠΉ `bits.c`, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΡƒΠΆΠ΅ Π²Ρ‹Ρ€Π΅Π·Π°Π½Π½Ρ‹ΠΉ ΠΈΠ· +plan9port Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ `Fconv`. ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ `cc/`-Ρ„Π°ΠΉΠ»Ρ‹ ΠŸΠžΠ‘Π›Π• Π°Ρ€ΠΎΡ‡Π½Ρ‹Ρ…, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ‰ΠΈΠΉ +`cc/bits.c` (Π½ΠΎΠ²Ρ‹ΠΉ fmt API) ΠΏΠΎΠ±Π΅ΠΆΠ΄Π°Π». diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba80bb4 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# plan9-kencc-linux + +ΠšΡ€ΠΎΡΡ-сборка **компиляторов / ассСмблСров / Π»ΠΈΠ½ΠΊΠ΅Ρ€ΠΎΠ² Plan 9 (kencc)** для всСх +Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€ **с Linux-хоста**, плюс Π±ΠΎΠ»Π²Π°Π½ΠΎΡ‡Π½ΠΎΠ΅ **UEFI-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅** (PE32+), +собранноС этим ΠΆΠ΅ Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½ΠΎΠΌ. НичСго юниксового Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ сборки самих `.efi`. + +Π‘ΠΎΠ±Ρ€Π°Π½ΠΎ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ Π½Π° Linux/musl. Пилилось Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-Π±ΠΎΡ‚ΠΎΠΌ (Claude) ΠΏΠΎ Π·Π°ΠΊΠ°Π·Ρƒ +Ρ‡Π°Ρ‚Π° ancap.in.ua. + +## Π§Ρ‚ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ +``` +bin/ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Π±ΠΈΠ½Π°Ρ€ΠΈ: 8c 6c 5c vc qc kc (компиляторы) + 6a 6l +scripts/ + setup.sh ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΠ΅Ρ‚ plan9foundation + plan9port, собираСт plan9port + build_arch.sh собираСт C-компилятор Π°Ρ€ΠΊΠΈ X (5|6|8|v|q|k) + build_al.sh собираСт ассСмблСр/Π»ΠΈΠ½ΠΊΠ΅Ρ€ + build_all.sh собираСт вСсь кросс-ΠΊΠΈΡ‚ +efi/ + hello.c сам EFI-Π°ΠΏΠΏ (наш ΠΊΠΎΠ΄) + fetch_ref.sh тянСт pe64.s/efi.h/mem.h ΠΈΠ· 9legacy (nboot/efi) + efi_build.sh 6a+6c+6l -> dd -> bootx64.efi (PE32+) + mkesp.py Π·Π°Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ .efi Π² Π·Π°Π³Ρ€ΡƒΠ·ΠΎΡ‡Π½Ρ‹ΠΉ ESP (FAT16) +patches/ ΠΏΠ°Ρ‚Ρ‡ΠΈ ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡ€Π°Π²ΠΊΠ΅ (докумСнтация) +PATCHES.md ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠ°Ρ‚Ρ‡ Π½ΡƒΠΆΠ΅Π½ +``` + +## ИдСя +Π€Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-компилятора Plan 9 (`cc/`) + ΠΊΠΎΠ΄ΠΎΠ³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π°Ρ€ΠΎΠΊ (`5c`,`6c`,`8c`,`vc`,`qc`,`kc`) +ΠΏΠΈΡˆΡƒΡ‚ΡΡ Π½Π° Plan 9 C ΠΈ рассчитаны Π½Π° Ρ€ΠΎΠ΄Π½ΡƒΡŽ сборку Π² Plan 9. ΠœΡ‹ собираСм ΠΈΡ… Π½Π° Linux, +компилируя **plan9port**-овским `9c`/`9l` (ΠΎΠ½ΠΈ Π΄Π°ΡŽΡ‚ `lib9`/`libbio`/`libmach` ΠΈ +Π΄Ρ€ΡƒΠΆΠ°Ρ‚ с хостовым gcc/musl). Всё, Ρ‡Ρ‚ΠΎ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚, лСчится нСбольшими ΠΏΠ°Ρ‚Ρ‡Π°ΠΌΠΈ (см. `PATCHES.md`). + +| Π°Ρ€ΠΊΠ° | ΠΊΠΎΠΌΠΏ | ассСмблСр | Π»ΠΈΠ½ΠΊΠ΅Ρ€ | +|------|------|-----------|--------| +| 386 | 8c | 8a | 8l | +| amd64 | 6c | 6a | 6l | +| arm | 5c | 5a | 5l | +| mips | vc | va | vl | +| power | qc | qa | ql | +| sparc | kc | ka | kl | + +## Быстрый старт +```sh +# 1. зависимости (plan9foundation + plan9port) +bash scripts/setup.sh +export PLAN9SRC=$PWD/deps/plan9foundation +export PLAN9PORT=$PWD/deps/plan9port +# (ΠΎΠΏΡ†. musl: export MUSL_ENV=/path/to/env.sh) + +# 2. ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ всё +bash scripts/build_all.sh # -> build/*/{6c,6a,6l,...} + +# 3. ΠΎΠ΄ΠΈΠ½ компилятор +bash scripts/build_arch.sh 6 # -> build/6c/6c + +# 4. ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ +echo 'int f(void){return 42;}' > t.c +build/6c/6c t.c && ls t.6 # ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΈΠΊ Plan9 .6 +``` + +## EFI-Π±ΠΎΠ»Π²Π°Π½ΠΊΠ° +```sh +cd efi +./fetch_ref.sh # pe64.s/efi.h/mem.h ΠΈΠ· 9legacy +PLAN9SRC=$PWD/../deps/plan9foundation ./efi_build.sh +# -> bootx64.efi : PE32+ x64 EFI_APPLICATION +python3 mkesp.py bootx64.efi esp.img # -> Π·Π°Π³Ρ€ΡƒΠ·ΠΎΡ‡Π½Ρ‹ΠΉ ESP (/EFI/BOOT/BOOTX64.EFI) +# запуск: qemu-system-x86_64 -bios OVMF.fd -drive format=raw,file=esp.img +``` + +## Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Π±ΠΈΠ½Π°Ρ€ΠΈ +Π’ `bin/` Π»Π΅ΠΆΠ°Ρ‚ ΡƒΠΆΠ΅ собранныС компиляторы/асм/Π»ΠΈΠ½ΠΊΠ΅Ρ€ (Linux/musl x86_64). +Под свой хост пСрСсобСри скриптами β€” Π±Π°ΠΉΡ‚-Π²-Π±Π°ΠΉΡ‚ воспроизводимо. + +Π›ΠΈΡ†Π΅Π½Π·ΠΈΠΈ ΠΈ авторство исходников β€” см. `NOTICE`. diff --git a/bin/5c b/bin/5c new file mode 100755 index 0000000..c1e6fcf Binary files /dev/null and b/bin/5c differ diff --git a/bin/6a b/bin/6a new file mode 100755 index 0000000..122bd1d Binary files /dev/null and b/bin/6a differ diff --git a/bin/6c b/bin/6c new file mode 100755 index 0000000..dfa9c13 Binary files /dev/null and b/bin/6c differ diff --git a/bin/6l b/bin/6l new file mode 100755 index 0000000..ee75a69 Binary files /dev/null and b/bin/6l differ diff --git a/bin/8c b/bin/8c new file mode 100755 index 0000000..c178f5f Binary files /dev/null and b/bin/8c differ diff --git a/bin/kc b/bin/kc new file mode 100755 index 0000000..1e44e92 Binary files /dev/null and b/bin/kc differ diff --git a/bin/qc b/bin/qc new file mode 100755 index 0000000..8980901 Binary files /dev/null and b/bin/qc differ diff --git a/bin/vc b/bin/vc new file mode 100755 index 0000000..574f14c Binary files /dev/null and b/bin/vc differ diff --git a/efi/README.md b/efi/README.md new file mode 100644 index 0000000..fa1cdd1 --- /dev/null +++ b/efi/README.md @@ -0,0 +1,35 @@ +# efi β€” Π±ΠΎΠ»Π²Π°Π½ΠΎΡ‡Π½Ρ‹ΠΉ UEFI-Π°ΠΏΠΏ Π½Π° ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½Π΅ Plan 9 + +МинимальноС `bootx64.efi` (amd64, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ **PE32+**), собранноС **Ρ‚ΠΎΠ»ΡŒΠΊΠΎ** +ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Plan 9 kencc `6a`/`6c`/`6l` β€” Π±Π΅Π· ΡŽΠ½ΠΈΠΊΡΠΎΠ²Ρ‹Ρ… компиляторов/Π»ΠΈΠ½ΠΊΠ΅Ρ€ΠΎΠ². + +## Π¦Π΅ΠΏΠΎΡ‡ΠΊΠ° +| шаг | ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° | Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ | +|-----|---------|-----------| +| 1 | **6a** | ассСмблируСт `pe64min.s` β€” DOS/PE32+ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ + entry + `eficall` | +| 2 | **6c** | ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ `hello.c` (плановскиС `` ΠΈ Ρ‚.Π΄.) | +| 3 | **6l** | Π»ΠΈΠ½ΠΊΡƒΠ΅Ρ‚ свободностоящий ΠΎΠ±Ρ€Π°Π· ΠΏΠΎ `-T0x8000` | +| 4 | `dd skip=40` | срСзаСт 40-Π±Π°ΠΉΡ‚Π½Ρ‹ΠΉ plan9 a.out Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ β†’ ΠΎΠ±Π½Π°ΠΆΠ°Π΅Ρ‚ PE32+ | + +`pe64.s` ΠΊΠ»Π°Π΄Ρ‘Ρ‚ DOS+PE32+ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ Π² тСкст-сСгмСнт; Π»ΠΈΠ½ΠΊΠ΅Ρ€ раскладываСт +ΠΎΠ±Ρ€Π°Π· ΠΎΡ‚ `IMAGEBASE`, Π° `dd` срСзаСт плановский Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ β€” остаётся чистый PE, +ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΠ° Π³Ρ€ΡƒΠ·ΠΈΡ‚ ΠΈΠ· `/EFI/BOOT/BOOTX64.EFI`. + +## Π‘Π±ΠΎΡ€ΠΊΠ° +```sh +./fetch_ref.sh # pe64.s/efi.h/mem.h ΠΈΠ· 9legacy +PLAN9SRC=.../plan9foundation ./efi_build.sh # -> bootx64.efi +python3 mkesp.py bootx64.efi esp.img # -> Π·Π°Π³Ρ€ΡƒΠ·ΠΎΡ‡Π½Ρ‹ΠΉ ESP (FAT16) +qemu-system-x86_64 -bios OVMF.fd -drive format=raw,file=esp.img +``` + +## Π§Ρ‚ΠΎ своё, Ρ‡Ρ‚ΠΎ рСфСрСнс +* `hello.c`, `efi_build.sh`, `mkesp.py`, `fetch_ref.sh` β€” наш ΠΊΠΎΠ΄. +* `pe64.s`, `efi.h`, `mem.h` β€” ΠΈΠ· 9legacy `nboot/efi` (тянутся, Π½Π΅ хранятся). + Для Π±ΠΎΠ»Π²Π°Π½ΠΊΠΈ ΠΎΡ‚ `pe64.s` Π±Π΅Ρ€Ρ‘ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ+entry+`eficall` (`head -162`); + ΠΌΠ°ΡˆΠΈΠ½Π΅Ρ€ΠΈΡŽ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ядра (`jump`/`_warp32`/`_gdt`) отбрасываСм β€” Π΅ΠΉ Ρ‚ΡƒΡ‚ Π½Π΅Ρ‡Π΅Π³ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ. + +## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° +`MZ` + `PE\0\0` + Machine `0x8664` + Magic `0x20B` (PE32+) + Subsystem `10` +(EFI_APPLICATION). `mkesp.py` Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ сам ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚ FAT ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈ свСряСт +`/EFI/BOOT/BOOTX64.EFI` Π±Π°ΠΉΡ‚-Π²-Π±Π°ΠΉΡ‚ с исходным `.efi`. diff --git a/efi/efi_build.sh b/efi/efi_build.sh new file mode 100644 index 0000000..51f0ff9 --- /dev/null +++ b/efi/efi_build.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚ Π±ΠΎΠ»Π²Π°Π½ΠΎΡ‡Π½Ρ‹ΠΉ bootx64.efi (PE32+) ΠŸΠžΠ Π’Π˜Π ΠžΠ’ΠΠΠΠ«Πœ Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½ΠΎΠΌ 6a/6c/6l. +# ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ: ./fetch_ref.sh (достаёт pe64.s/efi.h/mem.h ΠΈΠ· 9legacy). +# Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚: BINDIR с 6a/6c/6l (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡. ../bin) ΠΈ PLAN9SRC (плановскиС include). +set -e +cd "$(dirname "$0")" +BINDIR="${BINDIR:-$PWD/../bin}" +: "${PLAN9SRC:?export PLAN9SRC β€” Π½ΡƒΠΆΠ½Ρ‹ плановскиС include (amd64/include, sys/include)}" +IMAGEBASE=0x8000 +export objtype=amd64 + +[ -f pe64.s ] || { echo "Π½Π΅Ρ‚ pe64.s β€” сначала ./fetch_ref.sh"; exit 1; } +# ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ pe64: MZ+PE Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ + entry + eficall (Π±Π΅Π· Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ° ядра) +head -162 pe64.s > pe64min.s + +rm -f *.6 *.out bootx64.efi +echo "1) 6a pe64min.s"; "$BINDIR/6a" -DIMAGEBASE=$IMAGEBASE pe64min.s +echo "2) 6c hello.c"; "$BINDIR/6c" -I"$PLAN9SRC/amd64/include" -I"$PLAN9SRC/sys/include" hello.c +echo "3) 6l link"; "$BINDIR/6l" -l -s -R1 -T$IMAGEBASE -o bootx64.out pe64min.6 hello.6 +echo "4) dd strip 40b (plan9 a.out header) -> PE32+" +dd if=bootx64.out bs=1 skip=40 of=bootx64.efi 2>/dev/null + +echo "bootx64.efi: $(ls -la bootx64.efi | awk '{print $5}') Π±Π°ΠΉΡ‚" +python3 - <<'PY' +d=open('bootx64.efi','rb').read(); po=int.from_bytes(d[0x3c:0x40],'little'); o=po+24 +ok = d[:2]==b'MZ' and d[po:po+4]==b'PE\x00\x00' \ + and int.from_bytes(d[po+4:po+6],'little')==0x8664 \ + and int.from_bytes(d[o:o+2],'little')==0x20b \ + and int.from_bytes(d[o+68:o+70],'little')==10 +print("PE32+ x64 EFI_APPLICATION:", "OK" if ok else "BAD") +PY +echo "ESP-ΠΎΠ±Ρ€Π°Π·: python3 mkesp.py bootx64.efi esp.img" diff --git a/efi/fetch_ref.sh b/efi/fetch_ref.sh new file mode 100644 index 0000000..67b726b --- /dev/null +++ b/efi/fetch_ref.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# ВянСт ΠΈΠ· 9legacy рСфСрСнсный EFI-Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ (nboot/efi) ΠΈ достаёт ΠΈΠ· Π½Π΅Π³ΠΎ +# pe64.s (PE32+ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ°), efi.h ΠΈ mem.h. Π­Ρ‚ΠΎ НЕ наш ΠΊΠΎΠ΄ β€” это Plan9/9legacy, +# поэтому ΠΊΠ°Ρ‡Π°Π΅ΠΌ, Π° Π½Π΅ Ρ…Ρ€Π°Π½ΠΈΠΌ Π² Ρ€Π΅ΠΏΠ΅. Наш ΠΊΠΎΠ΄ β€” hello.c/efi_build.sh/mkesp.py. +set -e +cd "$(dirname "$0")" +echo ">> ΠΊΠ°Ρ‡Π°ΡŽ 9legacy nboot.diff ..." +python3 -c "import urllib.request; urllib.request.urlretrieve('http://9legacy.org/9legacy/patch/nboot.diff','nboot.diff')" +python3 - <<'PY' +import re +d=open('nboot.diff').read().splitlines() +want={'pe64.s','efi.h','mem.h'}; cur=None; buf=[]; out={} +for l in d: + m=re.match(r'^\+\+\+ .*/nboot/efi/(\S+)', l) + if m: + if cur: out[cur]='\n'.join(buf) + cur=m.group(1) if m.group(1) in want else None; buf=[]; continue + if cur is not None: + if l.startswith('--- '): out[cur]='\n'.join(buf); cur=None; continue + if l.startswith('+'): buf.append(l[1:]) +if cur: out[cur]='\n'.join(buf) +for k,v in sorted(out.items()): open(k,'w').write(v); print(' ΠΈΠ·Π²Π»Ρ‘ΠΊ', k, f'({len(v.splitlines())} строк)') +PY +echo ">> Π³ΠΎΡ‚ΠΎΠ²ΠΎ: pe64.s efi.h mem.h (рСфСрСнс 9legacy)" diff --git a/efi/hello.c b/efi/hello.c new file mode 100644 index 0000000..35cd86d --- /dev/null +++ b/efi/hello.c @@ -0,0 +1,52 @@ +/* + * Π‘ΠΎΠ»Π²Π°Π½ΠΎΡ‡Π½Ρ‹ΠΉ EFI-Π°ΠΏΠΏ для amd64 (bootx64.efi), PE32+. + * БобираСтся ΠŸΠžΠ Π’Π˜Π ΠžΠ’ΠΠΠΠ«Πœ Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½ΠΎΠΌ Plan9 (6c/6a/6l) Π½Π° Linux/musl: + * PE-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ entry -> pe64.s (ассСмблСр 6a), ΠΈΠ· 9legacy nboot/efi. + * ΠŸΠ΅Ρ‡Π°Ρ‚ΡŒ -> UEFI SIMPLE_TEXT_OUTPUT_PROTOCOL (efi.h ΠΈΠ· 9legacy). + * ΠšΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ Π²Ρ…ΠΎΠ΄Π° Π·Π°Π΄Π°Ρ‘Ρ‚ pe64.s: reloc ΠΊΠ»Π°Π΄Ρ‘Ρ‚ SystemTable, ΠΏΡ€Ρ‹Π³Π°Π΅Ρ‚ Π½Π° efimain(ih, st). + */ +#include +#include "efi.h" + +/* Π³Π»ΠΎΠ±Π°Π»Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΆΠ΄Ρ‘Ρ‚ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ (ΠΊΠ°ΠΊ Π² рСфСрСнсном efi.c) */ +EFI_HANDLE IH; +EFI_SYSTEM_TABLE *ST; + +/* Π²Ρ‹Π·ΠΎΠ² EFI-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎ MS-x64 ABI β€” Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² pe64.s */ +extern uintptr eficall(void *fn, ...); + +/* ΠΏΠ΅Ρ‡Π°Ρ‚ΡŒ ASCII-строки Ρ‡Π΅Ρ€Π΅Π· ConOut (ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ Π² UTF-16, \n -> \r\n) */ +static void +eputs(char *s) +{ + CHAR16 w[2]; + + w[1] = 0; + for(; *s; s++){ + if(*s == '\n'){ + w[0] = '\r'; + eficall(ST->ConOut->OutputString, ST->ConOut, w); + } + w[0] = (uchar)*s; + eficall(ST->ConOut->OutputString, ST->ConOut, w); + } +} + +void +efimain(EFI_HANDLE ih, EFI_SYSTEM_TABLE *st) +{ + IH = ih; + ST = st; + + eputs("\n"); + eputs("+--------------------------------------------------+\n"); + eputs("| Hello from a Plan 9 kencc EFI application |\n"); + eputs("| compiler/assembler/linker: 6c / 6a / 6l |\n"); + eputs("| cross-built on Linux/musl, wrapped as PE32+ |\n"); + eputs("+--------------------------------------------------+\n"); + eputs("\nefimain reached OK. Idling via BootServices->Stall.\n"); + + /* Π±ΠΎΠ»Π²Π°Π½ΠΊΠ°: просто крутимся, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΠ° Π½Π΅ считала нас ΡƒΠΏΠ°Π²ΡˆΠΈΠΌΠΈ */ + for(;;) + eficall(ST->BootServices->Stall, (UINTN)1000000); +} diff --git a/efi/mkesp.py b/efi/mkesp.py new file mode 100644 index 0000000..d9ab581 --- /dev/null +++ b/efi/mkesp.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΎΡ‡Π½Ρ‹ΠΉ ESP-ΠΎΠ±Ρ€Π°Π· (FAT16) c /EFI/BOOT/BOOTX64.EFI. +# Π‘Π΅Π· mtools/mkfs β€” Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΏΠΎ спСцификации FAT, плюс самопровСрка (ΠΎΠ±Ρ…ΠΎΠ΄ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ). +import struct, sys, os, math + +EFI = sys.argv[1] if len(sys.argv)>1 else "/data/work/chat_-1002129270612/plan9/build/efi/bootx64.efi" +OUT = sys.argv[2] if len(sys.argv)>2 else "/data/work/chat_-1002129270612/plan9/build/efi/esp.img" +data = open(EFI,"rb").read() + +BPS=512; SPC=1; RSVD=1; NFAT=2; ROOTENT=512; TOT=8192 +rootsecs=(ROOTENT*32+BPS-1)//BPS +tmp1=TOT-(RSVD+rootsecs); tmp2=256*SPC+NFAT +FATSZ=(tmp1+tmp2-1)//tmp2 +first_data=RSVD+NFAT*FATSZ+rootsecs +nclus=(TOT-first_data)//SPC +assert nclus>4085, f"стало Π±Ρ‹ FAT12 ({nclus} кластСров)" + +img=bytearray(TOT*BPS) +# --- boot sector / BPB --- +bs=img +bs[0:3]=b'\xEB\x3C\x90'; bs[3:11]=b'MSWIN4.1' +struct.pack_into(' cl2) +root_off=(RSVD+NFAT*FATSZ)*BPS +img[root_off:root_off+32]=dirent("EFI","",0x10,efi_cl,0) +# EFI dir (cl2): '.', '..', BOOT(dir->cl3) +o=clus_off(efi_cl) +img[o:o+32]=dirent(".","",0x10,efi_cl,0) +img[o+32:o+64]=dirent("..","",0x10,0,0) +img[o+64:o+96]=dirent("BOOT","",0x10,boot_cl,0) +# BOOT dir (cl3): '.', '..', BOOTX64.EFI(file->cl4) +o=clus_off(boot_cl) +img[o:o+32]=dirent(".","",0x10,boot_cl,0) +img[o+32:o+64]=dirent("..","",0x10,efi_cl,0) +img[o+64:o+96]=dirent("BOOTX64","EFI",0x20,file_cl,len(data)) +# Π΄Π°Π½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Π° +for i,c in enumerate(file_clusters): + chunk=data[i*BPS*SPC:(i+1)*BPS*SPC] + off=clus_off(c); img[off:off+len(chunk)]=chunk + +open(OUT,"wb").write(img) + +# --- Π‘ΠΠœΠžΠŸΠ ΠžΠ’Π•Π ΠšΠ: ΠΎΠ±ΠΎΠΉΡ‚ΠΈ FAT ΠΈ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŒ /EFI/BOOT/BOOTX64.EFI --- +im=open(OUT,"rb").read() +def rd(a,n): return im[a:a+n] +def fat(c): return struct.unpack_from('"; exit 1; } +X="${T:0:1}"; K="${T:1:1}" + +: "${PLAN9SRC:?ΡƒΠΊΠ°ΠΆΠΈ PLAN9SRC}"; : "${PLAN9PORT:?ΡƒΠΊΠ°ΠΆΠΈ PLAN9PORT}" +[ -n "$MUSL_ENV" ] && . "$MUSL_ENV" +export PLAN9="$PLAN9PORT"; export PATH="$PLAN9/bin:$PATH" +SRC="$PLAN9SRC/sys/src/cmd" +OUT="${OUT:-$PWD/build}"; B="$OUT/$T" + +rm -rf "$B"; mkdir -p "$B"; cd "$B" +cp "$SRC/$T"/* "$B"/ 2>/dev/null || true +cp "$SRC/${X}c"/*.h "$B"/ 2>/dev/null || true # X.out.h +cp "$SRC"/cc/compat "$SRC"/cc/macbody "$SRC"/cc/lexbody "$SRC"/cc/cc.h "$B"/ 2>/dev/null || true +if [ "$K" = "l" ]; then # Π»ΠΈΠ½ΠΊΠ΅Ρ€Ρƒ: ΠΈΠΌΠ΅Π½Π° ΠΎΠΏΠΊΠΎΠ΄ΠΎΠ² + ΠΎΠ±Ρ‰ΠΈΠΉ ELF-Π²Ρ‹Π²ΠΎΠ΄ + cp "$SRC/${X}c"/enam.c "$B"/ 2>/dev/null || true + cp "$SRC"/8l/elf.c "$SRC"/8l/elf.h "$B"/ 2>/dev/null || true +fi + +# ---- ΠΏΠ°Ρ‚Ρ‡ΠΈ (Ρ‚Π΅ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ для компиляторов) ---- +for c in *.c; do grep -qE '#include[ \t]*[<"]/sys/' "$c" 2>/dev/null && { echo " пропуск: $c"; rm -f "$c"; }; done +sed -i 's|"\.\./[a-zA-Z0-9]*/|"|g' *.c *.h 2>/dev/null || true +sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' *.c *.h compat macbody lexbody 2>/dev/null || true +python3 - <<'PY' +import glob,re +pat=re.compile(r'\{\s*return\s+sbrk\s*\(\s*(\w+)\s*\)\s*;\s*\}') +mm='''{ +\tvoid *p; +\tp = mmap(0, %s, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); +\tif(p == MAP_FAILED) return (void*)-1; +\treturn p; +}''' +for f in glob.glob('*')+['compat']: + try: s=open(f).read() + except: continue + if 'sbrk(' in s and 'mmap' not in s: + m=pat.search(s) + if m: + s2=pat.sub(mm%m.group(1), s, count=1) + if '#include ' not in s2: s2='#include \n'+s2 + open(f,'w').write(s2); print(" mmap-ΠΏΠ°Ρ‚Ρ‡:",f) +PY +[ -f a.y ] && { yacc -d a.y; sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' y.tab.c 2>/dev/null || true; } + +ok=0; fail=0; errf=""; rm -f *.o +for f in *.c; do + if 9c -fcommon -I. "$f" >/tmp/al_$$ 2>&1; then ok=$((ok+1)); else fail=$((fail+1)); [ -z "$errf" ] && errf="$f" && cp /tmp/al_$$ /tmp/alf_$$; fi +done +echo "[$T] компиляция: OK=$ok FAIL=$fail" +[ "$fail" != 0 ] && { echo "пСрвая ошибка ($errf):"; head -10 /tmp/alf_$$; exit 2; } + +if [ "$K" = "l" ]; then EXTRA="-lmach"; else EXTRA=""; fi # Π»ΠΈΠ½ΠΊΠ΅Ρ€Ρƒ Π½ΡƒΠΆΠ΅Π½ libmach +9l -o "$T" *.o $EXTRA +echo "[$T] Π±ΠΈΠ½Π°Ρ€ΡŒ: $(ls -la $T | awk '{print $5}') Π±Π°ΠΉΡ‚ -> $B/$T" diff --git a/scripts/build_all.sh b/scripts/build_all.sh new file mode 100644 index 0000000..7f058aa --- /dev/null +++ b/scripts/build_all.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚ Π’Π•Π‘Π¬ кросс-ΠΊΠΈΡ‚: C-компиляторы + ассСмблСры + Π»ΠΈΠ½ΠΊΠ΅Ρ€Ρ‹ всСх Π°Ρ€ΠΎΠΊ. +# Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ экспортированных PLAN9SRC ΠΈ PLAN9PORT (см. setup.sh). +set -e +here="$(cd "$(dirname "$0")" && pwd)" +: "${PLAN9SRC:?export PLAN9SRC (см. scripts/setup.sh)}" +: "${PLAN9PORT:?export PLAN9PORT (см. scripts/setup.sh)}" +export OUT="${OUT:-$PWD/build}" + +echo "=== C-компиляторы ===" +for X in 5 6 8 v q k; do bash "$here/build_arch.sh" $X; done +echo "=== ассСмблСры ===" +for X in 5 6 8 v q k; do bash "$here/build_al.sh" ${X}a || echo " (${X}a β€” ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½/ошибка)"; done +echo "=== Π»ΠΈΠ½ΠΊΠ΅Ρ€Ρ‹ ===" +for X in 5 6 8 v q k; do bash "$here/build_al.sh" ${X}l || echo " (${X}l β€” ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½/ошибка)"; done + +echo +echo "=== собранныС Π±ΠΈΠ½Π°Ρ€ΠΈ ($OUT) ===" +find "$OUT" -maxdepth 2 -type f -perm -u+x \( -name '[0-9kvq][cal]' \) -printf '%f %s Π±Π°ΠΉΡ‚\n' 2>/dev/null | sort diff --git a/scripts/build_arch.sh b/scripts/build_arch.sh new file mode 100644 index 0000000..3cdc4fb --- /dev/null +++ b/scripts/build_arch.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚ Plan9 kencc C-компилятор для Π°Ρ€ΠΊΠΈ X (5,6,8,v,q,k) Π½Π° Linux-хостС. +# ИспользованиС: PLAN9SRC=.../plan9foundation PLAN9PORT=.../plan9port build_arch.sh 6 +# ΠžΠΏΡ†.: MUSL_ENV=.../env.sh (Π°ΠΊΡ‚ΠΈΠ²Π°Ρ‚ΠΎΡ€ musl-Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½Π°), OUT=ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ сборки. +set -e +X="$1"; [ -z "$X" ] && { echo "usage: $0 "; exit 1; } +A="${X}c" + +: "${PLAN9SRC:?ΡƒΠΊΠ°ΠΆΠΈ PLAN9SRC β€” Π΄Π΅Ρ€Π΅Π²ΠΎ исходников plan9 (plan9foundation)}" +: "${PLAN9PORT:?ΡƒΠΊΠ°ΠΆΠΈ PLAN9PORT β€” собранный plan9port (bin/9c,9l,9ar,yacc + lib/)}" +[ -n "$MUSL_ENV" ] && . "$MUSL_ENV" +export PLAN9="$PLAN9PORT"; export PATH="$PLAN9/bin:$PATH" +SRC="$PLAN9SRC/sys/src/cmd" +OUT="${OUT:-$PWD/build}" +B="$OUT/$A" + +rm -rf "$B"; mkdir -p "$B"; cd "$B" +# ΠΊΠΎΠ΄ΠΎΠ³Π΅Π½ Π°Ρ€ΠΊΠΈ БНАЧАЛА, ΠΏΠΎΡ‚ΠΎΠΌ Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄ cc/ β€” cc/ Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π΅Π½ ΠΏΡ€ΠΈ совпадСнии ΠΈΠΌΡ‘Π½ +# (Ρƒ kc свой ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠΉ bits.c с Fconv β€” Π±Π΅Ρ€Ρ‘ΠΌ cc/bits.c) +cp "$SRC/$A"/*.c "$SRC/$A"/*.h "$B"/ +cp "$SRC"/cc/*.c "$SRC"/cc/*.h "$B"/ +cp "$SRC"/cc/compat "$SRC"/cc/macbody "$SRC"/cc/lexbody "$B"/ 2>/dev/null || true + +# ---- ПАВЧИ ΠΏΠΎΠ΄ линукс-хост ---- +# 0) Π²Ρ‹ΠΊΠΈΠ½ΡƒΡ‚ΡŒ плановскиС Ρ€Π°Π½Ρ‚Π°ΠΉΠΌ-Ρ„Π°ΠΉΠ»Ρ‹ (тянут /sys/... Ρ…Π΅Π΄Π΅Ρ€Ρ‹, Π½Π΅ Ρ‡Π°ΡΡ‚ΡŒ компилятора) +for c in *.c; do grep -qE '#include[ \t]*[<"]/sys/' "$c" 2>/dev/null && { echo " пропуск Ρ€Π°Π½Ρ‚Π°ΠΉΠΌ: $c"; rm -f "$c"; }; done +# 1) плоская раскладка: ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ../cc/ ../Xc/ +sed -i "s|\"\.\./cc/|\"|g; s|\"\.\./${A}/|\"|g" *.c *.h 2>/dev/null || true +# 2) round/log2 ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΡƒΡŽΡ‚ с musl math.h -> p9round/p9log2 +sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' *.c *.h compat macbody lexbody 2>/dev/null || true +# 3) Runemask Π½Π΅Ρ‚ Π² plan9port +grep -q 'define Runemask' lex.c || sed -i '/#include[ \t]*"y.tab.h"/a #ifndef Runemask\n#define Runemask 0x1FFFFF\n#endif' lex.c +# 3b) ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ swcmp -> const (musl qsort-ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€) +sed -i 's/swcmp(void\*, *void\*)/swcmp(const void*, const void*)/' gc.h *.h 2>/dev/null || true +# 4) mysbrk: sbrk() Π½Π° musl ΠΎΡ‚Π΄Π°Ρ‘Ρ‚ -1 -> mmap +python3 - "$B/compat" <<'PY' +import sys +p=sys.argv[1]; s=open(p).read() +old='void*\nmysbrk(ulong size)\n{\n\treturn sbrk(size);\n}' +new='''#include +void* +mysbrk(ulong size) +{ +\tvoid *p; +\tp = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); +\tif(p == MAP_FAILED) return (void*)-1; +\treturn p; +}''' +if old in s: open(p,'w').write(s.replace(old,new)); print(" mmap-ΠΏΠ°Ρ‚Ρ‡: ΠΎΠΊ") +else: print(" mmap-ΠΏΠ°Ρ‚Ρ‡: ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½") +PY + +# ---- yacc: cc.y -> y.tab.c / y.tab.h ---- +yacc -d cc.y 2>/dev/null || yacc -d "$SRC/cc/cc.y" +sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' y.tab.c 2>/dev/null || true + +# ---- компиляция (-fcommon: tentative-Π³Π»ΠΎΠ±Π°Π»Ρ‹ ΠΏΠΎΠ΄ gcc -fno-common) ---- +ok=0; fail=0; errf=""; rm -f *.o +for f in *.c; do + if 9c -fcommon -I. "$f" >/tmp/ba_$$ 2>&1; then ok=$((ok+1)); else fail=$((fail+1)); [ -z "$errf" ] && errf="$f" && cp /tmp/ba_$$ /tmp/baf_$$; fi +done +echo "[$A] компиляция: OK=$ok FAIL=$fail" +[ "$fail" != 0 ] && { echo "пСрвая ошибка ($errf):"; head -8 /tmp/baf_$$; exit 2; } + +# ---- Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠ°: свой machcap.o -> Π²Ρ‹ΠΊΠΈΠ½ΡƒΡ‚ΡŒ omachcap.o; ΠΈΠ½Π°Ρ‡Π΅ omachcap ΠΈ Π΅ΡΡ‚ΡŒ machcap ---- +if [ -f machcap.o ]; then LINK=$(ls *.o | grep -v '^omachcap.o$'); else LINK=$(ls *.o); fi +9l -o "$A" $LINK +echo "[$A] Π±ΠΈΠ½Π°Ρ€ΡŒ: $(ls -la $A | awk '{print $5}') Π±Π°ΠΉΡ‚ -> $B/$A" diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100644 index 0000000..2d693f0 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Π“ΠΎΡ‚ΠΎΠ²ΠΈΡ‚ зависимости для сборки Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½Π°: исходники plan9 + собранный plan9port. +# ВрСбуСтся: git, gcc/clang, make, yacc (ΠΈΠ»ΠΈ plan9port-овский). ΠšΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ кладутся +# рядом со скриптом (ΠΈΠ»ΠΈ Π² $DEPS). ПослС β€” экспортни PLAN9SRC/PLAN9PORT (ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ Π² ΠΊΠΎΠ½Ρ†Π΅). +set -e +DEPS="${DEPS:-$PWD/deps}" +mkdir -p "$DEPS"; cd "$DEPS" + +# 1) Π΄Π΅Ρ€Π΅Π²ΠΎ исходников plan9 (plan9foundation β€” Ρ‚ΡƒΡ‚ ΠΆΠΈΠ²ΡƒΡ‚ cc/ ΠΈ Xc/Xa/Xl) +if [ ! -d plan9foundation ]; then + echo ">> ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΡŽ plan9foundation ..." + git clone --depth 1 https://github.com/plan9foundation/plan9.git plan9foundation \ + || git clone --depth 1 https://git.9front.org/plan9front/plan9front plan9foundation +fi + +# 2) plan9port (Π΄Π°Ρ‘Ρ‚ 9c/9l/9ar/yacc + lib9/libbio/libmach β€” ΠΈΠΌΠΈ ΠΈ собираСм kencc) +if [ ! -d plan9port ]; then + echo ">> ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΡŽ plan9port ..." + git clone --depth 1 https://github.com/9fans/plan9port.git plan9port +fi +if [ ! -x plan9port/bin/9c ]; then + echo ">> ΡΠΎΠ±ΠΈΡ€Π°ΡŽ plan9port (ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΡΡ‚ΡŒ ΠΏΠ°Ρ€Ρƒ ΠΌΠΈΠ½ΡƒΡ‚) ..." + ( cd plan9port && ./INSTALL -b ) # -b: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ, Π±Π΅Π· установки Π² систСму +fi + +echo +echo "Π“ΠΎΡ‚ΠΎΠ²ΠΎ. Экспортни:" +echo " export PLAN9SRC=$DEPS/plan9foundation" +echo " export PLAN9PORT=$DEPS/plan9port" +echo " # Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΡˆΡŒ musl-Ρ‚ΡƒΠ»Ρ‡Π΅ΠΉΠ½: export MUSL_ENV=/path/to/env.sh" -- cgit v1.2.3