On trying to extract files from a Texas Instruments S1500

So this started out as a weird thing that killed a day for me. I thought it was a little fun to look at but, ultimately I proved that I could extract files, but not from the requested image.

So let’s get into some more details, my failure, and well it’s been raised into another chance for some luck/fast knowledgeable hacker to get a payout to extract a single file.

As mentioned above the computer is the Texas Instruments S1500, the disk image was dumped on bitsavers years ago as s1505_cp3540/s1505_cp3540.dd.gz. As you may guess it’s a raw ‘dd’ of a disk.

Now looking at a few sources namely unix-ag the OS in question is TI System V, an AT&T SVR3.2 derivate. Running strings does reveal ‘SysVr3TCPID’ And this appears to be the Unix Version Banner:

(c)Copyright 1993 Hewlett-Packard Company,  All Rights Reserved.
(c)Copyright 1986-1992 Texas Instruments Incorporated,  All Rights Reserved.
(c)Copyright 1984-1988 AT&T, All Rights Reserved.
(c)Copyright 1979, 1980, 1983, 1985-1990 The Regents of the Univ. of California
(c)Copyright 1980, 1984, 1986 Unix System Laboratories, Inc.
(c)Copyright 1990 Motorola, Inc.
(c)Copyright 1989-1990 The Santa Cruz Operation. All Rights Reserved.
                         RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the U.S. Government is subject to
restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
Technical Data and Computer Software clause in DFARS 252.227-7013.
                         Hewlett-Packard Company
                         3000 Hanover Street
                         Palo Alto, CA 94304 U.S.A.
Rights for non-DOD U.S. Government Departments and Agencies are as set
forth in FAR 52.227-19(c)(1,2).

Along with further extraneous info like:

TI Sys V
V/68-1.0
3.3.2
MC680X0
Hewlett-Packard 9000 Series 1500

Fantastic. Well digging around you’ll eventually find that SYSV filesystems have a magic number, and it’s 0xfd187320

So a simple search through the raw filesystem reveals some:

neozeed@remlazar:/mnt/c/temp$ xxd s1505_cp3540.dd | grep 'fd18 7e20 0000 0002'
0035b7f0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....
00f5b7f0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....
02f5bff0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....
04cc0bf0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....
0505bff0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....
1f1267f0: 0000 0000 0000 0000 fd18 7e20 0000 0002  ..........~ ....

And this fits the bill, as the next 32bit ‘word’ is the version, in this case 2 to indicate 1024k blocks ,and improvement added to SYSVr2. One thing is that the struct to read a super block is 512bytes (or is it always?), and the magic number is near the end, so from the above offsets, subtract 496 (decimal!) and you can get the start and sizes of each filesystem. Fantastic!

Speaking of SYSVr2, Do you know what is another SYSVr2? A/UX.

Shoebill was panned for not emulating the full Macintosh, rather it reads the kernel directly from the filesystem, and boots into it. That means Shoebill can read UFS/SYSV. Great start?

So I took the filesystem code from Shoebill, hacked it enough to let me build on Visual Studio, and point it to a raw filesystem and take a look. I put it here: filesystem.c

Now I’m impatient so it still needs a legit Apple A/UX virtual disk. Granted we don’t need it, but it made it easier to let the existing code fiddle with apple partitions, but when it comes time to read SYSV blocks, I closed the file handle and swapped things around. And that lead to this:

As you can see there is a LOT of zeros. However the magic & type align.

Meanwhile here is what an A/UX SYSV filesystem looks like. Notice far less zeros.

Additionally I was able to get another 68k based SYSV Unix disk, and yeah not all zeros. Also yes, using the Shoebill code it extracted files just fine.

However using my approach on the filesytem I always only get a directory with 2 enteries the ‘. ..’. I modified the source to just count inodes and write them to disk. And use inode 2 is just a tiny file. No doubt with all the zeros the disk is either very corrupted (backup superblocks?! where?! how?!) or the kernel implicitly knows these things, or finds them somewhere else.

I’ve been authorized to give a bounty of $200 USD to be able to extract arbitrary files from the 1505 disk image. I thought I’d give it a shot, but I don’t get how the super block aligns but the data doesn’t. Unless there is some other insane padding thing for a 1k superblock? The more I think about it, it’s probably likely as I know at some point I was skipping 3 blocks from an offset to get to a superblock, and 3 is just a weird number. 1 block header, 2 block superblock makes more sense.

Additionally this table may prove useful, especially for the ‘skip 3’ or pad to 1k:

Tape and disk utility is in progress...

26 partitions, 12-longword descriptors:
     Name    Start    Length   User  Comments
