OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 16, 2024 5:11 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Next Filesystem to Implement
PostPosted: Fri Feb 02, 2007 11:56 am 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
I was wondering which filesystem I should implement after FAT 12/16/32. I'm looking for something that is easy and a good step up from FAT.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 02, 2007 12:06 pm 
Offline
Member
Member

Joined: Tue Nov 07, 2006 7:37 am
Posts: 514
Location: York, England
Preferably one you already know quite well and won't have to research in such detail. Especially if you have experience with it. If not i would probably pick whatever the default is in Linux atm. Somethign like Ext2fs which is well documented will be best.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 04, 2007 9:14 pm 
Offline
Member
Member

Joined: Tue Oct 17, 2006 7:57 pm
Posts: 25
Ext2 looks pretty simple. Although I have not implemented it myself, I have looked at the spec.

Plus then you will have a nice balance of the Windows and Linux worlds. :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 3:39 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Does any one know of a good way to create and access EXT2 filesystems from withing Windows XP?

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 5:26 pm 
Offline
Member
Member
User avatar

Joined: Tue Oct 17, 2006 9:29 pm
Posts: 2426
Location: Canada
frank wrote:
Does any one know of a good way to create and access EXT2 filesystems from withing Windows XP?


A Google search showed a few results, This one is the most notable.. Looks like it's still fairly maintained...

It's under the GPL licence, Supports both read/write operations.

http://www.ext2fsd.com/

One can always just use a UNIX-like system full time though :wink:

_________________
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.


Last edited by Brynet-Inc on Tue Feb 06, 2007 4:56 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 06, 2007 12:18 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Thanks

Brynet-Inc wrote:
One can always just use a UNIX-like system full time though :wink:


I would if I could, but I don't have high speed internet, so I can't download it, and I have yet to find a UNIX-like system that works well with my WIN modem. Plus I have no money. :wink:

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject: Re: Next Filesystem to Implement
PostPosted: Tue Feb 06, 2007 3:22 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

frank wrote:
I was wondering which filesystem I should implement after FAT 12/16/32. I'm looking for something that is easy and a good step up from FAT.


I'd probably try to implement ISO9660 (CD-ROM) - mostly because I refuse to implement file system code that may be used to break the security (file system permissions, etc) of other OSs....


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Next Filesystem to Implement
PostPosted: Tue Feb 06, 2007 3:59 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Quote:
I'd probably try to implement ISO9660 (CD-ROM)


Thanks, I was looking into that one two.

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 10:23 am 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2006 12:00 am
Posts: 1444
Or you could implement a basic NTFS.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 12:33 pm 
Offline
Member
Member
User avatar

Joined: Tue Oct 17, 2006 9:29 pm
Posts: 2426
Location: Canada
Dex wrote:
Or you could implement a basic NTFS.


Now that wouldn't be productive or useful.. or in any way fun.. now would it ;)

_________________
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 2:20 pm 
Offline
Member
Member
User avatar

Joined: Thu Jan 04, 2007 3:29 pm
Posts: 1466
Location: Noricum and Pannonia
frank wrote:
Thanks

Brynet-Inc wrote:
One can always just use a UNIX-like system full time though :wink:


I would if I could, but I don't have high speed internet, so I can't download it, and I have yet to find a UNIX-like system that works well with my WIN modem. Plus I have no money. :wink:


Aye, a WinModem isn't compatible with any Linux\Unix\BSD\SkyOS I know of. I had one, and when I installed Linux it was my first problem. I found that I had to buy a US Robotics Modem, which work quite nicely.

For an easy file system: Why not Minix? I'm sure it's well documented. :)

_________________
C8H10N4O2 | #446691 | Trust the nodes.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 5:30 pm 
Offline
Member
Member
User avatar

Joined: Tue Oct 17, 2006 9:29 pm
Posts: 2426
Location: Canada
One of the main reasons that winmodems don't work on these systems is the actual cards are blank slate.

There firmware is usually located in a closed source binary driver, Targeting Windows normally :P..

Also, Not many of these winmodems are in any way identical, so making a driver that supporting them all is... improbable.

Still, The Linux community has lower standards against binary blobs, There are a few closed source winmodem drivers.

http://linmodems.org/
http://www.google.ca/search?hl=en&safe= ... arch&meta=

Few links above, but again.. Anyone who supports such vendor lock-in is really pathetic.

As Alboin said, Quite a few older (ISA usually) cards work perfectly.. (Normally appearing simply as communications ports, /dev/cua01 would be COM2 OpenBSD as an example..)

For the subject at hand anyway, frank.. You could possibly add support for OpenBSD's Berkeley FFS implementation, Or FreeBSD's UFS2 or w/e.

...Not sure why anyone would implement Minix's file system Alboin :?

_________________
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.


Last edited by Brynet-Inc on Wed Feb 07, 2007 5:37 pm, edited 8 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 5:30 pm 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2006 12:00 am
Posts: 1444
Brynet-Inc wrote:
Dex wrote:
Or you could implement a basic NTFS.


Now that wouldn't be productive or useful.. or in any way fun.. now would it ;)

