vak: (Daemon)
Один крутой чувак из Австралии взялся развивать 2.11BSD для архитектуры i386.

github.com/TheSledgeHammer/2.11BSD_X44
vak: (Daemon)
За последние три дня я могучим рывком, броском, пинком и нахрапом закончил таки переделку RetroBSD под компилятор Clang. Теперь не нужно бегать искать GCC для mips32. Ставите стандартный Clang и вперёд. Инструкция по сборке лежит в корневом файле README. Для запуска на симуляторе годится обновлённый QEMU для pic32. Если кому понадобится старая версия с GCC - она лежит в бранче gcc.

Поддержку устаревшего хардвера я убрал. Оставил только две платы, обе имеются в продаже:Из минусов: потеряны две фичи.
  • MIPS16e - компактная система команд - не поддерживается компилятором Clang. Формально она там есть, но код генерится совершенно нерабочий. Так что приходится довольствоваться стандартным набором инструкций. Из-за этого некоторые "толстые" приложения не лезут в память, к примеру компилятор SmallerC.
  • Не удаётся собрать библиотеку libc.а в формате a.out для того же компилятора SmallerC. Потому что имеющийся ассемблер mips32 не понимает некоторые навороченные конструкции, порождаемые компилятором Clang. Надо будет допиливать.
Но в целом система фурычит довольно неплохо. Открывается путь для переноса на другие платформы: esp32, stm32, riscv и другие.
vak: (Daemon)
Хотите взглянуть, как грузится RetroBSD с точки зрения последовательности системных вызовов? Стартует /sbin/iuit, из-под него /bin/sh выполняет скрипт /etc/rc, проверяет файловую систему, запускает cron и в конце концов getty. Я сделал флажок в QEMU для pic32, чтобы трассировать системные вызовы. Вывод слегка обработал вручную, вот результат.

gist.github.com/sergev/c0c21f47220e2d3ec6eee4b5b076ec0f
vak: (Daemon)
Внезапно выяснилось, что в RetroBSD была старая ошибка, из-за которой он не запускался на QEMU. Инструкция ERET попадала в delay-слот условного перехода. Строго говоря, это неопределённое поведение. В железе на PIC32 оно работает, но симулятор такого не прощает. Поправил, теперь всё с порядке.
$ 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
Обратите внимание: работают ассемблер и Си компилятор.
vak: (Daemon)
Нашёлся умный человек, подсказал как собрать на нынешнем Debian 12 (bookworm) симулятор pic32, который я сварганил десять лет назад. Приятно вспомнить.

Главная хитрость - установить Python 2.7. Официально делать это крайне не рекомендуется, но оно работает, как ни странно.
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 для pic32:
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
Бинарник QEMU будет установлен как /usr/local/qemu-mips/bin/qemu-system-mipsel. Запустим LiteBSD:
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"
Стартует классический юникс 30-летней давности:
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 -q.
vak: (Daemon)
Хотите вспомнить молодость? Запустить FreeBSD 1.0, историческую версию 1993 года. Или FreeBSD 2.0.5, версию 1995 года. Нынче это легко делается с помощью современного симулятора QEMU. Он ставится на Ubuntu командой "sudo apt install qemu-system-x86", а на маке "brew install qemu".

Установка юникса в то время требовала много ручной работы. Я подготовил образы дисков с уже установленной минимальной системой, и с настроенной сетью.

FreeBSD 1.0

Скачиваем файл FreeBSD-1.0-qemu.tar.xz. Извлекаем файлы, запускаем:
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
Входим как root, без пароля. Смотрим версию ядра, размеры файловых систем, версию компилятора. Останавливается машина командой halt.

FreeBSD 2.0.5

Именно на этой версии большинство народа из моего поколения получало первый юниксный опыт. Скачиваем файл FreeBSD-2.0.5-qemu.tar.xz. Здесь я сделал сразу четыре диска, хотя наполнен только один. Можете размечать их, монтировать и использовать под свои дела.
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

Сеть настроена. Можете вспоминать, как и откуда скачивать пакеты по FTP и как их устанавливать. 😀

[personal profile] dmarck, заметь: ни тебе rtld, ни ASLR.
vak: (Daemon)
Подрихтовал ещё немного тулзу, и таки добился своего. Можем теперь наблюдать интимные подробности работы динамического загрузчика.

Пример состоит из двух частей, обе написаны на ассемблере.
  • Главная программа foobar.S выдаёт пару текстовых сообщений, вызывая функцию say() из динамической библиотеки. Затем завершается системным вызовом _exit().
  • Бибилиотека lib.S реализует функцию say(), которая выполняет системный вызов write().
Всё это на процессоре arm32 под FreeBSD.



