Technical:
5/5 multitools: We hack a kernel driver for starters. C proficiency is a really good idea.
Sanity:
51/50 straight jackets: We should be committed
"Linux is a semi... Windows is a car.... TempleOS is a motorcycle -- if you lean-over too far, a motorcycle will crash. Don't do that!"
"TempleOS is a x86_64, multi-cored, non-preemptive multi-tasking, ring-0-only, single-address_mapped (identity-mapped), operating system for recreational programming. The people whom can most benefit are:
TL;DR
New software for TempleOS:
"The vision for this operating system was a modern Commodore 64, which was a fun toy." TempleOS is evocative of an era:
Code that fails this test is bad code
Thesis: Linus Torvalds developed Git in a hurry
In a 2007 thread called Trivia: When did git self-host?
In a 2007 thread called Trivia: When did git self-host?
In an LKML thread called Kernel SCM saga..
Git is functional, self-hosting, over-engineered, and has been re-named at least once:
Git "features":
The first prototype of Git consisted of 8 C files
Conclusion: With SHA-1 and zlib compression, you can write a Git client
But what does Git do? It:
By design, everything else is icing
What does git add EmptyFile.txt do?
The Git index is complicated.
Back in the "Kernel SCM saga.." thread 1 2
At this point, Git's over-engineered, under-baked core design has been finalized
Git retains several weekend hackish design flaws:
Conclusion: For an SCM, Git was poorly designed. For a file system, it's also poorly designed.
RedSea stores the core kernel dir entry data structure
#define CDIR_FILENAME_LEN 38 //Must include terminator zero public class CDirEntry { CDirEntry *next,*parent,*sub; U8 *full_name; I64 user_data,user_data2; U0 start; U16 attr; U8 name[CDIR_FILENAME_LEN]; I64 clus,size; CDate datetime; };
The core kernel dir entry data structure is 64 bytes
#define CDIR_FILENAME_LEN 38 //Must include terminator zero // "fixed-sized 64-byte directory entries" // means these 64 bytes: U0 start; // 0 bytes U16 attr; // 2 bytes U8 name[CDIR_FILENAME_LEN]; // 38 bytes I64 clus,size; // 16 bytes CDate datetime; // 8 bytes
The core kernel dir entry data structure is 64 bytes
#define CDIR_FILENAME_LEN 38 //Must include terminator zero U8 name[CDIR_FILENAME_LEN]; // 38 bytes
What about FAT32?
FAT32 allows filenames beyond the DOS-style 8.3 syntax
FAT32 allows filenames beyond the DOS-style 8.3 syntax
https://en.wikipedia.org/wiki/VFAT_long_filename
Thank you for coming to my talk.
Wait a sec:
Hmmm....
Because strings must end with '\0', CDIR_FILENAME_LEN (38) is 1 byte too small for a Git object file name.
We need to:
To write a Git object to disk in TempleOS:
1. Increase CDIR_FILENAME_LEN (38) by 1
In /Kernel/KernelA.HH:
- #define CDIR_FILENAME_LEN 38 + #define CDIR_FILENAME_LEN 39
2. An assertion in FileSysRedSea.HC must be commented out
In /Kernel/BlkDev/FileSysRedSea.HC:
- #assert CDIR_SIZE==64 + //#assert CDIR_SIZE==64
4. FAT32 driver must be patched to support 1 more LFN record
In /Kernel/BlkDev/FileSystemFAT.HC, edit:
Look for mentions of "13" and "26"
switch (de->ord&0x3F) { case 1: for (i=0;i<13;i++) if (!(tmpde->name[i]=ptr[fat_long_name_map[i]])) return TRUE; break; case 2: for (i=0;i<12;i++) if (!(tmpde->name[i+13]=ptr[fat_long_name_map[i]])) return TRUE; break; }
Add the extra record:
case 2: - for (i=0;i<12;i++) + for (i=0;i<13;i++) if (!(tmpde->name[i+13]=ptr[fat_long_name_map[i]])) return TRUE; break; + case 3: + for (i=0;i<13;i++) + if (!(tmpde->name[i+2*13]=ptr[fat_long_name_map[i]])) + return TRUE; + break;
Look for mentions of "13" and "26"
if ((l=StrLen(tmpde->name))>13) { ... ld[de_cnt].attr=RS_ATTR_LONG_NAME; for (i=13;i<l;i++) ptr[fat_long_name_map[i-13]]=tmpde->name[i]; i++; for (;i<26;i++) ptr[fat_long_name_map[i-13]](U16)=0xFFFF; ...
Insert new logic before old name length check
+ l=StrLen(tmpde->name); + if (l>2*13) { + ... + for (i=2*13;i<l;i++) + ptr[fat_long_name_map[i-2*13]]=tmpde->name[i]; + i++; + for (;i<3*13;i++) + ptr[fat_long_name_map[i-2*13]](U16)=0xFFFF; + l=2*13; + } - if ((l=StrLen(tmpde->name))>13) { + if (l>13) {
A patched FileSysFAT.HC:
DEFLATE is designed for LZ77 compression, but supports uncompressed blocks as well.
"Blocks" add headers and a checksum, "uncompressed" is null-compression
Use zpipe to read git objects without "git cat-file":
$ git cat-file -t e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 $ git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 \ | wc -c
Output:
blob 0
Use zpipe to read git objects without "git cat-file":
$ cd .git/objects/e6 $ zpipe -d < 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 \ | od -vAx -t x1z
Output:
000000 62 6c 6f 62 20 30 00 >blob 0.< 000007
Use zpipe to read git objects without "git cat-file":
$ cd .git/objects/cf $ zpipe -d < 91034ac3780fd8b2392442a69430b6cef94cef \ | od -vAx -t x1z
Output:
000000 62 6c 6f 62 20 37 00 48 69 20 6d 6f 6d 21 >blob 7.Hi mom!< 00000e
Hack zpipe.c to write uncompressed blocks:
- ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION); + ret = def(stdin, stdout, 0);
Find all files and lengths:
find . -type f -size +65535c -exec ls -l {} \; \ | awk '{print $5 " " $NF}' | sort -rn
Run Unzip("C:/",FUF_RECURSE); so you can grep but remember:
} else if (FileFind("::/Doc/StandBy.DD.Z")) Type("::/Doc/StandBy.DD.Z",0);
Learn HolyC by reading HolyC. Search codebase with ripgrep and fzf:
set RG_PREFIX "rg --column --line-number \ --no-heading --color=always --smart-case "
fzf --bind "change:reload:$RG_PREFIX {q} || true" \ --ansi | awk -F: '{print $1}' | xargs -r less
More on fzf: Bread on Penguins - "fzf, everyone's favorite fuzzy finder" - YouTube
U8 *buf, *header; I64 size; buf=FileRead("EmptyFile.TXT",&size); header=MStrPrint("blob %d",size);
#define DEFLATE_CHKSUM_LEN 4 #define DEFLATE_HEADER 2 #define DEFLATE_BLOCK 5 I64 obj_len=StrLen(header)+1 + size + DEFLATE_CHKSUM_LEN + \ DEFLATE_HEADER + DEFLATE_BLOCK; U8 *obj=MAlloc(obj_len); obj[0](U16)=0x0178; // RFC-1951 Deflate header obj[DEFLATE_HEADER_LEN]=1; obj[DEFLATE_HEADER_LEN+1]=size&0xFF; obj[DEFLATE_HEADER_LEN+2]=(size>>8)&0xFF; obj[DEFLATE_HEADER_LEN+3]=~obj[DEFLATE_HEADER_LEN+1]; obj[DEFLATE_HEADER_LEN+4]=~obj[DEFLATE_HEADER_LEN+2];
U8 *ptr; ptr=obj + DEFLATE_HEADER_LEN + DEFLATE_BLOCK; MemCpy(ptr,header,StrLen(header)); ptr+=StrLen(header); *ptr++=0; // the '\0' in 'blob X\0' MemCpy(ptr,buf,size);
#include "Sha1.HC"; Sha1Context ctx; I64 i,j; U32 tmp; U8 *digest_str,*digest_bytes; Sha1Init(&ctx); Sha1Update(&ctx,obj + \ DEFLATE_HEADER_LEN + DEFLATE_BLOCK,size+StrLen(blob)); digest_str=Sha1Final(&ctx); for(i=0;i<5;i++) { tmp=EndianU32(ctx.state[i]); for(j=0;j<4;j++) { digest_bytes[(4*i)+j]=tmp&255; tmp>>=8; } }
U8 *dir=MStrPrint(".git/objects/%c%c/", digest_str[0], digest_str[1]); U8 *file=MStrPrint("%s", digest_str+2); DirMk(dir); Cd(dir); FileWrite(file,obj,obj_len);
But what does all of this look like?
1 Except for mtimes, even though Git tracks them to the nanosecond
What has Git done for TempleOS? Three "D"s:
This led me to ask myself a question
Why are we so dependent on Git? Common arguments:
Git is 20 years old. Did good software development practices not exist before 2005? What else is there?
"Three minutes before the lunar lander reached the Moon's surface... alarms were triggered. The [computer] was designed to support seven simultaneous programs running, but Aldrin’s request was the eighth. The result was a series of unexpected error codes during the live descent. The on-board flight software captured these alarms with the 'never supposed to happen displays'.... Hamilton had prepared for just this situation years before[.]"
"Three minutes before the lunar lander reached the Moon's surface... alarms were triggered. The [computer] was designed to support seven simultaneous programs running, but Aldrin’s request was the eighth. The result was a series of unexpected error codes during the live descent. The on-board flight software captured these alarms with the 'never supposed to happen displays'.... Hamilton had prepared for just this situation years before[.]"
Good software engineering existed before 2005.
What is it?
Implementable in TempleOS, but Got keeps Git's broken workflow
Necessity is the mother of invention
What if you just want to save your Thursday stuff? Use Bak.HC.
U8 *Bak(U8 *file_find_mask=NULL) { Date2Struct(&ds,Now); dst=MStrPrint("~/Backup/%d%02d%02dT%02d%02d%02d", ds.year,ds.mon,ds.day_of_mon,ds.hour,ds.min,ds.sec); DirMk("~/Backup"); DirMk(dst); tmpde=de=FilesFind(file_find_mask,FUF_JUST_FILES); while(tmpde) { Copy(tmpde->full_name,dst); tmpde=tmpde->next; } DirEntryDel(de); Cd(dst); Sha1Sum(dst,"sha1sum.TXT",FALSE); return dst; }
Bool WriteNote(U8 *dir=NULL) { cd=DocNew; DocFlagsToggle(cd,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR); DocPrint(cd,"\n\n# Enter notes; comment ends at '#'\n"); DocEd(cd); buf=DocSave(cd); DocDel(cd); i=StrFind("\n#",buf)-buf; while (0x0A==buf[--i]) buf[i]=0; file=MStrPrint("%s/notes.TXT",dir); if (0<i) FileWrite(file,buf,1+i); Free(buf); Free(file); return FALSE; }
Features:
How do I...?
Git on TempleOS: functional, barely, but what did we learn?
Git won the source control war. BitKeeper went open source in 2016 and BitMover went out of business in 2018.
"[M]y biggest regret [about the license] is not money, it is that Git is such an awful excuse for an SCM. It drives me nuts that the model is a tarball server. Even Linus has admitted to me that it's a crappy design. It does what he wants, but what he wants is not what the world should want."
Git on TempleOS: functional, barely, but what did we learn?
"OSS maxim: Is there something you are looking for and it's not available? Then build it."
If it doesn't satisfy these principles, it doesn't belong in TempleOS.
New software:
Available at https://su.bze.ro/software.html