This code will find and load a file from a ntfs partion, Sorry its not in C ;).
Here is "mtrdr.asm"
Code:
; KolibriOS bootloader
; this code has been written by diamond in 2005 specially for KolibriOS

; this code is loaded by ntldr to 0D00:0000
; and by io.sys from config.sys to xxxx:0100
   format   binary
   use16

   org   0xD000
; entry point for 9x booting
   jmp   @f
   db   'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
   db   'NTFS'
@@:
   mov   si, load_question + 100h - 0D000h
   call   out_string
;   mov   si, answer + 100h - 0D000h   ; already is
xxy:   mov   ah, 0
   int   16h
   or   al, 20h
   mov   [si], al
   cmp   al, 'y'
   jz   xxz
   cmp   al, 'n'
   jnz   xxy
; continue load Windows
;       call    out_string
;       ret
out_string:
   lodsb
   test   al, al
   jz   .xxx
   mov   ah, 0Eh
   mov   bx, 7
   int   10h
   jmp   out_string
.xxx:   ret
xxz:
; boot KolibriOS
   call   out_string
   push   0
   pop   ds
   mov   word [4], new01handler + 100h - 0D000h
   mov   [6], cs
   pushf
   pop   ax
   or   ah, 1
   push   ax
   popf
;   int   19h
;   pushf      ; there will be no iret
   call   far [19h*4]
xxt:
; TF has been cleared when entered new01handler
;   pushf
;   pop   ax
;   and   ah, not 1
;   push   ax
;   popf
   xor   di, di
   mov   ds, di
   cmp   word [8*4+2], 0F000h
   jz   @f
   les   bx, [8*4]
   mov   eax, [es:bx+1]
   mov   [8*4], eax
@@:
   mov   eax, [8*4]
   mov   [20h*4], eax
   mov   si, 100h
   push   cs
   pop   ds
   push   0D00h
   pop   es
   mov   cx, 2000h/2
   rep   movsw
   jmp   0D00h:0256h
load_question   db   'Load KolibriOS? [y/n]: ',0
answer   db   ?
   db   13,10,0

new01handler:
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
   push   bp
   mov   bp, sp
   push   bx
   push   ds
   lds   bx, [bp+2]
   cmp   word [bx], 19cdh
   jz   xxt
   pop   ds
   pop   bx
   pop   bp
   iret

relative_read:
   add   eax, [partition_start]

; read from hard disk
; drive_size must be already initialized
; in: eax = absolute sector
;     cx = number of sectors
;     es:bx -> buffer
read:
   pushad
   cmp   eax, [drive_size]
   jb   .old_style
; new style - LBA, function 42
   cmp   [has_lba], 0
   jz   disk_error
; allocate disk address packet on the stack
; qword +8: absolute block number
   push   dword 0    ; dword +C is high dword
   push   eax      ; dword +8 is low dword
; dword +4: buffer address
   push   es      ; word +6 is segment
   push   bx      ; word +4 is offset
; word +2: number of blocks = 1
; word +0: size of packet = 10h
   push   dword 10010h
; now pair ss:sp contain address of disk address packet
.patch1:
   mov   ax, 4200h
   mov   dl, [boot_drive]
   mov   si, sp
   push   ds
   push   ss
   pop   ds
   int   13h
   pop   ds
   add   sp, 10h
.end:
   popad
   jc   disk_error
   add   bx, 200h
   inc   eax
   dec   cx
   jnz   read
   ret
.old_style:
; old style - CHS, function 2
; convert absolute sector in eax to cylinder-head-sector coordinates
; calculate sector
   xor   edx, edx
   movzx   ecx, [sectors]
   div   ecx
; sectors are counted from 1
   inc   dl
   mov   cl, dl      ; low 6 bits of cl = sector number
; calculate head number
   shld   edx, eax, 10h   ; convert eax to dx:ax
   div   [heads]
   mov   dh, dl      ; dh = head
   mov   ch, al      ; ch = low 8 bits of cylinder
   shl   ah, 6
   or   cl, ah      ; high 2 bits of cl = high 2 bits of cylinder
.patch2:
   mov   ax, 201h   ; function 2, al=1 - number of sectors
   mov   dl, [boot_drive]
   int   13h
   jmp   .end

disk_error:
   mov   si, disk_error_msg
   call   out_string
   jmp   $

has_lba db   0

disk_error_msg   db   'Disk read error!',0
start_msg   db   2,' KolibriOS bootloader, running on ',0
errfs_msg   db   'unknown filesystem, cannot continue',0
fat16_msg   db   'FAT12/FAT16 - unsupported',13,10,0
fat32_msg   db   'FAT32',13,10,0
ntfs_msg   db   'NTFS',13,10,0
error_msg   db   'Error'
colon      db   ': ',0
mft_string   db   'MFT',0
root_string   db   '\',0
nodata_string   db   '$DATA not found',0
noindex_string   db   '$INDEX_ROOT not found',0
invalid_read_request_string db 'cannot read attribute',0
notfound_string db   'not found',0
directory_string db   'is a directory',0
fragmented_string db   'too fragmented file',0
exmem_string   db   'extended memory error',0
bad_cluster_string db   'bad cluster',0