Компилируем, запускаем. Работу динамического загрузчика я сократил для ясности. Инструкции главной программы выделены зелёным, инструкции библиотечной функции сиреневым. Видно, как при первом вызове функции say() её адрес ещё не готов. Активируется динамический загрузчик, находит адрес функции и уходит в неё. При втором вызове say() переход происходит напрямую. Вставка-переходник say@plt занимает три машинных команды.
$ 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.
vak: (Daemon)
Коммерческие операционки перестали поддерживать 32-битные версии, но Линукс и BSD пока не сдаются. В частности, FreeBSD продолжает выпускать образы установщиков и поддерживать репозиторий пакетов для 32-битных ARM процессоров.

Для проверки сего факта я запустил FreeBSD на Олинуксино lime2. Всё работает как ожидается, только порт Ethernet поднять не удалось. Не знаю уж в чём там проблема, ведь под Линуксом порт работает. Может в U-Boot что подконфигурить надо, но мне лень искать.

Запишу здесь процесс для памяти.

(1) Скачать образ диска FreeBSD:
wget https://download.freebsd.org/releases/ISO-IMAGES/14.2/FreeBSD-14.2-RELEASE-arm-armv7-GENERICSD.img.xz
(2) Записать на карточку microSD посредством утилиты balenaEtcher или ещё как-нибудь.

(3) Скачать пакет с загрузчиком U-Boot для платы A20 Olinuxino Lime2:
wget https://pkg.freebsd.org/FreeBSD:14:aarch64/latest/All/u-boot-olinuxino-lime2-2024.07.pkg
(4) Добыть оттуда бинарник загрузчика:
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 .
(5) Записать загрузчик на ту же карточку microSD поверх образа FreeBSD. Здесь замените /dev/diskN на девайс карточки в вашей системе:
dd if=u-boot-sunxi-with-spl.bin of=/dev/diskN bs=1k seek=8 conv=sync
После этого грузитесь с карточки и заходите в систему с консольного порта, юзер root, пароль root. 
vak: (Daemon)
Я таки смог запустить трассировку на архитектуре ARM32. Для этого пришлось научиться ставить FreeBSD на виртуальном Cortex-A15 под симулятором QEMU.
$ 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.
vak: (Daemon)
Поддержка архитектуры RISC-V в FreeBSD всё ещё в процессе разработки. Но уже можно запустить ядро на симуляторе QEMU. Вот как это делается.
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
Вход как root без пароля. Пакетов для RISC-V ещё нету, как я понимаю, поэтому командой pkg ничего установить не удаётся.

Протокол загрузки:
vak: (Daemon)
Всё оказалось просто. Вот исходники глючащей функции: git.musl-libc.org/cgit/musl/tree/src/math/log10l.c

Суть в ифдефах:
#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
В нашем случае срабатывает именно последний вариант, когда в мантиссе 113 бит и максимальная экспонента равна 16384.

И такого добра там навалом.
$ 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
То есть никто не тестировал эту библиотеку на компиляторе со 128-битным long double. Тут чинить и чинить.

UPD: правильные реализации можно найти в OpenLibm, к примеру: github.com/JuliaMath/openlibm/blob/master/ld128/e_log10l.c
vak: (Daemon)
Установил Chimera Linux на старенький макбук десятилетней давности. Процесс несложный: записываем ISO образ на флешку и с неё грузимся. Дальше по той же инструкции. Всё работает кроме Wi-Fi. Наверное надо драйвер подгрузить.





Update: с драйвером WiFi всё плохо.
$ lspci
...
02:00.0 Network controller: Broadcom Inc. and subsidiaries BCM4360 802.11ac Dual Band Wireless Network Adapter (rev 03)
Этот чип поддерживается в Линуксе драйвером broadcom-sta. Но чип этот старенький, драйвером никто не занимается и привинчивать к Химере не станет. Проще воткнуть отдельный USB WiFi адаптер, к примеру AC1200.

Отличный ноубук кстати. Хоть и старый, но весьма приятный в работе. Единственное - батарейка заряжается только до 63%.

vak: (Daemon)
Меня неожиданно порадовал этот проект. Не знаю как пойдёт, но у него потенциально большое будущее. Попробую пояснить почему.

Что такое современная опенсорсная операционная система? Это сообщество + ядро + /bin/init + libc + пакеты приложений. Так по пунктам и буду рассуждать.

1. Новая операционная система общего назначения, строящая по принципам скорее BSD чем GNU. То есть сathedral супротив bazaar, в терминах Эрика Рэймонда. За последние десять лет движение BSD стало как-то утрачивать энергию. Здесь есть шанс на возрождение.

2. Используется ядро Linux вместо FreeBSD/NetBSD/OpenBSD. У Линукса огромное преимущество в драйверах и поддержке со стороны бизнеса. Всякий производитель процессоров или компьютерных плат нынче предоставляет версию линукса в драйверами. Для BSD нет смысла пытаться догнать уходящий поезд. Проще к нему присоединиться.

