mellvik / tlvc Goto Github PK
View Code? Open in Web Editor NEWTiny Linux for Vintage Computers
License: Other
Tiny Linux for Vintage Computers
License: Other
The new tracing tools (partly) imported from ELKS (thank you @ghaerr) expand the previous ^P keyboard toggle which enables/disables extensive debug output from the kernel (as selected in include/linuxmt/debug.h
and now also in include/linuxmt/trace.h`): ^O now lists a snapshot of the L1/L2 buffer status on the system, ^N lists the active inodes.
These are extremely useful debugging tools, not the least because they may be used from any terminal or the physical console (virtual screens). Even via network logins (telnet
) ^P and ^N work, but not ^O.
The reason is that ^O traditionally has a special significance in telnet
as in Unix and Linux systems (not on TLVC - yet): Flush output. This is sometimes a real pain in the rear, and the best solution is to change the list buffer status command to an available control character.
In the meanwhile there is a more complicated quick fix: Most telnet
clients accept something like the following local command:
telnet> set flushoutput ^W
or some other preferred character. The ^W
is literal, enter the two characters as is. This will relieve ^O from its local duties and make it flow freely between the telnet
client and target machine.
If configured with L1 buffers only, TLVC hangs at rootmount time if the boot device is a full size minix fs.
A 64M minix fs requires 13 blocks of 'locked' (b_count
> 0) buffers, while there are only 12 L1 buffers available. Actually, the buffer level is unimportant, it's the number of buffers that count. (1 superblock, 12 bitmap blocks).
the root cause seems to be located in minix_read_super
, which reads the entire fs bitmap into buffers and keeps them 'locked' for the duration of the mount. Mounting 4 fullsize file systems locks up 52 buffers.
the issue may seem esoteric but needs to be fixed in order to make TLVC bootable on small systems. That said, if the filesystem is small, booting and/or mounting works fine. The qemu std 32M boot image boots, but leaves little left for system operation.
the problem does not apply to fat filesystems which require only one block locked in bufferspace.
When mounting a fresh image from a build, TLVC reports it as needing fsck.
This is irritating and unnecessary. Fix in host tools.
If a shell is started from a (sub)mounted filesystem, then exited, that fs can no longer be unmounted (boot required).
ash
only, sash
is finesh
may be leaving open file descriptors behind somehow.TLVC 0.6.0
login: root
tlvc17# mount /dev/dhda2 /mnt
MINIX: inodes 21845 imap 3 zmap 8, first data 696
MINIX-fs: mounting unchecked file system 0x502, running fsck is recommended.
tlvc17# umount /mnt
tlvc17# fsck -a /dev/rdhda2
Filesystem on /dev/rdhda2 is dirty, needs checking.
tlvc17# fsck -a /dev/rdhda1
Filesystem on /dev/rdhda1 is dirty, needs checking.
tlvc17# !mo
mount /dev/dhda2 /mnt
MINIX: inodes 21845 imap 3 zmap 8, first data 696
tlvc17# /mnt/bin/sh
# df
Filesystem 1K-blocks Free Used % FUsed% Mounted on
/dev/dhda3 65535 62984 2551 4% 1% /
/dev/dhda2 65535 63707 1828 3% 1% /mnt
# ^D
tlvc17# !um
umount /mnt
/mnt: Device or resource busy <----- cannot unmount even if process is gone
tlvc17# mount /dev/dhda1 /mnt2 <--- mounting a different fs this time
MINIX: inodes 21845 imap 3 zmap 8, first data 696
tlvc17# /mnt2/bin/sash <----- try sash
# ls /mnt2
.
..
386.linux
bin
bootopts
bootopts.386
dev
etc
good.linux
linux
mnt
root
tmp
# ^D
tlvc17# umount /mnt2 <----- no problem unmounting
tlvc17# mount /dev/dhda4 /mnt2 <----- mounting FAT fs
FAT: me=f8,csz=16,#f=2,floc=1,fsz=147,rloc=295,#d=512,dloc=327,#s=601776,ts=601776
FAT: total 300M, fat16 format
tlvc17# /mnt2/bin/sh
/mnt2/bin/sh: not found
tlvc17# cp /bin/sh /mnt2/bin/
tlvc17# sync
tlvc17# /mnt2/bin/sh
# pwd
/root
# ^D
tlvc17# umount /mnt2
/mnt2: Device or resource busy <----- again, umount is blocked
tlvc17# df
Filesystem 1K-blocks Free Used % FUsed% Mounted on
/dev/dhda3 65535 62984 2551 4% 1% /
/dev/dhda2 65535 63707 1828 3% 1% /mnt
/dev/dhda4 300883 295112 5771 2% /mnt2 (FAT)
tlvc17# ps
PID GRP TTY USER STAT CPU HEAP FREE SIZE COMMAND
1 0 root S 0 3072 2014 12944 /bin/init 3
12 12 1 root S 0 1188 13330 71280 -/bin/sh
13 13 S0 root S 0 2280 12316 71280 -/bin/sh
14 14 S2 root S 0 0 1976 8512 /bin/getty /dev/ttyS2 57600
42 13 S0 root R 0 1024 1176 11680 ps
6 6 root S 0 1024 34738 75824 ktcp -b -p ne0 10.0.2.17 10.0.2.2 255.255.255.0
8 8 root S 0 0 1998 9744 telnetd
10 2 S0 root S 0 0 7306 28672 ftpd -d
tlvc17# umount /mnt
/mnt: Device or resource busy
tlvc17# umount /mnt2
/mnt2: Device or resource busy
tlvc17#
The serial console will lose characters on output at low speeds. At 9600 bps, CRs will be lost - like every 5-7 lines. Only CRs, never anything else at this speed. At 4800, more characters are lost, at 300, the output is completely unintelligible. While at 19200, everything is fine.
Notably:
printk
s onlyExample - sync
will trigger two calls to list_buffer_status()
:
tlvc16# stty 1200
tlvc16# sync
f / ptt
2 0/9 7/5 UL
3 7/8 3/5 L
3/9 2/5 L
5 5/8 4/5 L
7 /8 3/5 L
9 2/8 5/02 L
0
2/c2 5/5 L
2 5/9 9/02 L
4 1/ce 16/5 L
4 0/9 6/02 L T uss /(r La 9a 9e 4
u k sanB
2 0/9 7/5
L
3 7/8 12/5 L
3/9 2/5 L
5 5/8 /5 L
7 /8 3/5 L
9 2/8 5/02 L
0 2/c2 5/5 L
2 5/
9 9/02 L
4 1/ce 16/5 L
4 0/9 6/02 L T uss /(r La 9a 9e 4
tlvc16#
tlvc16# stty 4800
5?
tlvc16# sync
# u/h bkdv lg 1a ctBn
2 0/c92 7/052 L0 0 0
3 7/c86 132/052 L0 0
4 1/c9e 72/052 L6 0 0
5 5/c8e 4/052 L0 0 0
6 8/c8a 66/052 L0 0 0
8 1/c9e 1
06/052 L0 0 0
9 0/c9a 6/052 L0 0 0
2: 0/c8a 3/052 L1 0 0
2 2/c82 75/050
L0 0 0
3 2/c92 5/052 L9 0 0
otlL ufr ns 0/2 (2 re) 1kL mp 23ump 13rmp 442
# u/h bkdv lsLmpMntBn
2 1/c92 7/052 L4 0 0
3 7/c86 132/052 L0 0 0
4 3/c9e 72/052 L0 0 0
5 5/c8e
4/052 L0 0 0
6 8/c8a 66/052 L0 0 0
8 2/c9e 106/052 L8 0 0
9 0/c9a 6/052 L
0 0 0
0 0/c8a 3/052 L1 0 0
2 2/c82 75/052 L0 0 0
3 2/c92 5/052 L0 0 0
oa
2bfer ns 0/2 (2 re, 1kL mp 23ump 13rmp 442
tlvc16#
tlvc16# stty 9600
????
tlvc16# sync
# buf/bh blk/dev flgs L1map Mcnt Bcnt
2: 10/c902 17/0502 U L04 0 0
3: 7/c8c6 1342/0502 U L03 0 0
4: 13/c93e 782/0502 U L06 0 0
5: 5/c89e 14/0502 U L02 0 0
6: 8/c8da 696/0502 U L05 0 0
8: 21/c9de 1086/0502 U L08 0 0
19: 20/c9ca 16/0502 U L07 0 0
20: 0/c83a 23/0502 U L10 0 0
22: 2/c862 785/0502 U L01 0 0
23: 22/c9f2 15/0502 U L09 0 0
Total L2 buffers inuse 0/24 (24 free), 10k L1 (map 203 unmap 193 remap 4446)
# buf/bh blk/dev flgs L1map Mcnt Bcnt
2: 10/c902 17/0502 U L04 0 0
3: 7/c8c6 1342/0502 U L03 0 0
4: 13/c93e 782/0502 U L06 0 0
5: 5/c89e 14/0502 U L02 0 0
6: 8/c8da 696/0502 U L05 0 0
8: 21/c9de 1086/0502 U L08 0 0
19: 20/c9ca 16/0502 U L07 0 0
20: 0/c83a 23/0502 U L10 0 0
22: 2/c862 785/0502 U L01 0 0
23: 22/c9f2 15/0502 U L09 0 0
Total L2 buffers inuse 0/24 (24 free), 10k L1 (map 203 unmap 193 remap 4446)
tlvc16#
tlvc16# stty 19200
_?mE
tlvc16# sync
# buf/bh blk/dev flgs L1map Mcnt Bcnt
2: 10/c902 17/0502 U L04 0 0
3: 7/c8c6 1342/0502 U L03 0 0
4: 13/c93e 782/0502 U L06 0 0
5: 5/c89e 14/0502 U L02 0 0
6: 8/c8da 696/0502 U L05 0 0
8: 21/c9de 1086/0502 U L08 0 0
19: 20/c9ca 16/0502 U L07 0 0
20: 0/c83a 23/0502 U L10 0 0
22: 2/c862 785/0502 U L01 0 0
23: 22/c9f2 15/0502 U L09 0 0
Total L2 buffers inuse 0/24 (24 free), 10k L1 (map 203 unmap 193 remap 4460)
# buf/bh blk/dev flgs L1map Mcnt Bcnt
2: 10/c902 17/0502 U L04 0 0
3: 7/c8c6 1342/0502 U L03 0 0
4: 13/c93e 782/0502 U L06 0 0
5: 5/c89e 14/0502 U L02 0 0
6: 8/c8da 696/0502 U L05 0 0
8: 21/c9de 1086/0502 U L08 0 0
19: 20/c9ca 16/0502 U L07 0 0
20: 0/c83a 23/0502 U L10 0 0
22: 2/c862 785/0502 U L01 0 0
23: 22/c9f2 15/0502 U L09 0 0
Total L2 buffers inuse 0/24 (24 free), 10k L1 (map 203 unmap 193 remap 4460)
tlvc16#
Under high load, ktcp
may fail to open new connections and eventually hang completely. The issue is very timing sensitive. even the smallest printf
in related code eliminates the problem. Even rearranging some code in the ktcp.c
main loop is enough to change the behaviour (but not to eliminate the problem).
Here's the scenario most likely to repeat the problem (this is on a AMI386SX/40 SBC):
telnet
into TLVC, issue the command hd /dev/hda
- which will run for a long time.ftp
. A message should say connect <something>
, then the ftp
client would hang. The output in the telnet
window will continue. If the client ftp
command does not hang, ktcp
is working normally and will continue to do so for a while. Try again in a few minutes, run some other commands in the meanwhile. And make sure there aren't any debug statements in the code that emit output during the opening of connections.ftp
command hangs, issue a netstat
command from the console or a serial terminal window. this will hang and the output in the telnet
window will stop. Interrupt the hanging netstat
with ^C and the output in the telnet
window will continue. This stop/start sequence is repeatable any number of times.ftp
connection from the client is likely to hang ktcp
completely (and make all network processes uninterruptible, including netstat
).telnet
session may have the same effect (or not), this part is unpredictable.The ftp
startup sequence that hangs gets through the first few packets, then stops:
10.0.2.2.34938 > 10.0.2.17.ftp: Flags [S], cksum 0x1841 (incorrect -> 0xd3e1), seq 1108791349, win 29200, options [mss 1460,sackOK,TS val 2374025631 ecr 0,nop,wscale 7], length 0
12:48:23.230917 00:80:29:ef:d9:51 (oui Unknown) > b8:27:eb:9a:77:bc (oui Unknown), ethertype IPv4 (0x0800), length 64: (tos 0x0, ttl 64, id 558, offset 0, flags [none], proto TCP (6), length 44)
10.0.2.17.ftp > 10.0.2.2.34938: Flags [S.], cksum 0x2338 (correct), seq 1057845702, ack 1108791350, win 4380, options [mss 1460], length 0
12:48:23.231067 b8:27:eb:9a:77:bc (oui Unknown) > 00:80:29:ef:d9:51 (oui Unknown), ethertype IPv4 (0x0800), length 54: (tos 0x0, ttl 64, id 55864, offset 0, flags [DF], proto TCP (6), length 40)
10.0.2.2.34938 > 10.0.2.17.ftp: Flags [.], cksum 0x182d (incorrect -> 0xda00), seq 1, ack 1, win 29200, length 0
12:48:23.235371 00:80:29:ef:d9:51 (oui Unknown) > b8:27:eb:9a:77:bc (oui Unknown), ethertype IPv4 (0x0800), length 282: (tos 0x0, ttl 64, id 559, offset 0, flags [none], proto TCP (6), length 268)
IOW, ktcp
accepts the connection by responding with a SYN-ACK, and the client follows with an ACK as appropriate, and it seems like this ACK is never registered on the TLVC side of the connection.
I lot of time has been spent on tracking down the problem, with little success so far. It seems likely though that the problem is located in the devtcp
code
sign-compare -Wno-cast-qual -Wno-unused-parameter -Wno-missing-prototypes -Wno-empty-body -c -o super.o super.c
super.c:19:28: fatal error: linuxmt/devnum.h: No such file or directory
#include <linuxmt/devnum.h>
ls: cannot access 'tlvc/include/linuxmt/dev*': No such file or directory
the file dose not exist
The raw floppy driver doesn't check that the requests are physically possible. With 20b (10k) being the (currently) largest possible block, all IO requests on a 360k floppy will fail (2 tracks = 1 cylinder = 2x9 sectors = 18 blocks), the driver reporting an unknown error
. Using the track size as block size in such cases will work and is the preferable workaround.
This problem will occur with any block size if the request spans a cylinder boundary. e.g. dd if=/dev/rdf0 skip=17b bs=2b
will fail on a 360k floppy.
[I've just noticed that this happens, not attempted to analyze what's going on yet]
When ktcp
receives IP packets with checksum errors, it reports (prints) the error, then discards the packet. Fine, except the tcp level doesn't notice that there is a packet missing. Thus no NAK and no request for a retransmit. The incoming file (if it's a file transfer) ends up short - and ftp
thinks everything is just fine.
The sending ftp client reports the correct number of bytes transferred - as expected, what the receiving ftpd
thinks must be looked at.
When mounting a 10MB FAT12 file system (on an ancient 10MB MFM drive), the ts=
value reported on the console looks suspicious:
FAT: me=f8,csz=8,#f=2,floc=1,fsz=8,rloc=17,#d=512,dloc=49,#s=20723,ts=-1006632960
FAT: total 10M, fat12 format
The functionality seems unaffected but testing has been limited by driver related issues.
BTW, ELKS reports the exact same numbers.
Hello @Mellvik,
I just happened to run across your project... you have been very busy!! And very nice job, in particular with getting both the FD and HD direct drivers running, along with a fully interrupt-driven I/O subsystem :) Your research and comments on each PR are quite interesting and it is great to hear that TLVC I/O runs quite a bit faster than ELKS as a result. I am interested to learn more about short-term vs long term speedups as well.
If you are interested, I have a number of questions and/or comments about the side-effects of a kernel that now may be reentered (not actually, but effectively through other tasks that might get awakened within a previously-wait-to-I/O-completed system call), as well as thoughts on how to fully eliminate all BIOS dependencies, which it sounds like could be a goal of TLVC.
I thought to open this issue for comments, as well as possibly comment or question on various open issues and commits, if you would like.
Thank you!
When using mv
to move a file off a FAT file system, the file space is not released and the file system becomes un-umount
able.
Using cp
and rm
works fine. Repeatable on floppies and HD file systems.
fsck
reports perfectly valid minix file systems as not a minix file system, perhaps DOS?
on 360k floppies.
While rounding up the work on issue #20 , I noticed that doing a df
on a mounted FAT volume generates an enormous amount of unmaps/remaps of the same block. Enormous = 487
Even on a small (17M) FAT volume, df
is notoriously time consuming - if significantly better today than a couple of years ago (ELKS). I have been assuming that the reason was lots of disk reads to gather required data, but 17 consecutive blocks isn't much (the metric seems to be 1 block per MB for FAT16, 41 consecutive blocks on a 41M volume).
Watching the 487 maps/unmaps per block - and (notably) not having looked at the code - it seems there must be some optimization potential, best case at the FS level, worst case in the df
code itself.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.