====== Gforth als Prozess 1 unter Linux ====== ===== USB-Stick oder SD-Karte mit GForth almost native ===== Die Installation von GForth 'almost native' für x86-32Bit wurde für i686 Rechner (Pentium-Pro und neuer) kompiliert. Getestet wurde auf einem Thinkpad X60 und einen NoName Laptop mit VIA C7 CPU. Bei Fragen und Verbesserungsvorschlägen bitte eine E-Mail an ''gforth-an@strotmann.de''. ==== Anleitung Dateien ==== Anleitung zum erstellen einen USB-Stick oder SD-Karte unter Linux - USB Stick oder SD-Karte einstecken, Gerätename per "dmesg" herausfinden (im folgenden /dev/sdb1 bitte gegen den eigenen Gerätenamen austauschen. ACHTUNG, bei falschem Gerätenamen droht Datenverlust!) - die Software "syslinux" als Paket installieren (per yum, apt-get, emerge etc) - eine primäre Partition auf dem Stick anlegen (wenn nicht schon vorhanden) - Partition mit dem EXT2 Dateisystem formatieren ''% mkfs.ext2 /dev/sdb1'' - Partition anhängen '''% mount /dev/sdb1 /mnt'' - Dateien auf die Partition spielen ''cd /mnt; tar cvfz gforth-almost-native-20140815.tgz; sync; cd;'' - extlinux installieren ''% extlinux -i /mnt'' - Bootsektor installieren ''% cat /usr/share/syslinux/mbr.bin > /dev/sdb'' - Partition aushängen ''% umount /mnt'' - USB-Stick ausprobieren [[http://strotmann.de/~cas/download/gforth-an/gforth-almost-native-20140815.tgz|GForth 'almost native' Dateien vom 20140815 (12.5 MB)]] ==== Anleitung Dateisystem-Abbild ==== - USB-Stick oder SD-Karte einstecken (mind. 512 MB), Gerätename per "dmesg" herausfinden (im folgenden /dev/sdb1 bitte gegen den eigenen Gerätenamen austauschen. ACHTUNG, bei falschem Gerätenamen droht Datenverlust!) - Image auf das Gerät spielen ''gzcat gforth-almost-native-20140815.img.gz | dd bs=1M > /dev/sdb'' - USB-Stick oder SD-Karte ausprobieren [[http://strotmann.de/~cas/download/gforth-an/gforth-almost-native-20140815.img.gz|GForth 'almost native' USB-Stick Image (512MB) vom 20140815 (37 MB)]] ==== Blocks und Datei-IO unter gforth-an ==== Wenn GNU/Forth (gforth) unter Linux als PID-1 gestartet wird, so ist ein Dateizugriff auf das Dateisystem des USB-Sticks oder der Festplatte möglich. GNU/Forth Blocks sind im gforth-Handbuch Dokumentiert: [[https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Blocks.html]]. Wird keine explizite Datei für die Blocks angegeben, wir werden die Blocks in die Datei "blocks.fb" auf dem Datenträger geschrieben, von dem gforth-an gestartet wurde (z.B. dem USB-Stick). Die Datei-IO Worte des gforth orientieren sich am ANSI-Forth Standard und sind im Handbuch unter [[https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Files.html]] dokumentiert. Es können so viele Blocks erstellt werden, wie Speicherplatz auf dem Datenträger frei ist. ==== Editor ==== Bis es einen besseren Editor für gforth-na gibt (Freiwillige vor), kann der Retro-Forth Editor ([[http://retroforth.org/pages/?PortsOfRetroEditor]]) benutzt werden. Der Retro-Forth Editor ist klein genug, um Ihn einzutippen und dann mittels des Editors (nochmal) in einen Block zu schreiben, um den Editor danach direkt aus dem Block laden zu können. .( Retro Forth block editor for gForth ) cr 16 constant l/b : (block) scr @ block ; : (line) c/l * (block) + ; : row dup c/l type c/l + cr ; : .rows l/b 0 do i . row loop ; : .block ." Block: " scr @ dup . updated? 43 + emit space ; : +--- ." +---" ; : :--- ." :---" ; : x--- +--- :--- +--- :--- ; : --- space space x--- x--- x--- x--- cr ; : vb --- scr @ block .rows drop --- ; : .stack ." Stack: " .s ; : status .block .stack ; : v cr vb status ; : v* update v ; : s dup scr ! block drop v ; : ia (line) + >r 10 parse r> swap move v* ; : i 0 swap ia v* ; : d (line) c/l bl fill v* ; : x (block) l/b c/l * bl fill v* ; : p -1 scr +! v ; : n 1 scr +! v ; : e scr @ load ; cr .( editor loaded ) cr ==== Tastaturbelegung ==== Der Standard-Linux-Kernel startet mit einer Tastaturbelegung für US-amerikanische Tastaturen. Um eine deutsche Tastaturbelegung zu bekommen, sind folgende Optionen: * beim Kompilieren des Linux-Kernels die Datei "drivers/tty/vt/defkeymap.map" anpassen. Die Keymap-Dateien finden im Linux unter "/usr/share/keymaps" * Unter GForth mittels der Syscalls die Funktion des Linux-Programmes "loadkeys" nachbauen, um die Linux-Tastaturtabelle zu setzen * Unter Forth einen neuen Tastaturtreiber schreiben, welcher die Zeichen von US-amerikanisch auf deutsche Tastatur anpasst. Ein einfacher Tastaturtreiber: \ german keyboard mapping create keytab $100 allot keytab $100 erase : keytrans: char keytab + c! ; : keyb-de key dup keytab + c@ dup if swap then drop ; ' keyb-de IS xkey \ Incomplete german keyboard mapping char z keytrans: y char y keytrans: z char " keytrans: @ char ö keytrans: ; char Ö keytrans: : char ä keytrans: ' char Ä keytrans: " char ü keytrans: [ char Ü keytrans: { char ; keytrans: < char : keytrans: > char # keytrans: \ char * keytrans: } char } keytrans: + char ' keytrans: | char ? keytrans: _ char ( keytrans: * char ) keytrans: ( char - keytrans: / char = keytrans: ) char & keytrans: ^ char / keytrans: & char _ keytrans: ? ===== Linux Syscalls aus GForth für amd64-64bit Linux ===== abi-code sys-getpid -8 di d) r8 lea \ adjust data stack pointer for new value 39 # ax mov \ getpid syscall is "39" $0F c, $05 c, \ syscall ax r8 ) mov \ move result to data-stack (pointer in R8) r8 ax mov \ return new data-stack pointer in AX ret \ return from call end-code abi-code sys-sync 162 # ax mov \ sync syscall is "162" $0F c, $05 c, \ syscall di ax mov \ return data-stack pointer unchanged ret \ return from call end-code abi-code sys-poweroff 169 # ax mov \ reboot syscall is "169" $fee1dead # di mov \ magic 1 85072278 # si mov \ magic 2 $4321fedc # dx mov \ command (poweroff) $0F c, $05 c, \ syscall ret \ we don't expect to come back end-code abi-code sys-reboot 169 # ax mov \ reboot syscall is "169" $fee1dead # di mov \ magic 1 85072278 # si mov \ magic 2 $01234567 # dx mov \ command (reboot) $0F c, $05 c, \ syscall ret \ we don't expect to come back end-code \ re-define bye : bye sys-sync sys-poweroff ; ===== Linux Syscalls aus GForth für ia86-32bit Linux ===== abi-code sys-getpid ( -- pid ) \ get process ID for gforth 20 # ax mov \ get-pid syscall $80 # int \ execute syscall ax cx mov \ save result 4 sp d) ax mov \ get stackpointer 4 # ax sub \ make space for result on stack cx ax ) mov \ move result to stack ret \ return from code end-code abi-code sys-reboot ( -- ) \ shutdown and reboot machine 88 # ax mov \ reboot syscall $fee1dead # bx mov \ magic 1 85072278 # cx mov \ magic 2 $01234567 # dx mov \ command (restart) $80 # int \ execute syscall ret \ we don't expect to come back end-code abi-code sys-poweroff ( -- ) \ shutdown and poweroff machine 88 # ax mov \ reboot syscall $fee1dead # bx mov \ magic 1 85072278 # cx mov \ magic 2 $4321fedc # dx mov \ command (poweroff) $80 # int \ execute syscall ret \ we don't expect to come back end-code abi-code sys-sync ( -- ) \ commit buffer cache to disk 36 # ax mov \ sync syscall $80 # int \ execute syscall 4 sp d) ax mov \ return stackpointer ret \ return end-code \ redefine "bye" : bye sys-sync sys-poweroff ; ===== FAQ ===== * Frage: Kann gforth-na auf die Festplatte installiert werden * Antwort: ja. Bei einem Linux-System kann das ''gforth'' Programm (statisch gegen diet-libc gelinkt) in ein Verzeichnis kopiert werden (zusammen mit der Image-Datei ''gforth.fi''. Im Linux-Bootloader muss dann ein neuer Eintrag erstellt werden, welcher das gforth als init Prozess startet. Beispiel-Eintrag bei einem Debian-System mit ''grub'' Boot-Loader: menuentry 'GNU/Forth almost native' --class debian --class gnu-linux --class gnu --class os { load_video insmod gzio insmod part_msdos insmod ext2 set root='(hd0,msdos1)' search --no-floppy --fs-uuid --set=root 3413a572-49e9-47f0-9a27-fb3daa7c13b2 echo 'Loading GNU/Forth ...' linux /vmforth root=/dev/sda3 rw fbcon=font:SUN12x22 init=/bin/gforth } * Frage: welche Minimalanforderungen an den Rechner hat gforth-na? * Antwort: bei Benutzung eines (selbstkompilierten) 2.6.x Linux-Kernels: 386SX CPU mit 4 MB Hauptspeicher ===== gforth mit diet-libc bauen ===== diet-libc ist eine minimale kleine C-Runtime Library mit der statisch gelinkte, kleine Binaries erzeugt werden koennen. Anbei die Schritte, um das aktuelle gforth aus Bernds git Repository mit der diet-libc zu bauen. Der "make" Durchgang schlaegt beim kompilieren des gforth-itc fehl. An dieser Stelle ist aber das normale gforth binary schon gebaut und kann installiert werden. # cd /usr/src # wget http://www.fefe.de/dietlibc/dietlibc-0.33.tar.bz2 --2014-10-21 15:42:56-- http://www.fefe.de/dietlibc/dietlibc-0.33.tar.bz2 Resolving www.fefe.de (www.fefe.de)... 2001:4d88:ffff:ffff:d0:b723:863f:2, 31.15.64.162 Connecting to www.fefe.de (www.fefe.de)|2001:4d88:ffff:ffff:d0:b723:863f:2|:80... connected. HTTP request sent, awaiting response... 200 Coming Up Length: 626885 (612K) [application/octet-stream] Saving to: ‘dietlibc-0.33.tar.bz2’ 100%[==================================================================================>] 626,885 531KB/s in 1.2s 2014-10-21 15:42:57 (531 KB/s) - ‘dietlibc-0.33.tar.bz2’ saved [626885/626885] # tar xvfj dietlibc-0.33.tar.bz2 # make # install bin-i386/diet /usr/local/bin # export CC="diet gcc" # git clone https://github.com/forthy42/gforth.git # cd gforth # autoreconf -i # ./configure # make Der "make" Befehl schlaegt beim bauen von gforth-itc fehl, das normale "gforth" Programm konnte aber schon gebaut werden. # make install # strip $(which gforth) # file $(which gforth-0.7.9_20140402) /usr/local/bin/gforth-0.7.9_20140402: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=19f1d32b09820cd21bc9f2ee552491f51f878fd8, stripped # ls -l $(which gforth-0.7.9_20140402) -rwxr-xr-x 1 root root 143496 Oct 21 16:06 /usr/local/bin/gforth-0.7.9_20140402 ===== Links ===== * GNU/Forth Dokumentation: [[https://www.complang.tuwien.ac.at/forth/gforth/Docs-html]] * GNU/Forth Quellcode auf github: [[https://github.com/forthy42/gforth]] * Anton Ertl: Almost native Forth: [[http://www.complang.tuwien.ac.at/forth/gforth/almost-native/]] * Linux 64Bit Syscall Tabelle: [[http://blog.rchapman.org/post/36801038863/linux-system-call-table-for-x86-64]] * Linux 32Bit Syscall Tabelle: [[http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html]] * GNU Forth (gforth): [[http://www.gnu.org/s/gforth/]] * Introduction to Computer Organization von Robert G. Plantz, PDF eBook bei Lulu: [[http://www.lulu.com/shop/robert-g-plantz/introduction-to-computer-organization-ebook/ebook/product-21369110.html]] * PC Assembly Language von Paul Carter, Kostenloses PDF eBook bei Lulu: [[http://www.lulu.com/shop/paul-carter/pc-assembly-language/ebook/product-17380062.html]] * Art of Assembly Language, 2nd Edition von Randall Hyde: [[http://www.nostarch.com/assembly2.htm]] * Wikibooks X86 Assembly: [[http://en.wikibooks.org/wiki/X86_Assembly]] * A. Ertl u. D. Kühling -- ABI-CODE: Increasing the portability of assembly language words: [[http://www.complang.tuwien.ac.at/anton/euroforth/ef10/papers/ertl.pdf]] * fefe: diet libc - a libc optimized for small size: [[http://www.fefe.de/dietlibc/]] * Linux Kernel Repository: [[http://kernel.org]] * Knoppix-Live-Linux System: [[http://www.knopper.net/knoppix/index.html]]