3. Ядро это только половина юникса, а вторую половину, возможно более важную для юзера, определяет набор системных процессов. В классике это был /bin/init, а нынче всё чаще systemd. И то, и другое имеет серьёзные проблемы. Здесь эти проблемы решено рубить радикальным образом, опираясь на современные идеи. Новый подход dinit выглядит весьма неплохо.

4. Теоретически приложения общаются с ядром через системные вызовы, а на практике через набор библиотек нижнего уровня. Условно говоря, это libc, libc++ и прочие. В мире GNU оно всё стандартизовалось вокруг glibc. И это проблема, так как сделано оно там не лучшим образом. Громоздко, часто неэффективно, а переделывать уже поздно: субстанция слиплась и затвердела. 😀 Здесь же за основу взяты библиотеки из мира BSD. Они написаны более качественно, понятно, а главное эффективно и компактно.

5. Установка приложений из централизованных репозиториев и беспроблемное обновление их (и самой операционной системы) по ходу жизни - критически важная часть функциональности. Иначе никто не будет такой системой пользоваться. Те же Debian и Ubuntu обязаны популярностью именно своей системе пакетов и обновлений. Был даже проект kFreeBSD, с ядром BSD и пакетами в формате Debian (не выжил). Многое там сделано по уму, но спроектировано 30 лет назад, тяжеловесное и переусложнённое. Здесь же, в Chimera Linux, взята другая технология пакетов "apk-tools", современная, но хорошо отработанная в Alpine Linux. Однако система сборки пакетов сделана новая, на основе Python. Выгляди намного проще и надёжнее.

Я установил виртуальную Химеру на макбуке, закачал и собрал несколько своих проектов - всё отлично, всё нравится. Поглядим, как дальше у проекта будет судьба складываться. Если кого интересует готовый образ установленной Химеры для UTM - скажите, дам скачать. Ужатый файл размером 1.1 Гбайт.
vak: (Daemon)
Just finished installing Chimera Linux as a virtual machine on my Macbook M2 Max. It's a beautiful OS, but getting it up and running felt like a time warp back to the early 90s. The installation process was as nostalgic as 386bsd, complete with a healthy dose of manual configuration. 😀 When installed, the system seems pretty stable and efficient, with 12 cores and 16 Gbytes of memory.



For full documentation, see chimera-linux.org/docs/installation.

(1) Download live image of Chimera Linux for ARM64 architecture:
    wget https://repo.chimera-linux.org/live/latest/chimera-linux-aarch64-LIVE-20241204-base.iso
(2) Create a virtual machine on UTM.
Press '+', select Virtualize, then Linux.
Press 'Browse...' and choose ISO image you've downloaded.
Make disk size 16 Gbytes.
Start the VM and wait until "login:" prompt.

(3) Log in as root with password 'chimera'.

(4) Invoke 'cfdisk /dev/vda'.
Select label type 'gpt'.

(5) Choose 'New' to create a first partition.
Enter partition size '200M'.
Choose 'Type' to change partition type to 'EFI System'.

(6) Choose 'Free space' line.
Choose 'New' to create a second partition.
Enter partition size '15G'.

(7) Choose 'Free space' line.
Choose 'New' to create a third partition.
Use the rest of the disk, i.e. partition size '823M'.
Choose 'Type' to change partition type to 'Linux swap'.

(8) Choose 'Write' and enter 'yes'.
Then choose 'Quit'.

(9) Format EFI filesystem:
    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
mount /dev/vda2 /media/root
chmod 755 /media/root
(13) Mount EFI partition:
    mkdir -p /media/root/boot/efi
mount /dev/vda1 /media/root/boot/efi
(14) Install packages over network:
    chimera-bootstrap /media/root
(15) Update the installed filesystem:
    chimera-chroot /media/root
apk update
apk upgrade --available
(16) Install Linux kernel:
    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
grub-install /dev/vda
update-grub
(22) Shut down.
    exit
sync
poweroff
(23) Disable ISO image in UTM configuration.

(24) Start the Chimera virtual machine again. It should boot from internal drive. You can log in as root with password you've set on step (19).

Now the system is complete and bootable. So let's configure it for our needs:

(1) Create a regular user with admin privileges:
    useradd vak
passwd vak
usermod -a -G wheel,kvm vak
(2) Set hostname:
    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
dinitctl enable sshd
(6) In case you need GUI, let's install the graphical interface:
    apk add gnome
