Stránka 3 z 4
Napsal: 10 srp 2016, 21:34
od lesana87
Tak jsem se inspirovala dokumentem od Zmije a stvořila jsem tohle:
Cčkový soubor struct.c:
Kód: Vybrat vše
#include <linux/sched.h>
#define offsetof(s, m) __builtin_offsetof (s, m)
typedef struct task_struct Ttask_struct;
int state_off = offsetof(Ttask_struct, state);
int mmu_pid_off = offsetof(Ttask_struct, mmu_pid);
int counter_off = offsetof(Ttask_struct, counter);
int priority_off = offsetof(Ttask_struct, priority);
int tstack_off = offsetof(Ttask_struct, tstack);
int timeout_off = offsetof(Ttask_struct, timeout);
který se zkompiluje
sdcc.exe -mz80 -Iinclude -S struct.c do struct.asm:
Kód: Vybrat vše
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.6.0 #9615 (MINGW32)
;--------------------------------------------------------
.module struct
.optsdcc -mz80
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
.globl _timeout_off
.globl _tstack_off
.globl _priority_off
.globl _counter_off
.globl _mmu_pid_off
.globl _state_off
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _INITIALIZED
_state_off::
.ds 2
_mmu_pid_off::
.ds 2
_counter_off::
.ds 2
_priority_off::
.ds 2
_tstack_off::
.ds 2
_timeout_off::
.ds 2
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
.area _HOME
.area _GSINIT
.area _GSFINAL
.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
.area _HOME
.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
.area _CODE
.area _CODE
.area _INITIALIZER
__xinit__state_off:
.dw #0x0000
__xinit__mmu_pid_off:
.dw #0x0001
__xinit__counter_off:
.dw #0x0002
__xinit__priority_off:
.dw #0x0003
__xinit__tstack_off:
.dw #0x0004
__xinit__timeout_off:
.dw #0x0048
.area _CABS (ABS)
a ten se následně přes
grep -A1 __xinit__ struct.asm | tr --delete '\n' | sed -e 's/__xinit__/\n/g' -e 's/:/ = /g' -e 's/\t.dw #//g' > include/struct.inc profiltruje do struct.inc:
Kód: Vybrat vše
state_off = 0x0000
mmu_pid_off = 0x0001
counter_off = 0x0002
priority_off = 0x0003
tstack_off = 0x0004
timeout_off = 0x0048
a offsety jsou na světě, stačí je includnout do toho assembleru a je hotovo.
Díky Zmije za inspiraci.
Napsal: 22 říj 2016, 21:38
od lesana87
Tak se mi konečně podařilo dopsat poslední důležité volání jádra sys_execve a už můžu i spustit nový program. Ještě včera jsem mohla jen forkovat.
Pro začátek obligátní Hello world, init a shell ještě nemám, ale funguje to, *nix na Z80.
Ale ten SDCC je hrůza, někdo mi zase může vykládat, jak je C efektivní, skoro jako assembler. Možná na ARMu, ale ne na Z80. Se zavřenýma očima bych to v assembleru napsala poloviční, s otevřenýma třetinový. Sotva se mi to do těch 56KB vejde, zbývá jen asi 400B místa.
Budu muset něco do assembleru přepsat, ještě mi tam pár věcí chybí.
Kód: Vybrat vše
*AZ80*
Memory test: 256KB OK
Loading OS..........
Annix Z80 V0.01_2016
Kernel code/data end: 0x9905/0xDE14
rs_init: port 0D8
0 virtual consoles
1 serial consoles
Buffers: 16
ROOTinode: dev=(1,0), mode=040111, cnt=3, lnks=4
File: 00F3, hello.a
243 bytes written.
ls:
1: .
1: ..
64: dev
63: bin
60: hello.a
Task-info:
0: s=1, sig=0, pid=0, ppid=0, ut= 9, st= 14, ks: 166/1961
Forking task 1...
Task 1
Task-info:
0: s=1, sig=0, pid=0, ppid=0, ut= 11, st= 14, ks: 166/1961
1: s=1, sig=0, pid=1, ppid=0, ut= 0, st= 0, ks: 108/1961
Test /dev/cua0.
Press enter to continue...
Exec: hello.a
235 bytes of image loaded.
Hello world! :o)
Press enter to continue...
End.
Task-info:
0: s=1, sig=8, pid=0, ppid=0, ut= 378, st= 14, ks: 166/1961
1: s=4, sig=0, pid=1, ppid=0, ut= 1, st= 7, ks: 166/1961
Wait: 1
Task-info:
0: s=1, sig=8, pid=0, ppid=0, ut= 778, st= 14, ks: 166/1961
Napsal: 29 říj 2016, 08:53
od lesana87
Už mám i malinkej shell, tak už to začíná vypadat unixově.
Kód: Vybrat vše
> cd /
> ls
d--x--x--x 6 0 0 128 ./
d--x--x--x 6 0 0 128 ../
drwxr-xr-x 2 0 0 96 dev/
drwxr-xr-x 2 0 0 176 bin/
-rwxrwxrwx 1 0 0 1382 hello.a
drwxr-xr-x 2 0 0 32 etc/
drwxr-xr-x 2 0 0 32 usr/
> cd bin
> ls
drwxr-xr-x 2 0 0 176 ./
d--x--x--x 6 0 0 128 ../
-rwxrwxrwx 1 0 0 2710 ls
-rwxrwxrwx 1 0 0 3281 sh
-rwxrwxrwx 1 0 0 1413 rm
-rwxrwxrwx 1 0 0 157 sync
-rwxrwxrwx 1 0 0 60 nop
-rwxrwxrwx 1 0 0 1630 cat
-rwxrwxrwx 1 0 0 1353 echo
-rwxrwxrwx 1 0 0 1464 mkdir
-rwxrwxrwx 1 0 0 2400 mknod
> cd dev
sh: No such file or directory
> cd /dev
> ls
drwxr-xr-x 2 0 0 96 ./
d--x--x--x 6 0 0 128 ../
crw-rw-rw- 1 0 0 4, 0 tty0
crw-rw-rw- 1 0 0 4, 4 cua0
brw-rw-rw- 1 0 0 1, 0 sra
brw-rw-rw- 1 0 0 1, 1 srb
> echo ahoj lidi :)
ahoj lidi :)
>
Napsal: 29 říj 2016, 09:55
od Wolfik
holka...ty sis nehrála s panenkama, když si byla malá, viď?
upřímně...respekt
Napsal: 29 říj 2016, 13:32
od Zmije
Gratuluji !
Budou k dispozici zdrojáky (github, bitbucket...) ?
Ještě jsem se chtěl zeptat, jestli nechceš zkusit některý port GCC, možna by pomohly optimalizace na velikost -os.
Napsal: 29 říj 2016, 15:41
od lesana87
Do světa se s tím nějak nechystám, kvalitou to na rozdávání moc není, stále nacházím chyby a navíc k čemu by to někomu bylo, když je to šité na hardware, který mám jen já?
Portem GCC myslíš co, ono existuje GCC pro Z80?
P.S.: Panenky jsou nuda.
Napsal: 15 led 2017, 14:34
od lesana87
Trošku jsem s tím *nixem pokročila.
Dodělala jsem do kernelu pár driverů. Taky funkce pro job control, ale ještě musím dodělat job control do shellu. Execve jsem rozšířila o možnost spouštět interpretované skripty (viz ukázka skriptu ah ve výpisu). Aby na to bylo místo, musela jsem už docela velkou část kernelu přepsat do assembleru. Libc se taky rozrostla, naposledy o funkce pro konverzi času. Přibyla spousta utilit, největší fsck má skoro 10KB. Program count, spuštěný na pozadí v ukázce, jen počítá ovečky, slouží k testování multitasku a zatěžování procesoru.
Dokonce mám už i celoobrazovkový editor ue. Akorát jsem musela ten původní z Public domain řádně překopat, aby byl použitelný na sériovém terminálu a nepřekresloval při každé klávese celou obrazovku. No, už se to začíná zaplňovat, za chvíli mi bude 128KB disk malý.
Kód: Vybrat vše
*AZ80*
Memory test: 128KB OK
Loading OS..........
Annix ver. 0.3.1 [#46 2017-01-15] on AZ80
Kernel code/data end: 0x9BB5/0xDB2D
rs_init: port 0D8
0 virtual consoles
1 serial consoles
Buffers: 16
ROOT (1,0)
Memory: 128KB total, 72KB free
fsck 0.1a (23-Dec-2016)
/dev/sra: 49/96 inodes free, 113/248 blocks free
/dev/epr on /mnt
Welcome to Annix 0.3.1
Simple shell v0.4a
> ps -l
Task-info:
# st sig cnt pri uid pid ppid pgrp ses tty wch utime stime name
0: S 0000 0 15 0 0 0 0 0 255 0000 1 2721 _idle_
1: S 0000 25 15 0 1 0 0 0 255 0000 0 5 _init_
2: S 0000 5 15 0 10 1 10 10 4 0000 0 10 sh
3: S 0000 21 15 0 6 1 0 0 255 A606 1 1 update
4: R 0000 12 15 0 11 10 10 10 4 0000 2 20 ps
> count &
> ps -l
Task-info:
# st sig cnt pri uid pid ppid pgrp ses tty wch utime stime name
0: S 0000 0 15 0 0 0 0 0 255 0000 4 3044 _idle_
1: S 0000 29 15 0 1 0 0 0 255 0000 0 5 _init_
2: S 0000 25 15 0 10 1 10 10 4 0000 0 18 sh
3: S 0000 29 15 0 6 1 0 0 255 A606 1 1 update
4: R 0000 3 15 0 12 10 10 10 4 0000 118 2 count
5: R 0000 13 15 0 13 10 10 10 4 0000 1 23 ps
> ls -l /dev
drwxr-xr-x 2 0 0 192 13:54 15-01-2017 ./
drwxr-xr-x 7 0 0 160 19:41 08-01-2017 ../
crw-rw-rw- 1 0 0 4, 4 16:35 29-12-2016 cua0
crw-rw-rw- 1 0 0 5, 0 16:42 29-12-2016 tty
crw-rw-rw- 1 0 0 1, 1 16:43 29-12-2016 mem
crw-rw-rw- 1 0 0 1, 2 16:43 29-12-2016 kmem
crw-rw-rw- 1 0 0 1, 3 16:43 29-12-2016 null
crw-rw-rw- 1 0 0 1, 4 16:43 29-12-2016 port
brw-rw-rw- 1 0 0 1, 0 16:43 29-12-2016 sra
brw-rw-rw- 1 0 0 1, 1 16:43 29-12-2016 srb
brw-rw-rw- 1 0 0 2, 0 16:44 29-12-2016 epr
crw-rw-rw- 1 0 0 1, 5 13:54 15-01-2017 zero
> ls -l /bin
drwxr-xr-x 2 0 0 464 17:12 14-01-2017 ./
drwxr-xr-x 7 0 0 160 19:41 08-01-2017 ../
-rwxrwxrwx 1 0 0 4362 14:36 07-01-2017 sh
-rwxrwxrwx 1 0 0 1346 16:52 29-12-2016 cp
-rwxrwxrwx 1 0 0 9757 16:52 29-12-2016 fsck
-rwxrwxrwx 1 0 0 1887 16:52 29-12-2016 mount
-rwxrwxrwx 1 0 0 2280 16:52 29-12-2016 mkfs
-rwxrwxrwx 1 0 0 146 16:52 29-12-2016 sync
-rwxrwxrwx 1 0 0 3679 20:01 07-01-2017 ls
-rwxrwxrwx 1 0 0 353 16:53 29-12-2016 mkdir
-rwxrwxrwx 1 0 0 1345 16:53 29-12-2016 mknod
-rwxrwxrwx 1 0 0 1151 16:53 29-12-2016 rm
-rwxrwxrwx 1 0 0 587 16:53 29-12-2016 cat
-rwxrwxrwx 1 0 0 333 09:46 15-01-2017 echo
-rwxrwxrwx 1 0 0 1658 16:53 29-12-2016 rdb
-rwxrwxrwx 1 0 0 1817 16:53 29-12-2016 umount
-rwxrwxrwx 1 0 0 1971 16:53 29-12-2016 df
-rwxrwxrwx 1 0 0 294 16:53 29-12-2016 sleep
-rwxrwxrwx 1 0 0 112 16:53 29-12-2016 update
-rwxrwxrwx 1 0 0 2566 18:59 10-01-2017 ps
-rwxrwxrwx 1 0 0 1153 16:53 29-12-2016 rmdir
-rwxrwxrwx 1 0 0 1418 16:53 29-12-2016 kill
-rwxrwxrwx 1 0 0 82 16:53 29-12-2016 count
-rwxrwxrwx 1 0 0 3757 11:45 08-01-2017 ue
-rw-rw-rwx 1 0 0 66 11:55 15-01-2017 ah
-rwxrwxrwx 1 0 0 1305 15:19 01-01-2017 chmod
-rwxrwxrwx 1 0 0 3545 14:36 07-01-2017 date
-rwxrwxrwx 1 0 0 5072 10:11 08-01-2017 dd
-rwxrwxrwx 1 0 0 714 09:30 15-01-2017 uname
> date
Su Jan 15 13:59:16 2017
> uname -a
Annix 0.3.1 #46 2017-01-15 AZ80
>
> cat /bin/ah
#!/bin/sh
echo Ahoj lidi :)
echo Zda se, ze to funguje. :o)
ps -l
> ah
Ahoj lidi :)
Zda se, ze to funguje. :o)
Task-info:
# st sig cnt pri uid pid ppid pgrp ses tty wch utime stime name
0: S 0000 0 15 0 0 0 0 0 255 0000 4 3044 _idle_
1: S 0000 29 15 0 1 0 0 0 255 0000 0 5 _init_
2: S 0000 27 15 0 10 1 10 10 4 0000 0 48 sh
3: S 0000 29 15 0 6 1 0 0 255 A606 1 1 update
4: R 0000 15 15 0 12 10 10 10 4 0000 3073 2 count
5: S 0000 11 15 0 20 10 10 10 4 0000 0 19 sh
6: R 0000 11 15 0 23 20 10 10 4 0000 6 24 ps
> dd if=/dev/zero of=/dev/srb bs=2048 count=64
64+0 records in
64+0 records out
> dd if=/dev/sra of=/dev/srb bs=4k count=32
32+0 records in
32+0 records out
> fsck -v /dev/srb
fsck 0.1a (23-Dec-2016)
/dev/srb: 49/96 inodes free, 113/248 blocks free
(31 REG, 6 DIR, 7 CHR, 3 BLK, 0 SLNK, 0 FIFO)
>
Napsal: 15 led 2017, 15:55
od FHonza
Upřímně obdivuji Tvoje zapálení
Bez ironie, myslím to opravdu.
Napsal: 15 led 2017, 16:22
od Wolfik
taky bych chtěl takhle rozumět embedded věcem jako lesana
Napsal: 15 led 2017, 16:46
od lesana87
A co ti v tom brání?
Napsal: 15 led 2017, 17:23
od Wolfik
priority, energie a čas
Napsal: 15 led 2017, 17:31
od Habesan
Kdybych 40 let denně cvičil, taky bych měl svaly jako Martin Maxa.
Napsal: 15 led 2017, 18:47
od lesana87
Ještě před rokem jsem se plácala úplně bez energie a nic mě nebavilo, pak mě chytlo tohle a úplně tím žiju. Čas si člověk udělá, když chce, stačí si upravit ty priority.
Napsal: 15 led 2017, 20:53
od Wolfik
já bych nevěděl, kde začít
třeba jak sis nastudovala portaci, tak starého linuxu?
tvoje znalosti Céčka a ASM si nabrala zřejmě víceletou praxí, já si připadám, že poslední roky v čistým C dělám víceméně pořád dokola to samý...
Napsal: 15 led 2017, 21:56
od lesana87
No vidíš, tak v C jsi napřed, já v C začala programovat až teď, dřív jsem programovala jen v assembleru.
Nevím, co přesně máš na mysli tou portací a jejím studováním. Prostě jsem prolejzala zdrojáky starýho linuxu a snažila jsem se v tom vyznat. K tomu se mi nepovedlo najít žádnou dokumentaci, všechno je až k verzi 2.0 a výše, ale i to trochu pomůže s pochopením. A pak taky zdrojáky unixu V6, k těm existuje i nějaká dokumentace od Thompsona a Ritchieho a povídání od J. Lionse. Přečetla jsem knížku The Design of the Unix Operating System od Maurice Bacha, ta je taky k novější verzi unixu, ale tam se toho moc nezměnilo. Četla jsem i Tanenbaumovo Operating Systems Design and Implementation o minixu. A pár dalších knížek. No a pak jsem to začala postupně přepisovat pro ten můj hardware. Některé části se daly převzít jen s malýma úpravama, třeba scheduler nebo funkce kolem souborového systému z linuxu. Některé jsem musela překopat úplně od základu, protože se vázaly na hw, třeba přepínání procesů, správa paměti, obsluhy přerušení, signály, přenosy dat mezi kernelem a procesama... Unix V6 je mnohem jednodušší než linux, tak z unixu jsem se snažila brát "jednoduchost" a z linuxu funkce, které unix neměl a přijdou mi užitečné.
Hlavně unix V6 běžel na procesoru s 64KB adresním prostorem jako má Z80, i když byl 16-bitovej a podobal se spíš ARMu, byl teda napsanej hodně úsporně. Takže z unixu mám převzatý hlavně datový struktury, protože ty jsou v linuxu dost paměťově rozežraný. Na ty struktury jsem se ale snažila naroubovat některé funkce z linuxu, protože byly třeba líp řešený než v unixu. Tohle kombinování si samozřejmě taky vyžádalo rozsáhlý úpravy kódu. Linux jako takový, ani ten úplně první, se do 64KB na osmibitu prostě nacpat nedá a unix V6 je zase takový moc omezený nebo jak to nazvat.
(Prapůvodně jsem začala portovat minix 1.1, ale ten je ještě omezenější.) Prostě je to takový kompromisní slepenec z unixu a linuxu.