; init procedure - ntldr jmps here
   repeat   0D256h - $
      db   1
   end   repeat
start:
; cs=es=0D00, ds=07C0, ss=0
; esi=edi=ebp=0, esp=7C00
   xor   ax, ax
   mov   ds, ax
   mov   es, ax
; our stack is 4Kb-2b!!! (0xFFE)
   mov   ss, ax
   mov   esp, 0FFFEh

; we are booting from first hard disk
   mov   dl, 80h
   mov   [boot_drive], dl
   cld
   sti
; calculate drive size
   mov   ah, 8   ; 8 = get drive parameters
   int   13h
; now: CF is set on error;
; ch = low 8 bits of maximum cylinder number
; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number
; dh = maximum head number
   jnc   @f
   mov   cx, -1
   mov   dh, cl
@@:
   movzx   ax, dh
   inc   ax
; ax = number of heads
   mov   [heads], ax
   mov   dl, cl
   and   dx, 3Fh
; dx = number of sectors
; (note that sectors are counted from 1, and maximum sector number = number of sectors)
   mov   [sectors], dx
   mul   dx
   xchg   cl, ch
   shr   ch, 6
   inc   cx
; cx = number of cylinders
   mov   [cyls], cx
   mul   cx
   mov   word [drive_size], ax
   mov   word [drive_size+2], dx
; this drive supports LBA?
   mov   dl, [boot_drive]
   mov   ah, 41h
   mov   bx, 55AAh
   int   13h
   jc   .no_lba
   cmp   bx, 0AA55h
   jnz   .no_lba
   test   cl, 1
   jz   .no_lba
   inc   [has_lba]
.no_lba:
; say hi to user
   mov   si, start_msg
   call   out_string
; now read first sector to determine file system type
; first sector of disk is MBR sector
   xor   eax, eax
   mov   cx, 1
   mov   bx, 500h
   call   read
   mov   eax, [6C6h]   ; first disk
   mov   [partition_start], eax
   mov   cx, 1
   mov   bx, 500h
   call   read
   movzx   ax, byte [50Dh]
   mov   [sect_per_clust], ax
; determine file system
   cmp   dword [536h], 'FAT1'
   jz   fat1x
   cmp   dword [552h], 'FAT3'
   jz   fat32
   cmp   dword [503h], 'NTFS'
   jz   ntfs
;       mov     si, errfs_msg           ; already is
   call   out_string
   jmp   $
fat1x:
   mov   si, fat16_msg
   call   out_string
   jmp   $
fat32:
   mov   si, fat32_msg
   call   out_string
   movzx   eax, word [50Bh]   ; bytes_per_sect
   movzx   ebx, byte [50Dh]   ; sects_per_clust
   mul   ebx
   mov   [cluster_size], eax
   movzx   ebx, word [50Eh]   ; reserved_sect
   add   ebx, [51Ch]      ; hidden
   mov   [fat_start], ebx
   movzx   eax, byte [510h]   ; num_fats
   mul   dword [524h]      ; sect_fat
   add   eax, ebx
; cluster 2 begins from sector eax
   movzx   ebx, byte [50Dh]   ; sects_per_clust
   sub   eax, ebx
   sub   eax, ebx
   sub   eax, [51Ch]   ; we will use relative_read
   mov   [data_start], eax
   mov   eax, [52Ch]      ; root_cluster
   push   menuet_img_name
   mov   [cur_obj], root_string
   call   fat32_parse_dir
; parse FAT chunk
; runlist at 2000:0000
   mov   di, 5
   push   2000h
   pop   es
   mov   byte [es:di-5], 1   ; of course, non-resident
   mov   dword [es:di-4], 1
   stosd
.parsefat:
   push   es
   push   ds
   pop   es
   call   next_cluster
   pop   es
   jnc   .done
   mov   ecx, [es:di-8]
   add   ecx, [es:di-4]
   cmp   eax, ecx
   jz   .contc
   mov   dword [es:di], 1
   add   di, 4
   stosd
   jmp   .parsefat
.contc:
   inc   dword [es:di-8]
   jmp   .parsefat
.done:
   xor   eax, eax
   stosd
   jmp   read_img_file

ntfs:
   mov   si, ntfs_msg
   call   out_string
   movzx   eax, word [50Bh]   ; bpb_bytes_per_sect
   push   eax
   movzx   ebx, byte [50Dh]   ; bpb_sects_per_clust
   mul   ebx
   mov   [cluster_size], eax
   mov   [data_start], 0
   mov   ecx, [540h]      ; frs_size
   cmp   cl, 0
   jg   .1
   neg   cl
   xor   eax, eax
   inc   eax
   shl   eax, cl
   jmp   .2
.1:
   mul   ecx
.2:
   mov   [frs_size], eax
   pop   ebx
   xor   edx, edx
   div   ebx
   mov   [frs_sectors], ax
; read first MFT record - description of MFT itself
   mov   [cur_obj], mft_string
   movzx   eax, byte [50Dh]   ; bpb_sects_per_clust
   mul   dword [530h]      ; mft_cluster
   mov   cx, [frs_sectors]
   mov   bx, 4000h
   mov   di, bx
   push   bx
   call   relative_read
   call   restore_usa
