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 --- efi/mkesp.py | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 efi/mkesp.py (limited to 'efi/mkesp.py') 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('