1  * LABL vl 0        2        FFFF
2  * PTBL pt 2        3        FFFF
3    SAVE sb 5        3        FFFF
4    FMT  fp 8        9        FFFF
5    TZON tz 17       296      FFFF
6  * unx1 lb 313      1024     0002  TI Sys V 3.3.2
7  * unx1 lb 313      1024     000A  TI Sys V 3.3.2
8  * unx1 lb 313      1024     0013  TI Sys V 3.3.2
9  * unx1 lb 313      1024     0014  TI Sys V 3.3.2
10   unx2 lb 1337     1024     0002  TI Sys V 3.3.2
11   unx2 lb 1337     1024     000A  TI Sys V 3.3.2
12   unx2 lb 1337     1024     0013  TI Sys V 3.3.2
13   unx2 lb 1337     1024     0014  TI Sys V 3.3.2
14   unx3 lb 2361     1024     0002  TI Sys V 3.3.2
15   unx3 lb 2361     1024     000A  TI Sys V 3.3.2
16   unx3 lb 2361     1024     0013  TI Sys V 3.3.2
17   unx3 lb 2361     1024     0014  TI Sys V 3.3.2
18 * cfg1 cb 3385     17       FFFF  TI Sys V 3.3.2
19   cfg2 cb 3402     17       FFFF  TI Sys V 3.3.2
20   cfg3 cb 3419     17       FFFF  TI Sys V 3.3.2
21 * root fb 3436     12288    FC02  TI Sys V 3.3.2
22   usr  fb 15724    32768    FC02  TI Sys V 3.3.2
23   jdis an 48492    2        FFFF  multi-volume file system anchor
24   pipe fb 48494    1024     FC02  pipe file system partition
25 * swap pb 49518    32768    0002
26   prt1 fb 82286    448972   FC02  part of jdis multi-volume

Did you know there is almost nothing left to document that this poor machine even existed?

Seriously look for “TI System V”

Heck even on the UTZOO archives..

AltaVista UTZOO search (superglobalmegacorp.com)

It’s like 5 posts, 3 being the same, someone who couldn’t dial out, and someone on the old UUCP map! Save me!