; scan for unnamed $DATA attribute
   pop   di
   mov   ax, 80h      ; $DATA
   mov   bx, 700h
   call   load_attr
   mov   si, nodata_string
   jc   find_error_si
   mov   [free], bx
; load menuet.img
; find entry
   mov   eax, 5
   push   menuet_img_name
   mov   [cur_obj], root_string
   call   ntfs_parse_dir
read_img_file:
   xor   si, si
   push   es
   pop   fs
; yes! Now read file to 0x100000
   lods byte [fs:si]
   cmp   al, 0   ; assume nonresident attr
   mov   si, invalid_read_request_string
   jz   find_error_si
   mov   si, 1
   xor   edi, edi
; read buffer to 1000:0000 and move it to extended memory
   push   1000h
   pop   es
   xor   bx, bx
.img_read_block:
   lods dword [fs:si]      ; eax=length
   xchg   eax, ecx
   jecxz   .img_read_done
   lods dword [fs:si]      ; eax=disk cluster
.img_read_cluster:
   pushad
; read part of file
   movzx   ecx, byte [50Dh]
   mul   ecx
   add   eax, [data_start]
   call   relative_read
; move it to extended memory
   mov   ah, 87h
   mov   ecx, [cluster_size]
   push   ecx
   shr   cx, 1
   mov   si, movedesc
   push   es
   push   ds
   pop   es
   int   15h
   pop   es
   cmp   ah, 0
   mov   si, exmem_string
   jnz   find_error_si
   pop   ecx
   add   [dest_addr], ecx
   popad
   inc   eax
   loop   .img_read_cluster
   jmp   .img_read_block
.img_read_done:
; menuet.img loaded; now load kernel.mnt
load_kernel:
   push   ds
   pop   es
   mov   [cur_obj], kernel_mnt_name
; read boot sector
   xor   eax, eax
   mov   bx, 500h
   mov   cx, 1
   call   read_img
; init vars
   mov   ax, [50Eh]   ; reserved_sect
   add   ax, [51Ch]   ; hidden
   mov   word [fat_start], ax
   xchg   ax, bx
   movzx   ax, byte [510h]      ; num_fats
   mul   word [516h]      ; fat_length
   add   ax, bx
; read root dir
   mov   bx, 700h
   mov   cx, [511h]   ; dir_entries
   add   cx, 0Fh
   shr   cx, 4
   call   read_img
   add   ax, cx
   mov   [img_data_start], ax
   shl   cx, 9
   mov   di, bx
   add   bx, cx
   mov   byte [bx], 0
.scan_loop:
   cmp   byte [di], 0
   mov   si, notfound_string
   jz   find_error_si
   mov   si, kernel_mnt_name
   call   fat_compare_name
   jz   .found
   and   di, not 1Fh
   add   di, 20h
   jmp   .scan_loop
.found:
   and   di, not 1Fh
   mov   si, directory_string
   test   byte [di+0Bh], 10h
   jnz   find_error_si
; found, now load it to 1000h:0000h
   mov   ax, [di+1Ah]
; first cluster of kernel.mnt in ax
; translate it to sector on disk in menuet.img
   push   ax
   dec   ax
   dec   ax
   movzx   cx, byte [50Dh]
   mul   cx
   add   ax, [img_data_start]
; now ax is sector in menuet.img
   mov   [kernel_mnt_in_img], ax
   div   [sect_per_clust]
; now ax is cluster in menuet.img and
; dx is offset from the beginning of cluster
   movzx   eax, ax
   push   2000h
   pop   ds
   mov   si, 1
.scani:
   sub   eax, [si]
   jb   .scanidone
; sanity check
   cmp   dword [si], 0
   push   invalid_read_request_string
   jz   find_error_sp
   pop   cx
; next chunk
   add   si, 8
   jmp   .scani
.scanidone:
   add   eax, [si]   ; undo last subtract
   add   eax, [si+4]   ; get cluster
   push   0
   pop   ds
   movzx   ecx, [sect_per_clust]
   push   dx
   mul   ecx      ; get sector
   pop   dx
   movzx   edx, dx
   add   eax, edx
   add   eax, [data_start]
   mov   [kernel_mnt_1st], eax
   pop   ax
   push   1000h
   pop   es
.read_loop:
   push   ax
   xor   bx, bx
   call   img_read_cluster
   shl   cx, 9-4
   mov   ax, es
   add   ax, cx
   mov   es, ax
   pop   ax
   call   img_next_cluster
   jc   .read_loop
   mov   eax, 'KLBR'
   mov   si, loader_block
   jmp   1000h:0000h

img_next_cluster:
   mov   bx, 700h
   push   ax
   shr   ax, 1
   add   ax, [esp]
   mov   dx, ax
   shr   ax, 9
   add   ax, word [fat_start]
   mov   cx, 2
   push   es
   push   ds
   pop   es
   call   read_img
   pop   es
   and   dx, 1FFh
   add   bx, dx
   mov   ax, [bx]
   pop   cx
   test   cx, 1
   jz   .1
   shr   ax, 4