dinitctl enable gdm
For the rest of configuration options see chimera-linux.org/docs/configuration/post-installation.
vak: (Daemon)
Три года назад я уже хвастался установкой FreeBSD на Raspberry Pi 4. Но то была экспериментальная версия. Нынче же последняя штатная версия FreeBSD 13.2 отлично встаёт как родная.
  • Скачиваем файл FreeBSD-13.2-RELEASE-arm64-aarch64-RPI.img.xz
  • Скачиваем и устанавливаем утилиту Raspberry Pi Imager (отсюда).
  • С её помощью записываем образ FreeBSD на карточку micro-SD.
  • Вставляем карточку в Raspberry Pi и загружаемся. Готово!
SSH в системе уже включён. Можно логиниться по сети юзером freebsd с паролем freebsd.

Подробности в статье: https://raspberrytips.com/install-freebsd-raspberry-pi/

Красивый удобный девайс получился в металлическом безвентиляторном корпусе. Надо всё-таки иметь хоть одну BSD под рукой: мало ли какой софт потребуется собрать, проверить.



Подробности конфигурации:
Потребление на холостом ходу и со 100% загрузкой всех процессоров:


vak: (Default)
Вам надоели указатели в Си/Си++? Тогда CHERI идёт к вам!

CHERI расшифровывается как "Capability Hardware Enhanced RISC Instructions". Это исследовательский проект в Кембридже по замене указателей на более безопасные capabilities. Не знаю как это по русски. В отличие от указателей capabilities содержат также границы и уровень доступа. ARM сделал экспериментальный процессор Morello с поддержкой capabilities.

Архитектура хардвера описана в статье: "CheriABI: Enforcing Valid Pointer Provenance and Minimizing Pointer Privilege in the POSIX C Run-time Environment" (PDF).

Особенности языка Си/Си++ на такой архитектуре приведены в статье: "CHERI C/C++ Programming Guide" (PDF).

Развивается проект CheriBSD: перенос операционной системы FreeBSD на платформу CHERI.

На видео показана работа графического сервера Wayland и демо OpenGL на процессоре Morello под операционной системой CheriBSD.



Подобных проектов в истории было много. Кто помнит, советская ЭВМ Эльбрус разрабатывалась с аналогичной целью, защититься от программных ошибок адресации памяти. Но во всех таких проектах софт приходилось писать с нуля из-за полной несовместимости с существующими методами программирования. А здесь 99% софта переносится без проблем.
vak: (Default)
Крэйг Тернер сделал обзор моих проектов RetroBSD и LiteBSD. Там есть несколько фактических ошибок, но в целом неплохо.

http://songseed.org/dinghy/d.pic32.platform.html

Я уже несколько лет как перестал заниматься этими проектами: другие дела держат. Надеялся, что публика поддержит и разовьёт, но критическая масса не накопилась и оно угасло. Однако интерес теплится тем не менее. Я ожидал, что LiteBSD будет активнее воспринят, ведь там и виртуальная память, и сетевой стек. Неожиданно народ проявляет больше внимания к RetroBSD.
vak: (Default)
Народ на днях задал мне вопрос, нет ли способа пересобрать RetroBSD из исходников на каком-нибудь современном линуксе, типа Ubuntu 22.04, не откатываясь на десять лет назад. Я потыркался маленько, и оказалось, что компилятор для mips32r2 найти не так уж легко. Нет способа просто установить GCC для MIPS из готовых пакетов ни на линуксе, ни на маке. Старые бинарные сборки устарели и на новых MacOS вообще не запускаются. Пытался скомпилировать последний GCC из исходников - валится где-то при сборке runtime библиотеки. Непруха в общем.

Неожиданно обнаружилось, что ситуацию может спасти Clang. Это другой Си компилятор, из проекта LLVM. Оказалось, что стандартный пакет типа clang-14 содержит бэкенд не только для x86-64, но и для кучи других архитектур, включая mips32. Вот полный список.
$ 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
У меня есть в запаснике пример прошивки для pic32. Пришлось повозиться, чтобы поправить его для Clang, но вроде неплохо выходит. Компиляция выглядит следующим образом:
$ 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
С компилятором разобрались, а теперь стоит большая задача поправить все исходники RetroBSD под него. Нынче Си гораздо более строгий, чем тридцать лет назад. Всяких глупостей не прощает.
vak: (Default)
Некие крутые перцы умудрились вытащить из загашников, отряхнуть пыль и установить на QEMU операционную систему FreeBSD версии 1.0. Это 1993 год, приятно вспомнить. Я тогда много занимался этой операционкой: драйверы, русификация, сетевые протоколы.

Скачиваем образ диска: FreeBSD-1.0_HDA.img

Запускаем:
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"
Приглашение вторичного загрузчика:

Начало загрузки ядра: копирайты, разпознавание устройств писишки. Больше 64 мегабайт памяти ядро не понимает. Шина ISA: тогда PCI ещё не было.

Загрузились, вводим имя юзера.

Смотрим версию ядра, размеры файловых систем, версию компилятора.