17 thoughts on “On trying to extract files from a Texas Instruments S1500

  1. Happy to hear you found the stuff I put on the unix-ag servers 25 years ago :). The TI1500 System V also supported volume management and a file system could be spread over multiple disks.

    I don’t have a S1500 any longer, but let me know if you have any questions… we have some TI Explorers in the museum here, but none of these seems to be the hybrid S1500/Explorer system.

    • Btw, the picture in the article shows an Explorer Lisp machine – it used the same NuBus-based chassis as the “big” S1500 machines (the S1505/07/08 used a smaller case) and also some of the same peripherals such as the NUPI SCSI controllers. The S1500 used TI924 or TI928 (rebranded HP) serial terminals.

    • YES if you have the gcc/binutils stuff anymore? The ftp site.. well it’s offline. I’d be interested in that. Also any backups? Namely /usr/include/sys ? I can’t tell what is going on but doing strings on the tapes & disk image on bitsavers is missing braces, and seemingly cut (at the same place!) on all kind of struct defintions. So it looks like TI modified the SYSVr2 1k superblock to be 1kb instead of 512bytes, and their inode structure is different too, although I’m just guessing and getting nowhere. If you have any of that stuff it’d be super apprecaited…

      Too bad you don’t have the machine it’d take a few minutes to pull it from a living one. 😐

      • Yes, the ftp server was taken offline years ago, but I have a backup of the gcc, gdb and binutils sources – got these from TI on a QIC tape in the ’90s. Header files are not included, unfortunately. Beware, the gcc (1.37) port is a horrible hack, it’s mostly #ifdef ti1500 sections in the hp9000/300 backend… https://multicores.org/ti1500/

        I don’t have a file system backup of the 1500 (at least here in Norway), but I’ll try to see if I can find something…

        • wow cool! Thanks! At a minimum it’ll let me test some drift, along with this other TI machine to see if it’s even really all that compatible. grepping those strings there is a few TI finger prints in critical stuff that basically ensure that they’d never run anything from anyone else.

          It’s amazing how little there is online about these machines.

          The older GCC seems to have been a little easier to patch around although there is still a lot of mystery in it to me. Most fun I had was with was getting 1.27 to target MS-DOS and get 99% of DooM working with it (only the fixed point math needed a newer version).

          • Im so sorry for bugging you.. .turns out the inode structure on disk is different from memory. 😐

            ino.h

            	/* Inode structure as it appears on a disk block. */
            struct dinode
            

            What is strange is doing a strings on the disk has it missing braces.. and I never can tell if it’s the end of the file if it was contiguous or if it’s just broken up.. 😐

            I’m not sure if it’s missing stuff but I’m certainly not reading inodes right from the disk. 🙁

          • This is the patient 0 from A/UX (0.7 floating around has kernel source)

            struct dinode
            {
                    ushort  di_mode;                /* mode and type of file */
                    short   di_nlink;               /* number of links to file */
                    ushort  di_uid;                 /* owner's user id */
                    ushort  di_gid;                 /* owner's group id */
                    off_t   di_size;                /* number of bytes in file */
                    char    di_addr[40];            /* disk block addresses */
            #define di_gen          di_addr[39]
                    time_t  di_atime;               /* time last accessed */
                    time_t  di_mtime;               /* time last modified */
                    time_t  di_ctime;               /* time created */
            };
            

            I guess its similar enough?

    • yeah these things were rare 20-30 years ago, and now.. it’s like a mere legend.

      I’ll have to get in contact with that Museum, although in general they usually don’t poke/prod the machines too hard.

  2. OK, I did some more investigations.

    The inodes (64 bytes each) start at 0x0035b800, the second entry is the root directory inode:

    0035b840: 41ed 0011 0000 0000 0000 0200 0000 c200 A……………
    0035b850: 0000 0000 0000 0000 0000 0000 0000 0000 …………….
    0035b860: 0000 0000 0000 0000 0000 0000 0000 0000 …………….
    0035b870: 0000 0000 37f1 63a6 3573 282c 30f5 4407 ….7.c.5s(,0.D.

    The file is 512 bytes long (offset 0x08), has 0x11 hard links (that’s a lot), uid and gid of 0 and uses block 0x0000c2 (offset 0x0c, big endian byte order). Still need to find the correct encoding for the first two bytes (di_mode). The last 12 bytes are the a/m/ctime Unix time stamp, 0x37f163a6 = Wednesday, 29 September 1999 00:56:06 GMT (https://www.epochconverter.com). Sounds reasonable.

    The offset of this block of 0xc2 * 0x400 = 0x30800.

    With the start address of the partition (“load band” in TI terms) of 0x35b000, the directory starts at 0x38B800:

    0038b800: 0002 2e00 0000 0000 0000 0000 0000 0000 …………….
    0038b810: 0002 2e2e 0000 0000 0000 0000 0000 0000 …………….
    0038b820: 0003 6269 6e00 0000 0000 0000 0000 0000 ..bin………..
    0038b830: 0004 6574 6300 0000 0000 0000 0000 0000 ..etc………..
    0038b840: 0005 7573 7200 0000 0000 0000 0000 0000 ..usr………..
    0038b850: 0006 7469 0000 0000 0000 0000 0000 0000 ..ti…………
    0038b860: 0007 7368 6c69 6200 0000 0000 0000 0000 ..shlib………
    0038b870: 0008 6c69 6200 0000 0000 0000 0000 0000 ..lib………..
    0038b880: 0009 6465 7600 0000 0000 0000 0000 0000 ..dev………..
    0038b890: 000a 7069 7065 0000 0000 0000 0000 0000 ..pipe……….
    0038b8a0: 000b 7261 6d00 0000 0000 0000 0000 0000 ..ram………..
    0038b8b0: 000c 746d 7000 0000 0000 0000 0000 0000 ..tmp………..
    0038b8c0: 000d 7574 696c 0000 0000 0000 0000 0000 ..util……….

    Looks like the root directory :-). The two bytes at 0x38b800 tell us the root directory inode is #2. So it seems the inode numbers start counting at 1 and inode 1 is the first one stored at 0x35b800 (no idea what this inode actually points to, it has an empty length and block list but appropriate time stamps).

    The following inode (#3) is /bin, this points to block 0xc3 at 0x38bc00:

    0038bc00: 0003 2e00 0000 0000 0000 0000 0000 0000 …………….
    0038bc10: 0002 2e2e 0000 0000 0000 0000 0000 0000 …………….
    0038bc20: 0173 6173 0000 0000 0000 0000 0000 0000 .sas…………
    0038bc30: 0174 6163 6374 636f 6d00 0000 0000 0000 .tacctcom…….
    0038bc40: 0175 6172 0000 0000 0000 0000 0000 0000 .uar…………
    0038bc50: 0176 6261 636b 7570 0000 0000 0000 0000 .vbackup……..
    0038bc60: 017d 6261 7365 6e61 6d65 0000 0000 0000 .}basename……
    0038bc70: 017f 6361 7400 0000 0000 0000 0000 0000 ..cat………..
    0038bc80: 0180 6368 6772 7000 0000 0000 0000 0000 ..chgrp………
    0038bc90: 0181 6368 6b73 686c 6962 0000 0000 0000 ..chkshlib……
    0038bca0: 0182 6368 6d6f 6400 0000 0000 0000 0000 ..chmod………
    0038bcb0: 0183 6368 6f77 6e00 0000 0000 0000 0000 ..chown………
    0038bcc0: 0187 636d 7000 0000 0000 0000 0000 0000 ..cmp………..
    0038bcd0: 0188 636f 6d6d 0000 0000 0000 0000 0000 ..comm……….
    0038bce0: 0189 6370 696f 0000 0000 0000 0000 0000 ..cpio……….
    0038bcf0: 018c 6372 7970 7400 0000 0000 0000 0000 ..crypt………
    0038bd00: 018d 6373 706c 6974 0000 0000 0000 0000 ..csplit……..
    0038bd10: 018e 6374 7261 6365 0000 0000 0000 0000 ..ctrace……..
    0038bd20: 018f 6374 6372 0000 0000 0000 0000 0000 ..ctcr……….
    0038bd30: 018f 6374 6300 0000 0000 0000 0000 0000 ..ctc………..

    Looks like /bin!

    So that doesn’t solve the problem completely, but maybe it’s a step in the right direction… hope it helps :).

Leave a Reply