.1:
   and   ax, 0FFFh
   mov   si, bad_cluster_string
   cmp   ax, 0FF7h
   jz   find_error_si
   ret
img_read_cluster:
   dec   ax
   dec   ax
   movzx   cx, byte [50Dh]   ; sects_per_clust
   mul   cx
   add   ax, [img_data_start]
   movzx   eax, ax
;   call   read_img
;   ret
read_img:
; in: ax = sector, es:bx->buffer, cx=length in sectors
   pushad
   movzx   ebx, bx
   mov   si, movedesc
   shl   eax, 9
   add   eax, 93100000h
   mov   dword [si+sou_addr-movedesc], eax
   mov   eax, 9300000h
   mov   ax, es
   shl   eax, 4
   add   eax, ebx
   mov   [si+dest_addr-movedesc], eax
   mov   ah, 87h
   shl   cx, 8   ; mul 200h/2
   push   es
   push   0
   pop   es
   int   15h
   pop   es
   cmp   ah, 0
   mov   si, exmem_string
   jnz   find_error_si
   popad
   ret

movedesc:
   times 16 db 0
; source
   dw   0xFFFF      ; segment length
sou_addr dw   0000h      ; linear address
   db   1      ; linear address
   db   93h      ; access rights
   dw   0
; destination
   dw   0xFFFF      ; segment length
dest_addr dd   93100000h   ; high byte contains access rights
            ; three low bytes contains linear address (updated when reading)
   dw   0
   times 32 db 0

find_error_si:
   push   si
find_error_sp:
   mov   si, error_msg
   call   out_string
   mov   si, [cur_obj]
   call   out_string
   mov   si, colon
   call   out_string
   pop   si
   call   out_string
   jmp   $

file_not_found:
   mov   si, [esp+2]
   mov   [cur_obj], si
   push   notfound_string
   jmp   find_error_sp

   include 'fat32.inc'
   include   'ntfs.inc'

write1st:
; callback from kernel.mnt
; write first sector of kernel.mnt from 1000:0000 back to disk
   push   cs
   pop   ds
   push   cs
   pop   es
; sanity check
   mov   bx, 500h
   mov   si, bx
   mov   cx, 1
   push   cx
   mov   eax, [kernel_mnt_1st]
   push   eax
   call   relative_read
   push   1000h
   pop   es
   xor   di, di
   mov   cx, 8
   repz   cmpsw
   mov   si, data_error_msg
   jnz   find_error_si
; ok, now write back to disk
   or   byte [read.patch1+2], 1
   or   byte [read.patch2+2], 1
   xor   bx, bx
   pop   eax
   pop   cx
   call   relative_read
   and   byte [read.patch1+1], not 1
   and   byte [read.patch2+2], not 2
; and to image in memory (probably this may be done by kernel.mnt itself?)
   mov   dword [sou_addr], 93010000h
   movzx   eax, [kernel_mnt_in_img]
   shl   eax, 9
   add   eax, 93100000h
   mov   dword [dest_addr], eax
   mov   si, movedesc
   push   ds
   pop   es
   mov   ah, 87h
   mov   cx, 100h
   int   15h
   cmp   ah, 0
   mov   si, exmem_string
   jnz   find_error_si
   retf
data_error_msg db 'data error',0

loader_block:
   db   1   ; version
   dw   1   ; flags - image is loaded
   dw   write1st   ; offset
   dw   0      ; segment

fat_cur_sector dd -1

; -----------------------------------------------
; ------------------ Settings -------------------
; -----------------------------------------------

; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
kernel_mnt_name    db   'kernel.mnt',0
menuet_img_name    db   'menuet.img',0

; uninitialized data follows
drive_size      dd   ?   ; in sectors
boot_drive      db   ?
heads         dw   ?
sectors       dw   ?
cyls         dw   ?
partition_start    dd   ?
free         dw   ?
cur_obj       dw   ?
data_start      dd   ?
img_data_start      dw   ?
sect_per_clust      dw   ?
kernel_mnt_in_img   dw   ?
kernel_mnt_1st      dd   ?
; NTFS data
cluster_size      dd   ?   ; in bytes
frs_size      dd   ?   ; in bytes
frs_sectors      dw   ?   ; in sectors
mft_data_attr      dw   ?
index_root      dw   ?
index_alloc      dw   ?
ofs         dw   ?
dir         dw   ?
; FAT32 data
fat_start      dd   ?
cur_cluster      dd   ?
; file must be 16 sectors long

   repeat   0F000h - $
      db   2
   end   repeat

Here is "ntfs.inc"
Code:
restore_usa:
; Update Sequence Array restore
   mov   bx, [di+4]
   mov   cx, [di+6]
   inc   bx
   add   bx, di
   inc   bx
   add   di, 1feh
   dec   cx
@@:
   mov   ax, [bx]
   stosw
   inc   bx
   inc   bx
   add   di, 1feh
   loop   @b
   ret

find_attr:
; in: di->file record, ax=attribute
; out: di->attribute or di=0 if not found
   add   di, [di+14h]
