2.11BSD_X44
2025-02-19 12:35Один крутой чувак из Австралии взялся развивать 2.11BSD для архитектуры i386.
github.com/TheSledgeHammer/2.11BSD_X44
github.com/TheSledgeHammer/2.11BSD_X44
Обратите внимание: работают ассемблер и Си компилятор.$ qemu-pic32 -machine pic32mx7-max32 -nographic -monitor none -serial stdio -bios boot-max32.hex -kernel unix.hex -sd retrobsd.img
Board: chipKIT Max32
Processor: M4K
RAM size: 128 kbytes
Load file: 'boot-max32.hex', 6720 bytes
Load file: 'unix.hex', 141140 bytes
Card0 image 'retrobsd.img', 102401 kbytes
2.11 BSD Unix for PIC32, revision G512 build 3:
Compiled 2025-02-07 by vak@bumba:
/home/vak/Project/BSD/retrobsd/sys/pic32/max32
cpu: 795F512L 80 MHz, bus 80 MHz
oscillator: HS crystal, PLL div 1:2 mult x20
spi2: pins sdi=RG7/sdo=RG8/sck=RG6
uart1: pins rx=RF2/tx=RF8, interrupts 26/27/28, console
uart2: pins rx=RF4/tx=RF5, interrupts 40/41/42
uart4: pins rx=RD14/tx=RD15, interrupts 67/68/69
sd0: port SPI2, pin cs=RC14
gpio0: portA, pins ii---ii-iiiioiii
gpio1: portB, pins iiiiiiiiiiiiiiii
gpio2: portC, pins i-ii-------iiii-
gpio3: portD, pins --iiiiiiiiiiiiii
gpio4: portE, pins ------iiiiiiiiii
gpio5: portF, pins --ii--------i-ii
gpio6: portG, pins iiii--i-----iiii
adc: 15 channels
pwm: 5 channels
sd0: type I, size 102400 kbytes, speed 10 Mbit/sec
sd0a: partition type b7, sector 2, size 102400 kbytes
sd0b: partition type b8, sector 204802, size 2048 kbytes
sd0c: partition type b7, sector 208898, size 102400 kbytes
phys mem = 128 kbytes
user mem = 96 kbytes
root dev = (0,1)
swap dev = (0,2)
root size = 102400 kbytes
swap size = 2048 kbytes
/dev/sd0a: 1444 files, 12342 used, 89657 free
Starting daemons: update cron
2.11 BSD UNIX (pic32) (console)
login: root
Password:
Welcome to RetroBSD!
erase ^?, kill ^U, intr ^C
# date
Sun Jan 24 23:08:07 PST 2016
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/sd0a 101999 12345 89654 12% /
# ps aux
USER PID NICE SZ TTY TIME COMMAND
root 0 0 3 ? 0:00 swapper
root 1 0 35 ? 0:00 init -
root 10 0 7 ? 0:00 update
root 12 0 54 ? 0:00 cron
root 13 0 39 0 0:00 -sh
root 17 0 42 0 0:00 ps aux
# ls /bin
[ crontab hostname pagesize size uucico
adb date id passwd sl uuclean
adc-demo dc iostat pdc sleep uucp
aout dd join picoc smux uudecode
apropos df kill portio sort uuencode
ar diff la pr split uulog
as diskspeed last printenv strip uuname
awk du lcc printf stty uupoll
basename echo lcpp ps su uuq
basic ed ld pwd sum uusend
bc egrep ln pwm sx uusnap
cal emg login ranlib sync uux
calendar env lol rb sysctl uuxqt
cat expr ls re sz vi
cb false mail renice tail vmstat
cc fgrep make renumber tar w
chat-server file man retroforth tee wall
chflags find md5 rev telnet wc
chfn fold med rm test web-client
chgrp forth mesg rmail time web-server
chmod fstat mkdir rmdir tip whatis
chpass glcdtest more rx touch whereis
chsh globdump msec rz tr who
cmp globread mv sb true whoami
col globwrite nice scc tsort write
comm grep nm scm tty xargs
compress groups nohup sed uname zcat
cp head ntpdate setty uncompress
cpp hostid od sh uniq
# cd /share/examples/asm
# make clean
rm -f *.o ashello echo *.dis *~
# cat ashello.S
/*
* This is an example of MIPS assembly program for RetroBSD.
*
* To compile this program, type:
* cc -c ashello.S
* ld ashello.o -o ashello
*/
#include <syscall.h>
.data // begin data segment
hello: .ascii "Hello, assembly world!\n" // a string
.text // begin code segment
.globl start // entry point for ld
start:
li $a0, 0 // arg 1: stdout fd
la $a1, hello // arg 2: string address
li $a2, 23 // arg 3: string length
syscall SYS_write // call the kernel: write()
nop // returns here on error
nop // skips two words on success
li $a0, 0 // arg 1: exit status
syscall SYS_exit // call the kernel: exit()
// no return
# make ashello
cc -c ashello.S
ld ashello.o -o ashello
# ./ashello
Hello, assembly world!
# cd /share/examples/c
# make clean
rm -f *.o *~ hello stdarg skeleton primelist primesum test1 test2 test3 gpio adc rain q8 tetris lcd6
# cat hello.c
#include <stdio.h>
int main()
{
printf ("Hello, C World!\n");
return 0;
}
# make hello
cc -o hello hello.c
# ./hello
Hello, C World!
# halt
killing processes... done
syncing disks... done
halted
Теперь соберём и установим QEMU для pic32:wget http://ftp.debian.org/debian/pool/main/libf/libffi/libffi7_3.3-6_amd64.deb
wget http://ftp.debian.org/debian/pool/main/o/openssl/libssl1.1_1.1.1w-0+deb11u1_amd64.deb
wget http://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb
wget http://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb
wget http://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-stdlib_2.7.18-8+deb11u1_amd64.deb
wget http://ftp.debian.org/debian/pool/main/p/python2.7/python2.7_2.7.18-8+deb11u1_amd64.deb
sudo dpkg -i libffi7_3.3-6_amd64.deb \
libssl1.1_1.1.1w-0+deb11u1_amd64.deb \
libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb \
python2.7-minimal_2.7.18-8+deb11u1_amd64.deb \
libpython2.7-stdlib_2.7.18-8+deb11u1_amd64.deb \
python2.7_2.7.18-8+deb11u1_amd64.deb
Бинарник QEMU будет установлен как /usr/local/qemu-mips/bin/qemu-system-mipsel. Запустим LiteBSD:sudo apt install libpixman-1-dev libfdt-dev zlib1g-dev libglib2.0-dev libsdl1.2-dev
git clone https://github.com/sergev/qemu.git
mkdir qemu-build
cd qemu-build
../qemu/configure --prefix=/usr/local/qemu-mips \
--target-list=mipsel-softmmu \
--python=/usr/bin/python2.7 \
--disable-werror
make CFLAGS="-O3 -Wno-error -isystem /usr/include/glib-2.0 -isystem /usr/lib/$(uname -m)-linux-gnu/glib-2.0/include" -j "$(nproc)"
make install
Стартует классический юникс 30-летней давности:wget https://raw.githubusercontent.com/wiki/sergev/qemu/binaries/boot-wifire.hex
wget https://raw.githubusercontent.com/wiki/sergev/qemu/binaries/vmunix.hex
wget https://raw.githubusercontent.com/wiki/sergev/qemu/binaries/litebsd.zip
unzip litebsd.zip
/usr/local/qemu-mips/bin/qemu-system-mipsel \
-machine pic32mz-wifire \
-nographic \
-monitor none \
-serial vc \
-serial vc \
-serial vc \
-serial stdio \
-bios "boot-wifire.hex" \
-kernel "vmunix.hex" \
-sd "litebsd.img"
Заходите как root, без пароля. Остановить систему можно командой halt -q.Board: chipKIT WiFire
Processor: microAptivP
RAM size: 512 kbytes
Load file: 'boot-wifire.hex', 6916 bytes
Load file: 'vmunix.hex', 522408 bytes
Card0 image 'litebsd.img', 339969 kbytes
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
4.4BSD-Lite build 13 compiled 2015-01-20
sergev@ubuntu-sergev:LiteBSD/sys/compile/WIFIRE.pic32
cpu: PIC32MZ2048ECG100 rev A4, 200 MHz
oscillator: system PLL div 1:6 mult x50
real mem = 512 kbytes
avail mem = 344 kbytes
using 18 buffers containing 73728 bytes of memory
spi1 at pins sdi=D14/sdo=C1/sck=D1
spi2 at pins sdi=F0/sdo=D11/sck=G6
spi3 at pins sdi=B10/sdo=C4/sck=B14
spi4 at pins sdi=F5/sdo=G0/sck=D10
uart1 at pins rx=F1/tx=D15, interrupts 112/113/114
uart4 at pins rx=F2/tx=F8, interrupts 170/171/172, console
sd0 at port spi3, pin cs=C3
sd0: type I, size 339968 kbytes, speed 12 Mbit/sec
sd0a: partition type b7, sector 2, size 204800 kbytes
sd0b: partition type b8, sector 409602, size 32768 kbytes
sd0c: partition type b7, sector 475138, size 102400 kbytes
bpf: sl0 attached
bpf: lo0 attached
WARNING: preposterous clock chip time -- CHECK AND RESET THE DATE!
starting file system checks.
/dev/rsd0a: file system is clean; not checking
starting network
clearing /tmp
standard daemons: update.
Wed Dec 10 21:07:36 PST 2014
4.4BSD-Lite (bsd.net) (tty4)
login: _
Входим как root, без пароля. Смотрим версию ядра, размеры файловых систем, версию компилятора. Останавливается машина командой halt.qemu-system-i386 \
-cpu 486 \
-m 64M \
-rtc base=localtime \
-hda freebsd1.0.qcow \
-netdev user,id=ed1,ipv6=off,hostfwd=tcp::2222-:22 \
-device ne2k_isa,netdev=ed1,mac=00:00:0d:31:04:11,irq=5
qemu-system-i386 \
-cpu pentium \
-m 128M \
-rtc base=localtime \
-hda freebsd2.0.5.qcow \
-hdb hdb.qcow \
-hdc hdc.qcow \
-hdd hdd.qcow \
-netdev user,id=ed1,ipv6=off,hostfwd=tcp::2222-:22 \
-device ne2k_isa,netdev=ed1,mac=00:00:0d:31:04:11,irq=5
$ cpp foobar.S | as -o foobar.o - $ cpp lib.S | as -o lib.o - $ ld -shared -o lib.so lib.o $ ld -o foobar foobar.o lib.so $ export LD_LIBRARY_PATH=. $ bintrace ./foobar Starting program: ./foobar sp = 0xbfbfeb50 lr = 0x20025538 cpsr = 0x10 ----------------------------------------------------------- dynamic loader 0x20025538: e1a0600d mov r6, sp r6 = 0xbfbfeb50 ... (initialize dynamic loader) ... 0x20025590: e1a0f003 mov pc, r3 ----------------------------------------------------------- 00010158 <_start>: 0x00010158: e300017c movw r0, #0x17c r0 = 0x17c 0x0001015c: e3400001 movt r0, #1 r0 = 0x1017c 0x00010160: ebfffff9 bl #0x1014c lr = 0x10164 ----------------------------------------------------------- 0001014c <say@plt>: 0x0001014c: e28fc600 add ip, pc, #0, #12 r12 = 0x10154 0x00010150: e28cca01 add ip, ip, #0x1000 r12 = 0x11154 0x00010154: e5bcf0c4 ldr pc, [ip, #0xc4]! r12 = 0x11218 ----------------------------------------------------------- 00010138 <.plt>: 0x00010138: e52de004 str lr, [sp, #-4]! sp = 0xbfbfeb4c 0x0001013c: e59fe004 ldr lr, [pc, #4] lr = 0x10c4 0x00010140: e08fe00e add lr, pc, lr lr = 0x1120c 0x00010144: e5bef008 ldr pc, [lr, #8]! lr = 0x11214 ----------------------------------------------------------- into dynamic loader 0x200255a0: e92d0c3f push {r0, r1, r2, r3, r4, r5, sl, fp} sp = 0xbfbfeb2c ... (find symbol 'say' in lib.so) ... 0x200255d4: e1a0f00c mov pc, ip ----------------------------------------------------------- 000000d4 <say>: 0x200170d4: e92d4080 push {r7, lr} sp = 0xbfbfeb48 0x200170d8: e1a01000 mov r1, r0 r1 = 0x1017c 0x200170dc: e3a00001 mov r0, #1 r0 = 0x1 0x200170e0: e3a02004 mov r2, #4 r2 = 0x4 0x200170e4: e3a07004 mov r7, #4 r7 = 0x4 0x200170e8: ef000000 svc #0 foo r0 = 0x4 r1 = 0 0x200170ec: e8bd8080 pop {r7, pc} r7 = 0 sp = 0xbfbfeb50 ----------------------------------------------------------- back to _start 0x00010164: e3000180 movw r0, #0x180 r0 = 0x180 0x00010168: e3400001 movt r0, #1 r0 = 0x10180 0x0001016c: ebfffff6 bl #0x1014c lr = 0x10170 ----------------------------------------------------------- 0001014c <say@plt>: 0x0001014c: e28fc600 add ip, pc, #0, #12 r12 = 0x10154 0x00010150: e28cca01 add ip, ip, #0x1000 r12 = 0x11154 0x00010154: e5bcf0c4 ldr pc, [ip, #0xc4]! r12 = 0x11218 ----------------------------------------------------------- 000000d4 <say>: 0x200170d4: e92d4080 push {r7, lr} sp = 0xbfbfeb48 0x200170d8: e1a01000 mov r1, r0 r1 = 0x10180 0x200170dc: e3a00001 mov r0, #1 r0 = 0x1 0x200170e0: e3a02004 mov r2, #4 0x200170e4: e3a07004 mov r7, #4 r7 = 0x4 0x200170e8: ef000000 svc #0 bar r0 = 0x4 r1 = 0 0x200170ec: e8bd8080 pop {r7, pc} r7 = 0 sp = 0xbfbfeb50 ----------------------------------------------------------- back to _start 0x00010170: e3a07001 mov r7, #1 r7 = 0x1 0x00010174: e3a00000 mov r0, #0 r0 = 0 0x00010178: ef000000 svc #0 Process exited normally.
(2) Записать на карточку microSD посредством утилиты balenaEtcher или ещё как-нибудь.wget https://download.freebsd.org/releases/ISO-IMAGES/14.2/FreeBSD-14.2-RELEASE-arm-armv7-GENERICSD.img.xz
(4) Добыть оттуда бинарник загрузчика:wget https://pkg.freebsd.org/FreeBSD:14:aarch64/latest/All/u-boot-olinuxino-lime2-2024.07.pkg
(5) Записать загрузчик на ту же карточку microSD поверх образа FreeBSD. Здесь замените /dev/diskN на девайс карточки в вашей системе:tar xf u-boot-olinuxino-lime2-2024.07.pkg
mv usr/local/share/u-boot/u-boot-olinuxino-lime2/u-boot-sunxi-with-spl.bin .
После этого грузитесь с карточки и заходите в систему с консольного порта, юзер root, пароль root.dd if=u-boot-sunxi-with-spl.bin of=/dev/diskN bs=1k seek=8 conv=sync
$ bintrace ./demo-arm32-freebsd
Starting program: ./demo-arm32-freebsd
sp = 0xbfbfeb58
lr = 0x10054
cpsr = 0x10
0x00010054: e3a07004 mov r7, #4
r7 = 0x4
0x00010058: e3a00001 mov r0, #1
r0 = 0x1
0x0001005c: e3001078 movw r1, #0x78
r1 = 0x78
0x00010060: e3401001 movt r1, #1
r1 = 0x10078
0x00010064: e3a0200d mov r2, #0xd
r2 = 0xd
0x00010068: ef000000 svc #0
Hello world!
r0 = 0xd
r1 = 0
0x0001006c: e3a07001 mov r7, #1
r7 = 0x1
0x00010070: e3a00000 mov r0, #0
r0 = 0
0x00010074: ef000000 svc #0
Process exited normally.
Вход как root без пароля. Пакетов для RISC-V ещё нету, как я понимаю, поэтому командой pkg ничего установить не удаётся.wget https://download.freebsd.org/snapshots/VM-IMAGES/15.0-CURRENT/riscv64/Latest/FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.raw.xz
xz --decompress FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.raw.xz
qemu-img convert -f raw -O qcow2 FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.raw FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.qcow
qemu-img resize FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.qcow 16G
qemu-system-riscv64 \
-machine virt \
-nographic \
-m 2048M \
-smp 2 \
-bios fw_jump.elf \
-kernel u-boot.bin \
-drive file=FreeBSD-15.0-CURRENT-riscv-riscv64-ufs.qcow,if=none,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=net0,ipv6=off,hostfwd=tcp::8022-:22 \
-device virtio-net-device,netdev=net0
В нашем случае срабатывает именно последний вариант, когда в мантиссе 113 бит и максимальная экспонента равна 16384.#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
long double log10l(long double x)
{
return log10(x);
}
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
...собственно реализация функции...
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
// TODO: broken implementation to make things compile
long double log10l(long double x)
{
return log10(x);
}
#endif
То есть никто не тестировал эту библиотеку на компиляторе со 128-битным long double. Тут чинить и чинить.$ git clone https://git.musl-libc.org/git/musl
$ cd musl/src/math
$ grep TODO:\ broken *.c
acoshl.c:// TODO: broken implementation to make things compile
asinhl.c:// TODO: broken implementation to make things compile
coshl.c:// TODO: broken implementation to make things compile
erfl.c:// TODO: broken implementation to make things compile
expl.c:// TODO: broken implementation to make things compile
expm1l.c:// TODO: broken implementation to make things compile
lgammal.c:// TODO: broken implementation to make things compile
log10l.c:// TODO: broken implementation to make things compile
log1pl.c:// TODO: broken implementation to make things compile
log2l.c:// TODO: broken implementation to make things compile
logl.c:// TODO: broken implementation to make things compile
powl.c:// TODO: broken implementation to make things compile
sinhl.c:// TODO: broken implementation to make things compile
tanhl.c:// TODO: broken implementation to make things compile
tgammal.c:// TODO: broken implementation to make things compile
$ lspciЭтот чип поддерживается в Линуксе драйвером broadcom-sta. Но чип этот старенький, драйвером никто не занимается и привинчивать к Химере не станет. Проще воткнуть отдельный USB WiFi адаптер, к примеру AC1200.
...
02:00.0 Network controller: Broadcom Inc. and subsidiaries BCM4360 802.11ac Dual Band Wireless Network Adapter (rev 03)
wget https://repo.chimera-linux.org/live/latest/chimera-linux-aarch64-LIVE-20241204-base.iso(2) Create a virtual machine on UTM.
mkfs.vfat /dev/vda1(10) Format root filesystem:
mkfs.ext4 /dev/vda2(11) Format swap partition:
mkswap /dev/vda3(12) Mount root filesystem:
mkdir /media/root(13) Mount EFI partition:
mount /dev/vda2 /media/root
chmod 755 /media/root
mkdir -p /media/root/boot/efi(14) Install packages over network:
mount /dev/vda1 /media/root/boot/efi
chimera-bootstrap /media/root(15) Update the installed filesystem:
chimera-chroot /media/root(16) Install Linux kernel:
apk update
apk upgrade --available
apk add linux-stable(17) Enable swap:
swapon /dev/vda3(17) Generate fstab:
genfstab / >> /etc/fstab(18) Install other packages:
apk add bash vim git(19) Set root password:
passwd root(20) Refresh initramfs image:
update-initramfs -c -k all(21) Install bootloader:
apk add grub-arm64-efi(22) Shut down.
grub-install /dev/vda
update-grub
exit(23) Disable ISO image in UTM configuration.
sync
poweroff
useradd vak(2) Set hostname:
passwd vak
usermod -a -G wheel,kvm vak
echo chimera > /etc/hostname(3) Set time zone:
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime(4) Enable system logging:
dinitctl enable syslog-ng(5) Enable remote login:
apk add openssh(6) In case you need GUI, let's install the graphical interface:
dinitctl enable sshd
apk add gnomeFor the rest of configuration options see chimera-linux.org/docs/configuration/post-installation.
dinitctl enable gdm
У меня есть в запаснике пример прошивки для pic32. Пришлось повозиться, чтобы поправить его для Clang, но вроде неплохо выходит. Компиляция выглядит следующим образом:$ clang-14 -print-targets
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_32 - AArch64 (little endian ILP32)
aarch64_be - AArch64 (big endian)
amdgcn - AMD GCN GPUs
arm - ARM
arm64 - ARM64 (little endian)
arm64_32 - ARM64 (little endian ILP32)
armeb - ARM (big endian)
avr - Atmel AVR Microcontroller
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
hexagon - Hexagon
lanai - Lanai
m68k - Motorola 68000 family
mips - MIPS (32-bit big endian)
mips64 - MIPS (64-bit big endian)
mips64el - MIPS (64-bit little endian)
mipsel - MIPS (32-bit little endian)
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc32le - PowerPC 32 LE
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
r600 - AMD GPUs HD2XXX-HD6XXX
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
sparc - Sparc
sparcel - Sparc LE
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
ve - VE
wasm32 - WebAssembly 32-bit
wasm64 - WebAssembly 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
С компилятором разобрались, а теперь стоит большая задача поправить все исходники RetroBSD под него. Нынче Си гораздо более строгий, чем тридцать лет назад. Всяких глупостей не прощает.$ make
/usr/lib/llvm-14/bin/clang -target mipsel -mcpu=mips32r2 -mabi=o32 -mfloat-abi=soft -DPIC32MX7 -c uart.c
/usr/lib/llvm-14/bin/ld.lld -m elf32ltsmip -T using-bootloader.ld -e _start -g uart.o -o uart.elf
/usr/lib/llvm-14/bin/llvm-objcopy -O ihex uart.elf uart.hex
/usr/lib/llvm-14/bin/llvm-objdump --mcpu=mips32r2 -d -S uart.elf > uart.dis
Приглашение вторичного загрузчика:qemu-system-i386 -monitor stdio \
-vga cirrus \
-m 128 \
-rtc base=localtime \
-hda FreeBSD-1.0_HDA.img \
-boot c \
-net nic,model=ne2k_isa \
-net tap,ifname=tap0,script=no,downscript=no \
-name "FreeBSD 1.0"