Retro UNIX 386 v2 için kernel programlama/geliştirme notları... (Erdoğan Tan).. Tarih sırasına göre günlük taslak notlar. ------------------------------------------------------------------------------ (Yapılmış ve yapılacak işlemleri/değişiklikleri açıklamak ve hatırlamak için.) benioku.txt'den devam.. (O dosyanın sonunda Retro UNIX v1.2, Kernel v0.2.2.0 tamamlanmış oldu) ..burada yazdıklarım Retro UNIX v1.2, Kernel v0.2.2.1'in geliştirme notları. 09/05/2022'de.... 1) u2.'s'de sysexec'de argument listi (ecore+pagesize) olan sanal bellek sonundan 4 byte geri çektim (lodsd ve dword move konutlarından) argument list sonuna doğru genel protection fault -v1.1'de mount programını denerken karşılaştım- oluşmaması için önlem aldım. (örnek: stack'tan argument count çekilir ve son argument pointerden sonra son argument -asciiz string- lodsb yerine lodsd ile alınırsa bellek sonuna denk gelen argument sonunda gpf oluşabiliyor. Yaptığım değişiklik bu olasılığı engellemek için. 2) u2.s'de sysstat sadece inode number ve inode structure döndürüyordu. 'pwd' ve 'cp' gibi programlarda mounted device number gerektiği için, en uygun ve eskiyle (önceki programlarla) uyumlu yöntem olarak inode'un aygıt/disk numarasını eax'de döndürecek ekleme yaptım. Root ise 0, mounted ise 1 dönüyor. (1 olmak zorunda değil ama [idev] veya [cdev] içindeki sayı doğrudan disk numrası değil; 0 ise root dev olduğunu ve disk numarasının [rdev] de olduğunu, 1 ise mounted dev olduğunu ve disk numarasının [mdev] de olduğunu gösteriyor. Orijinal unix v1 yöntemi böyle. Retro UNIX de sadece disk numaraları farklı.). 3) diskinit.s içindeki 'set_disk_parms' prosedüründe değişiklik yaptım. Artık 1 silindiri ayırmadan ne kadar silindir varsa, disk kapasitesi cylinders*spt*heads olarak doğru hesaplanıyor. (Eski haliyle son silindir hesaba katılmıyordu ve drv.size'a eksik sector count kayıtlanıyordu.) Düzeltme monte edilen (mounted device) dosya sisteminin (sysmount içinde) geçerlilik kontrolü işlemi olarak, free map byte count ile disk size kıyaslamasında doğru sonuç almak için gerekti. Örneğin: 360 byte olan fd0 süperbloku free map byte sayısı (offset 0'daki word) 360*8 = 2880 sektöre karşılık geliyor ama 80*18*2 olması gerekirken, 79*18*2 hesaplanan disk.size free map bit size ile karşılaştırıldığında geçersiz süperblok (içeriği) sonucuna yol açıyordu. Bunu düzelttim. 4) sysmount içinde [rdev] içndeki disk numarasının ait olduğu diskin mount yapılmasını önleyen (yani root diskinin kendi alt dizinine mount edilmesini önleyen) değişiklik yaptım. /dev/fd0 device numarası 0 olduğu için, boş anlamındaki [mdev] = 0 ile çakışıyordu. /dev/fd0 için umount yapılırken mount durumu olmadığı halde, [mdev] içindeki disk numarası 0 ile /dev/fd0 numrası eşit olduğundan umount başarılıymış görünüyordu. Önce [mnti] içinde mounting directory numarasının olması şartını kontrol ettirerek bunu önledim. Çünkü mounted device yok ise [mnti] = 0 oluyor. Aksi takdirde sıfır olmuyor. 15/05/2022'de.... 1) u2.s'de 'namei' içinde 'pwd' komutuna göre '..' parent directory linkin (mounted device durumu var ise) doğru çalışması için ekleme yaptım ([cdev]=1 ve [ii]=1 olursa ve '..' istenmiş ise, mounting directory'in parent dir ('sysmount' onu [mntp] içine kayıtlıyor) inode numarası döndürülüyor. ((bu ekleme/değişiklik 'pwd' komutu path çıktısının doğru olmasını sağlıyor.) Tabii ki mounted device içine dosya yazma yaparken path'in doğru olmasını da sağlamış oluyor. Geriye doğru gidişte '..' kullanıldığından , değiiklik doğru oldu.)) 2) u7.s'de 'sysmount' için [mntp] alanına mounting dir'nin parent dir'sinin kayıtlanması değişikliğini yaptım. [mntp] içinde kayıtlı inode numarasını 'namei' kullanıyor (yukarıda açıkladım). Ayrıca 'sysumount' dosya sisteminin bir dizinine monte edilmiş aygıtı device dosya adı doğru yazılmışsa demonte (dismount) ediyor. Bu esnada, eğer kullanıcı ([u.cdir]) demonte olan dizinde ise ([u.cdrv]=1), [u.cdir] shell'in çalıştırdığı child prosese ait olduğundan, /etc/umount'tan dönüşte parent prosesin -shell'in kullanıcıya ait kopyesinin- doğru dizine yerleşmesi için (yani demonte olan device 1 dizinlerinden çıkıp mounting directory'e kadar geri gidecek), parent prosesi 'p.ppid', 'p.pid' arama/karşılaştırması ile bulup, onun 'p.upage' değerinden, upage'indeki user structure'ında u.cdir ve u.cdrv değerleri değiştiriliyor. [mnti]=0 olurken, sırlamadan önceki mnti değeri parent'in 'u.cdir' alanına kayıtlanıyor ve parentin 'u.cdrv' ralaı sıfılanıyor (0 = root fs). Bu işlem umount'tan hemen sonra ('/etc/umount') root fs'deki mounting directory'inin asıl içeriğinin görülmesini saplıyor (ve yukarıda açıklanan faydası oluyor). 3) ux.s'de [mntp] dword alanı açtım. (bss'te).. 02/06/2022'de .... sysstime (set unix epoch time) sistem çağrısında, ayarlanacak epoch değerini içeren ebx register'ının set_date_time prosedüründe kullanıldığı yerden önce temizlenmesi gerekirken, eski değeriyle bırakılması, hatalı tarih/saat kayıtı yapılmasına yol açıyordu. Bunu hatayı düzeltim ve set_date_time kodunda iyileştirme yaptım. 08/06/2022'de .... ux.s içinde 4 byte'lık 'level:' alanını 'resd 1' olması gerekirken 'resd 0' olarak yazmam nedeniyle (indirekt blok içeren 5120 byte ve üstü büyüklükte dosyaları kopyelerken) u5.s'deki 'mget' içinde (bss kesimindeki 'level' alanının dword olarak ayrılmış olmaması dolayısıyla) 5120 byte ve üstü yeni dosyalarda yeni sektör/block oluşturma işlemi kilitleniyordu (sonsuz döngüye giriyordu); bugün bunu farkedip düzelttim.