.1:
; attributes codes are formally dwords, but all they fit in word
   cmp   word [di], -1
   jz   .notfound
   cmp   word [di], ax
   jnz   .continue
; for $DATA attribute, scan only unnamed
   cmp   ax, 80h
   jnz   .found
   cmp   byte [di+9], 0
   jz   .found
.continue:
   add   di, [di+4]
   jmp   .1
.notfound:
   xor   di, di
.found:
   ret

process_mcb_nonres:
; in: si->attribute, es:di->buffer
; out: di->buffer end
   add   si, [si+20h]
   xor   ebx, ebx
.loop:
   lodsb
   test   al, al
   jz   .done
   push   invalid_read_request_string
   movzx   cx, al
   shr   cx, 4
   jz   find_error_sp
   xchg   ax, dx
   and   dx, 0Fh
   jz   find_error_sp
   add   si, cx
   add   si, dx
   pop   ax
   push   si
   dec   si
   movsx   eax, byte [si]
   dec   cx
   jz   .l1e
.l1:
   dec   si
   shl   eax, 8
   mov   al, [si]
   loop   .l1
.l1e:
   xchg   ebp, eax
   dec   si
   movsx   eax, byte [si]
   mov   cx, dx
   dec   cx
   jz   .l2e
.l2:
   dec   si
   shl   eax, 8
   mov   al, byte [si]
   loop   .l2
.l2e:
   pop   si
   add   ebx, ebp
; eax=length, ebx=disk block
   stosd
   mov   eax, ebx
   stosd
   jmp   .loop
.done:
   xor   eax, eax
   stosd
   ret

load_attr:
; in: ax=attribute, es:bx->buffer, di->base record
; out: bx->buffer end; CF set if not found
   push   di
   push   ax
   mov   byte [es:bx], 1
   inc   bx
   push   bx
   mov   [ofs], bx
; scan for attrubute
   add   di, [di+14h]
@@:
   call   find_attr.1
   test   di, di
   jz   .notfound1
   cmp   byte [di+8], 0
   jnz   .nonresident
; resident attribute
   mov   si, di
   pop   di
   dec   di
   mov   al, 0
   stosb
   mov   ax, [si+10h]
   stosw
   xchg   ax, cx
   add   si, [si+14h]
   rep   movsb
   mov   bx, di
   pop   ax
   pop   di
   ret
.nonresident:
; nonresident attribute
   cmp   dword [di+10h], 0
   jnz   @b
; read start of data
   mov   si, di
   pop   di
   call   process_mcb_nonres
   push   di
.notfound1:
; $ATTRIBUTE_LIST is always in base file record
   cmp   word [esp+2], 20h
   jz   .nofragmented
; scan for $ATTRIBUTE_LIST = 20h
   mov   di, [esp+4]
   mov   ax, 20h
   call   find_attr
   test   di, di
   jz   .nofragmented
; load $ATTRIBUTE_LIST itself
   push   es
   mov   bx, 0C000h
   mov   di, [esp+4]
   push   bx
   push   [ofs]
   push   ds
   pop   es
   call   load_attr
   pop   [ofs]
   pop   si
   mov   bx, 8000h
   push   bx
   push   si
   call   read_attr_full
   pop   si
   pop   bx
   add   dx, bx
   mov   ax, [esp+2]
   pop   es
.1:
   cmp   [bx], ax
   jnz   .continue1
; only unnamed $DATA attributes!
   cmp   ax, 80h
   jnz   @f
   cmp   byte [bx+6], 0
   jnz   .continue1
@@:
   cmp   dword [bx+10h], 0
   jz   .continue1
   cmp   dword [bx+8], 0
   jnz   @f
   push   ax
   mov   ax, [esp+2]
   cmp   ax, [ofs]
   pop   ax
   jnz   .continue1
@@:
   pushad
   mov   eax, [bx+10h]
   mov   bx, dx
   push   [ofs]
   push   es
   push   ds
   pop   es
   call   read_file_record
   pop   es
   pop   [ofs]
   popad
   pushad
   mov   di, dx
   add   di, [di+14h]
.2:
   call   find_attr.1
   mov   eax, [bx+8]
   cmp   eax, [di+10h]
   jnz   .2
   mov   si, di
   mov   di, [esp+20h]
   sub   di, 4
   call   process_mcb_nonres
   mov   [esp+20h], di
   popad
.continue1:
   add   bx, [bx+4]
   cmp   bx, dx
   jb   .1
.nofragmented:
   pop   bx
   pop   ax
   pop   di
   cmp   bx, [ofs]
   jnz   @f
   dec   bx
   stc
@@:
   ret

read_attr_full:
; in: si->decoded attribute data, bx->buffer
; out: edx=length in bytes
   lodsb
   cmp   al, 0
   jnz   .nonresident
; resident
   lodsw
   movzx   edx, ax
   xchg   ax, cx
   mov   di, bx
   rep   movsb
   ret
.nonresident:
; nonresident :-)
   xor   edx, edx
.loop:
   lodsd
   xchg   ecx, eax
   jecxz   .loopend
   lodsd
   xchg   edi, eax
; read ecx clusters from cluster edi to es:bx
.intloop:
   push   ecx
; read 1 cluster from physical cluster edi to es:bx
   mov   ecx, [cluster_size]
   mov   eax, edi
   mul   ecx
   push   bx
   call   relative_read
   pop   bx
   pop   ecx
   inc   edi
   mov   eax, [cluster_size]
   add   edx, eax
   shr   eax, 4
   mov   bp, es
   add   bp, ax
   mov   es, bp
   loop   .intloop
   jmp   .loop
.loopend:
   mov   es, cx
   ret

read_file_record:
; in: eax=index of record, bx=buffer
   mov   si, 700h
   mov   ecx, [frs_size]
   mul   ecx
   push   bx
   push   [cur_obj]
   mov   [cur_obj], mft_string
   call   read_attr
   pop   [cur_obj]
   pop   di
   call   restore_usa
   ret
read_attr:
; in: edx:eax=offset in bytes, ecx=size in bytes, bx=buffer, si=attribute
   push   invalid_read_request_string
   cmp   byte [si], 0
   jnz   .nonresident
   test   edx, edx
   jnz   find_error_sp
   cmp   eax, 10000h
   jae   find_error_sp
   cmp   ecx, 10000h
   jae   find_error_sp
   cmp   ax, [si+2]
   jae   find_error_sp
   cmp   cx, [si+2]
   ja   find_error_sp
   add   si, 3
   add   si, ax
   mov   di, bx
   rep   movsb
   pop   ax
   ret
.nonresident:
   mov   edi, [cluster_size]
   div   edi
   mov   [ofs], dx
   add   cx, dx
   push   eax
   xchg   eax, ecx
   xor   edx, edx
   dec   eax
   div   edi
   inc   eax
   xchg   eax, ecx
   pop   eax
   add   si, 1
   xor   edx, edx
   push   bx
; eax=offset in clusters, ecx=size in clusters
.scan:
   mov   ebx, [si]
   test   ebx, ebx
   jz   .notfound
   add   edx, ebx
   add   si, 8
   cmp   eax, edx
   jae   .scan
   mov   edi, [si-4]
; now edx=end of block, ebx=length of block, edi=start of block on disk
; eax=required offset, ecx=required length
   push   edx
   push   edi
   sub   edx, eax
   add   edi, ebx
   sub   edi, edx
   cmp   edx, ecx
   jb   @f
   mov   edx, ecx
@@:
; read (edx) clusters from (edi=disk offset in clusters) to ([esp+8])
   cmp   [ofs], 0
   jnz   .ofs_read
.cont:
   pushad
   movzx   ebx, byte [50Dh]
;       xchg    eax, edx
;       mul     ebx
   xchg   ax, dx
   mul   bx
   xchg   cx, ax
   xchg   eax, edi
   mul   ebx
   mov   bx, [esp+8+20h]
   call   relative_read
   mov   [esp+8+20h], bx
   popad
.cont2:
   add   eax, edx
   sub   ecx, edx
.cont3:
   pop   edi
   pop   edx
   jnz   .scan
   pop   bx
   pop   ax
   ret
.ofs_read:
   push   ecx
   movzx   ecx, byte [50Dh]   ; bpb_sects_per_clust
   mov   eax, edi
   push   edx
   mul   ecx
   push   1000h
   pop   es
   xor   bx, bx
   call   relative_read
   mov   cx, bx
   push   si
   push   di
   mov   si, [ofs]
   mov   di, [esp+8+12]
   sub   cx, si
   push   ds
   push   es
   pop   ds
   pop   es
   rep   movsb
   mov   [esp+8+12], di
   push   es
   pop   ds
   pop   di
   pop   si
   pop   edx
   pop   ecx
   inc   edi
   mov   [ofs], 0
   inc   eax
   dec   ecx
   jz   .cont3
   dec   edx
   jnz   .cont
   jmp   .cont2
.notfound:
   mov   si, invalid_read_request_string
   jmp   find_error_si

ntfs_parse_dir:
; in: eax=directory iRecord, [word sp+2]=filename
; out: si=$DATA attribute of file
   mov   bx, [free]
   mov   [dir], bx
   push   bx
   call   read_file_record
   mov   ax, word [frs_size]
   add   [free], ax
   pop   di
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
   mov   ax, 90h    ; $INDEX_ROOT
   push   di
   mov   bx, [free]
   mov   [index_root], bx
   call   load_attr
   mov   si, noindex_string
   jc   find_error_si
   mov   [free], bx
   pop   di
   mov   ax, 0A0h   ; $INDEX_ALLOCATION
   mov   bx, [free]
   mov   [index_alloc], bx
   call   load_attr
   jnc   @f
   mov   [index_alloc], 0
@@:
   mov   [free], bx
; search for entry
   mov   si, [index_root]
   mov   bx, [free]
   call   read_attr_full
   mov   ebp, [bx+8]   ; subnode_size
   add   bx, 10h
.scan_record:
   add   bx, [bx]
.scan:
   test   byte [bx+0Ch], 2
   jnz   .not_found
   mov   si, [esp+2]
   movzx   cx, byte [bx+50h]   ; namelen
   lea   di, [bx+52h]      ; name
   xor   ax, ax
@@:
   lodsb
   cmp   al, 'a'
   jb   .notletter
   cmp   al, 'z'
   ja   .notletter
   or   byte [di], 20h
.notletter:
   scasw
   loopz   @b
   jz   .file_found
   jb   .not_found
   add   bx, [bx+8]
   jmp   .scan
.not_found:
   test   byte [bx+0Ch], 1
   jz   file_not_found
   cmp   [index_alloc], 0
   jz   file_not_found
   add   bx, [bx+8]
   mov   eax, [bx-8]
   mul   [cluster_size]
   mov   si, [index_alloc]
   mov   ecx, ebp
   mov   bx, [free]
   call   read_attr
   mov   di, [free]
   call   restore_usa
   mov   bx, [free]
   add   bx, 18h
   jmp   .scan_record
.file_found:
   mov   si, [esp+2]
   mov   [cur_obj], si
   mov   si, directory_string
   test   byte [bx+48h+3], 10h   ; directory?
   jnz   find_error_si
; read entry
   mov   eax, [bx]
   mov   bx, [dir]
   mov   [free], bx
   mov   bx, 4000h
   push   bx
   call   read_file_record
   pop   di
   mov   ax, 80h
   push   2000h
   pop   es
   xor   bx, bx
   call   load_attr
   mov   si, nodata_string
   jz   find_error_si
   mov   [free], bx
   ret   2

Here is fat.inc
Code:
fat32_parse_dir:
; in: eax=directory cluster
; out: eax=entry cluster
   mov   bx, 900h
   mov   di, bx
   push   eax
   call   read_cluster
   mov   cx, word [cluster_size]
   shr   cx, 5      ; div 20h
.scan_cluster:
   pop   eax
   cmp   byte [di], 0
   jz   file_not_found
   mov   si, [esp+2]
   push   eax
   call   fat_compare_name
   jz   .file_found
   and   di, not 1Fh
   add   di, 20h
   loop   .scan_cluster
   pop   eax
   call   next_cluster
   jnc   file_not_found
   jc   fat32_parse_dir
.file_found:
   pop   eax
   mov   si, [esp+2]
   mov   [cur_obj], si
   and   di, not 1Fh
   mov   si, directory_string
   test   byte [di+0Bh], 10h
   jnz   find_error_si
   mov   ax, [di+14h]
   shl   eax, 10h
   mov   ax, [di+1Ah]
   test   eax, eax
   mov   si, nodata_string
   jz   find_error_si
   ret   2

fat_compare_name:
   push   cx
   mov   cx, 9
.scan:
   lodsb
   cmp   al, '.'
   jz   .ext
   cmp   al, 0
   jz   .nameend
   cmp   al, 'a'
   jb   .notletter
   cmp   al, 'z'
   ja   .notletter
   or   byte [di], 20h
.notletter:
   scasb
   loopz   .scan
.notfound:
   inc   cx   ; to clear ZF flag
   pop   cx
   ret
.ext:
   mov   al, ' '
   dec   cx
   repz   scasb
   jnz   .notfound
   test   di, 1
   jnz   .notfound
   mov   cx, 4
   jmp   .scan
.nameend:
   mov   al, ' '
   dec   cx
   repz   scasb
   jnz   .notfound
   test   di, 1
   jnz   .file_found
   mov   cx, 3
   repz   scasb
   jnz   .notfound
.file_found:
   xor   cx, cx   ; to set ZF flag
   pop   cx
   ret

read_cluster:
; in: eax=cluster,bx->buffer
   and   eax, 0FFFFFFFh
   movzx   ecx, byte [50Dh]   ; sects_per_clust
   mul   ecx
   add   eax, [data_start]
;   call   read
;   ret
   jmp   relative_read
next_cluster:
   mov   bx, 700h
; sector is 200h bytes long, one entry in FAT occupies 4 bytes => 80h entries in sector
   push   eax
   shr   eax, 7      ; div 80h
   cmp   eax, [fat_cur_sector]
   jz   @f
   mov   [fat_cur_sector], eax
   add   eax, [fat_start]
   mov   cx, 1
   call   read
@@:
   pop   eax
   and   eax, 7Fh
   mov   eax, [700h+eax*4]
   and   eax, 0FFFFFFFh
   cmp   eax, 0FFFFFF7h
   mov   si, bad_cluster_string
   jz   find_error_si
   ret


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 6:41 pm 
Offline
Member
Member
User avatar

Joined: Thu Jan 04, 2007 3:29 pm
Posts: 1466
Location: Noricum and Pannonia
Brynet-Inc wrote:
...Not sure why anyone would implement Minix's file system Alboin :?


Well, I figured it's well documented, and shouldn't be too hard to implement. Moreover, it's probably a little better than FATx. (x being whatever you want it to be.) And well.....that's all really..... Just a suggestion....Besides, it's just about as useful as UFS.

_________________
C8H10N4O2 | #446691 | Trust the nodes.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 7:27 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
I know a winmodem won't work on linux, thats why I can't get linux, I don't have enough money for a real modem.

@Dex
Thanks for the code, I will try to look though it when I get the time

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot] and 867 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group