diff --git a/kernel/trunk/data32.inc b/kernel/trunk/data32.inc index 5de4741dd6..ab8669f005 100644 --- a/kernel/trunk/data32.inc +++ b/kernel/trunk/data32.inc @@ -368,6 +368,7 @@ cdid rd 1 hdbase rd 1 ; for boot 0x1f0 hdid rd 1 hdpos rd 1 ; for boot 0x1 +label known_part dword fat32part rd 1 ; for boot 0x1 cdpos rd 1 @@ -464,3 +465,4 @@ BiosDiskCaches rb 80h*(cache_ide1-cache_ide0) BiosDiskPartitions rd 80h IncludeUGlobals + diff --git a/kernel/trunk/detect/sear_par.inc b/kernel/trunk/detect/sear_par.inc index 970f58b346..cc1b3f7f95 100644 --- a/kernel/trunk/detect/sear_par.inc +++ b/kernel/trunk/detect/sear_par.inc @@ -20,15 +20,15 @@ $Revision$ mov [hdbase],0x1f0 mov [hdid],0x0 mov [hdpos],1 - mov [fat32part],1 + mov [known_part],1 search_partitions_ide0_1: - call set_FAT32_variables + call set_PARTITION_variables cmp [problem_partition],0 jne search_partitions_ide1 inc byte [DRIVE_DATA+2] call partition_data_transfer add [transfer_adress],100 - inc [fat32part] + inc [known_part] jmp search_partitions_ide0_1 search_partitions_ide1: @@ -37,15 +37,15 @@ $Revision$ mov [hdbase],0x1f0 mov [hdid],0x10 mov [hdpos],2 - mov [fat32part],1 + mov [known_part],1 search_partitions_ide1_1: - call set_FAT32_variables + call set_PARTITION_variables cmp [problem_partition],0 jne search_partitions_ide2 inc byte [DRIVE_DATA+3] call partition_data_transfer add [transfer_adress],100 - inc [fat32part] + inc [known_part] jmp search_partitions_ide1_1 search_partitions_ide2: @@ -54,15 +54,15 @@ $Revision$ mov [hdbase],0x170 mov [hdid],0x0 mov [hdpos],3 - mov [fat32part],1 + mov [known_part],1 search_partitions_ide2_1: - call set_FAT32_variables + call set_PARTITION_variables cmp [problem_partition],0 jne search_partitions_ide3 inc byte [DRIVE_DATA+4] call partition_data_transfer add [transfer_adress],100 - inc [fat32part] + inc [known_part] jmp search_partitions_ide2_1 search_partitions_ide3: @@ -71,15 +71,15 @@ $Revision$ mov [hdbase],0x170 mov [hdid],0x10 mov [hdpos],4 - mov [fat32part],1 + mov [known_part],1 search_partitions_ide3_1: - call set_FAT32_variables + call set_PARTITION_variables cmp [problem_partition],0 jne end_search_partitions_ide inc byte [DRIVE_DATA+5] call partition_data_transfer add [transfer_adress],100 - inc [fat32part] + inc [known_part] jmp search_partitions_ide3_1 end_search_partitions_ide: @@ -91,16 +91,16 @@ start_search_partitions_bd: push ecx mov eax, [hdpos] and [BiosDiskPartitions+(eax-80h)*4], 0 - mov [fat32part], 1 + mov [known_part], 1 search_partitions_bd: - call set_FAT32_variables + call set_PARTITION_variables cmp [problem_partition], 0 jne end_search_partitions_bd mov eax, [hdpos] inc [BiosDiskPartitions+(eax-80h)*4] call partition_data_transfer add [transfer_adress], 100 - inc [fat32part] + inc [known_part] jmp search_partitions_bd end_search_partitions_bd: pop ecx @@ -110,7 +110,7 @@ end_search_partitions_bd: partition_data_transfer: mov edi,[transfer_adress] - mov esi,PARTITION_START + mov esi,PARTITION_START ;start of file_system_data mov ecx,(file_system_data_size+3)/4 rep movsd ret diff --git a/kernel/trunk/fs/ext2.inc b/kernel/trunk/fs/ext2.inc new file mode 100644 index 0000000000..aa7e38a4ba --- /dev/null +++ b/kernel/trunk/fs/ext2.inc @@ -0,0 +1,816 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; 23.01.2010 turbanoff - read from ext2fs ;; +;; ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +EXT2_BAD_INO = 1 +EXT2_ROOT_INO = 2 +EXT2_ACL_IDX_INO = 3 +EXT2_ACL_DATA_INO = 4 +EXT2_BOOT_LOADER_INO= 5 +EXT2_UNDEL_DIR_INO = 6 + +;type inode +EXT2_S_IFREG = 0x8000 +EXT2_S_IFDIR = 0x4000 +;user inode right's +EXT2_S_IRUSR = 0x0100 +EXT2_S_IWUSR = 0x0080 +EXT2_S_IXUSR = 0x0040 +;group inode right's +EXT2_S_IRGRP = 0x0020 +EXT2_S_IWGRP = 0x0010 +EXT2_S_IXGRP = 0x0008 +;other inode right's +EXT2_S_IROTH = 0x0004 +EXT2_S_IROTH = 0x0002 +EXT2_S_IROTH = 0x0001 + +EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге +EXT2_FT_DIR = 2 ;это папка + +FS_FT_DIR = 0x10 ;это папка +FS_FT_ASCII = 0 ;имя в ascii +FS_FT_UNICODE = 1 ;имя в unicode + +struct EXT2_INODE_STRUC + .i_mode dw ? + .i_uid dw ? + .i_size dd ? + .i_atime dd ? + .i_ctime dd ? + .i_mtime dd ? + .i_dtime dd ? + .i_gid dw ? + .i_links_count dw ? + .i_blocks dd ? + .i_flags dd ? + .i_osd1 dd ? + .i_block dd 15 dup ? + .i_generation dd ? + .i_file_acl dd ? + .i_dir_acl dd ? + .i_faddr dd ? + .i_osd2 dd ? ; 1..12 +ends + +struct EXT2_DIR_STRUC + .inode dd ? + .rec_len dw ? + .name_len db ? + .file_type db ? + .name db ? ; 0..255 +ends + + +ext2_test_superblock: + mov eax, [PARTITION_START] + add eax, 2 ;superblock start at 1024b + call hd_read + + cmp [fs_type], 0x83 + jne .no + cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 + ja .no + cmp word [ebx+56], 0xEF53 ;s_magic + jne .no + cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) + jne .no + + ; OK, this is correct EXT2 superblock + clc + ret + .no: + ; No, this superblock isn't EXT2 + stc + ret + +ext2_setup: + mov [fs_type], 2 + mov ecx, [ebx+24] + inc ecx + mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb + + mov eax, 1 + shl eax, cl + mov [ext2_data.count_block_in_block], eax + + shl eax, 7 + mov [ext2_data.count_pointer_in_block], eax + mov edx, eax ; потом еще квадрат найдем + + shl eax, 2 + mov [ext2_data.block_size], eax + + push eax eax eax ;3 kernel_alloc + + mov eax, edx + mul edx + mov [ext2_data.count_pointer_in_block_square], eax + + call kernel_alloc + mov [ext2_data.global_desc_table],eax ;reserve mem for gdt + call kernel_alloc + mov [ext2_data.ext2_save_block], eax ; and for temp block + call kernel_alloc + mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc + + mov ebp, [ebx+88] + mov ecx, [ebx+32] + mov edx, [ebx+40] + mov eax, [ebx+20] ; first_data_block + + mov [ext2_data.inode_size], ebp + mov [ext2_data.blocks_per_group], ecx + mov [ext2_data.inodes_per_group], edx + + mov ebx, [ext2_data.global_desc_table] + inc eax ; first_data_block + 1 = gdt + call ext2_get_block ; read gtd + + push ebp ebp ebp ;3 kernel_alloc + call kernel_alloc + mov [ext2_data.ext2_save_inode], eax + call kernel_alloc + mov [ext2_data.ext2_temp_inode], eax + call kernel_alloc + mov [ext2_data.root_inode], eax + + mov ebx, eax + mov eax, EXT2_ROOT_INO + call ext2_get_inode ; read root inode + + popad + call free_hd_channel + and [hd1_status], 0 + ret +;================================================================== +;in: eax = i_block +; ebx = pointer to return memory +ext2_get_block: + push eax ebx ecx + mov ecx, [ext2_data.log_block_size] + shl eax, cl + add eax, [PARTITION_START] + mov ecx, [ext2_data.count_block_in_block] + @@: + call hd_read + inc eax + add ebx, 512 + loop @B + pop ecx ebx eax + ret +;=================================================================== +; in: ecx = номер блока +; ebp = адрес inode +; out: ecx = адрес очередного блока +ext2_get_inode_block: + cmp ecx, 12 + jbe .get_direct_block + + sub ecx, 12 + cmp ecx, [ext2_data.count_pointer_in_block] + jbe .get_indirect_block + + sub ecx, [ext2_data.count_pointer_in_block] + cmp ecx, [ext2_data.count_pointer_in_block_square] + jbe .get_double_indirect_block + + ;.get_triple_indirect_block: + push eax edx ebx + + mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] + mov ebx, [ext2_data.ext2_temp_block] + call ext2_get_block + + xor edx, edx + mov eax, ecx + div [ext2_data.count_pointer_in_block_square] + + ;eax - номер в полученном блоке edx - номер дальше + mov eax, [ebx + eax*4] + call ext2_get_block + + mov eax, edx + jmp @F + + .get_double_indirect_block: + push eax edx ebx + + mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] + mov ebx, [ext2_data.ext2_temp_block] + call ext2_get_block + + mov eax, ecx + @@: + xor edx, edx + div [ext2_data.count_pointer_in_block] + + mov eax, [ebx + eax*4] + call ext2_get_block + mov ecx, [ebx + edx*4] + + pop ebx edx eax + ret + + .get_indirect_block: + push eax ebx + mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] + mov ebx, [ext2_data.ext2_temp_block] + call ext2_get_block + + mov ecx, [ebx + ecx*4] + pop ebx eax + ret + + .get_direct_block: + mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] + ret + + +;=================================================================== +;get content inode by num +;in: eax = inode_num +; ebx = address of inode content +ext2_get_inode: + + pushad + mov edi, ebx ;сохраним адрес inode + dec eax + xor edx, edx + div [ext2_data.inodes_per_group] + + push edx ;locale num + + mov edx, 32 + mul edx ; address block_group in global_desc_table + + add eax, [ext2_data.global_desc_table] + mov eax, [eax+8] ; номер блока - в терминах ext2 + + mov ecx, [ext2_data.log_block_size] + shl eax, cl + add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) + + ;eax - указывает на таблицу inode-ов на hdd + mov ecx, eax ;сохраним его пока в ecx + + ; прибавим локальный адрес inode-а + pop eax ; index + mul [ext2_data.inode_size] ; (index * inode_size) + mov ebp, 512 + div ebp ;поделим на размер блока + + add eax, ecx ;нашли адрес блока для чтения + mov ebx, [ext2_data.ext2_temp_block] + call hd_read + + mov esi, edx ;добавим "остаток" + add esi, ebx ;к адресу + mov ecx, [ext2_data.inode_size] + rep movsb ;копируем inode + popad + ret + +;---------------------------------------------------------------- +ext2_upcase: + cmp al, 'a' + jb .ret + cmp al, 'z' + ja .ret + and al, 0xDF ; upcase = clear 0010 0000 + .ret: + ret +;---------------------------------------------------------------- +; in: esi -> children +; ebx -> pointer to dir block +; out: esi -> name without parent or not_changed +; ebx -> dir_rec of inode children or trash +ext2_test_block_by_name: + push eax ecx edx edi + + mov edx, ebx + add edx, [ext2_data.block_size] ;запомним конец блока + + .start_rec: + cmp [ebx + EXT2_DIR_STRUC.inode], 0 + jz .next_rec +; test [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR +; jz .next_rec + + push esi + movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] + lea edi, [ebx + EXT2_DIR_STRUC.name] + inc ecx + + @@: + dec ecx + jecxz .test_find + lodsb + mov ah, [edi] + inc edi + + call ext2_upcase + xchg al, ah + call ext2_upcase + cmp al, ah + je @B + @@: ;не подошло + pop esi + .next_rec: + movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] + add ebx, eax ;к след. записи + cmp ebx, edx ;проверим конец ли + jne .start_rec + jmp .ret + + .test_find: + cmp byte [esi], 0 + je .find ;нашли конец + cmp byte [esi], '/' + jne @B + inc esi + .find: + pop eax ;удаляем из стека сохраненое значение + ; mov ebx, [ebx + EXT2_DIR_STRUC.inode] + .ret: + pop edi edx ecx eax + ret + +;---------------------------------------------------------------- +; +; ext2_HdReadFolder - read disk folder +; +; esi points to filename +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +uglobal + EXT2_files_in_folder dd ? ;всего файлов в папке + EXT2_read_in_folder dd ? ;сколько файлов "считали" + EXT2_end_block dd ? ;конец очередного блока папки + EXT2_counter_blocks dd ? +endg + +ext2_HdReadFolder: + mov ebp, [ext2_data.root_inode] + mov [EXT2_read_in_folder], ebx + mov [EXT2_files_in_folder], ecx ;сохраним регистры + + .next_folder: + cmp byte [esi], 0 + jz .get_folder + + or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode + mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков + add eax, [ext2_data.count_block_in_block] + mov [EXT2_end_block], eax + .next_block_folder: + mov eax, [ext2_data.count_block_in_block] + sub [EXT2_end_block], eax + jz .not_found + inc [EXT2_counter_blocks] + mov ecx, [EXT2_counter_blocks] + call ext2_get_inode_block + + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record + call ext2_get_block + + mov eax, esi + call ext2_test_block_by_name + cmp eax, esi ;нашли имя? + je .next_block_folder + + cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR + jne .not_found ;нашли, но это не папка + mov eax, [ebx + EXT2_DIR_STRUC.inode] + mov ebx, [ext2_data.ext2_save_inode] ;все же папка. + call ext2_get_inode + mov ebp, ebx + jmp .next_folder + + .not_found: + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + ;--------------------------------------------- final step + ; in ebp - pointer to final inode (folder). + .get_folder: + push edx ;заголовок будем заполнять в конце (адрес - в стеке) edx + push [EXT2_read_in_folder] ;сохраненный регистр тоже в стек + + mov edi, [EXT2_files_in_folder] ;edi = число блоков для чтения + and [EXT2_read_in_folder], 0 + and [EXT2_files_in_folder], 0 + + mov esi, [ebp + EXT2_INODE_STRUC.i_blocks] + mov [EXT2_counter_blocks], esi + + add edx, 32 ;заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return + xor esi, esi ;esi = номер блока по порядку + + .new_block_folder: ;reserved label + mov ecx, esi ; получим номер блока + call ext2_get_inode_block + + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] + call ext2_get_block ; и считываем блок с hdd + + mov eax, ebx ; eax = current dir record + add ebx, [ext2_data.block_size] + mov [EXT2_end_block], ebx ; запомним конец очередного блока + + pop ecx + mov ecx, [ecx] ; ecx = first wanted (flags ommited) + + .find_wanted_start: + jecxz .find_wanted_end + .find_wanted_cycle: + cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + je @F + inc [EXT2_files_in_folder] + @@: + movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] + add eax, ebx ; к следующей записи + cmp eax, [EXT2_end_block] ; проверяем "конец" + je .end_block_find_wanted + loop .find_wanted_cycle + .find_wanted_end: + + mov ecx, edi + .wanted_start: ; ищем first_wanted+count + jecxz .wanted_end + .wanted_cycle: + cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + jz .empty_rec + inc [EXT2_files_in_folder] + inc [EXT2_read_in_folder] + + test [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;папка или нет + jnz @F + + push eax ;получим размер, если это файл + mov eax, [eax + EXT2_DIR_STRUC.inode] + mov ebx, [ext2_data.ext2_temp_inode] + call ext2_get_inode + mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size + mov ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size + mov dword [edx+32], eax + mov dword [edx+36], ebx + xor dword [edx], FS_FT_DIR ; для файлов xor - 2 раза + pop eax + @@: + xor dword [edx], FS_FT_DIR + mov dword [edx+4], FS_FT_ASCII ; symbol type in name + + push ecx esi ;copy name + movzx ecx, [eax + EXT2_DIR_STRUC.name_len] + mov edi, edx + add edi, 40 + lea esi, [eax + EXT2_DIR_STRUC.name] + rep movsb + pop esi ecx + and byte [edi], 0 + + add edx, 40 + 264 ; go to next record + .empty_rec: + movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] + add eax, ebx + cmp eax, [EXT2_end_block] + je .end_block_wanted + loop .wanted_cycle + + .wanted_end: ;теперь дойдем до конца чтобы узнать сколько файлов в папке + or ecx, -1 ;цикл уже есть, просто поставим ему огромный счетчик + jmp .find_wanted_cycle + + .end_block_find_wanted: ;вылетили из цикла find_wanted + mov ebx, [ext2_data.count_block_in_block] + sub [EXT2_counter_blocks], ebx + jz .end_dir + + ;получаем новый блок + inc esi + push ecx + mov ecx, esi + call ext2_get_inode_block + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] + call ext2_get_block + pop ecx + dec ecx + mov eax, ebx + add ebx, [ext2_data.block_size] + mov [EXT2_end_block], ebx + jmp .find_wanted_start + + .end_block_wanted: ;вылетели из цикла wanted + mov ebx, [ext2_data.count_block_in_block] + sub [EXT2_counter_blocks], ebx + jz .end_dir + + inc esi + push ecx + mov ecx, esi + call ext2_get_inode_block + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] + call ext2_get_block + pop ecx + dec ecx + mov eax, ebx + add ebx, [ext2_data.block_size] + mov [EXT2_end_block], ebx + jmp .wanted_start + + .end_dir: + pop edx + mov ebx, [EXT2_read_in_folder] + mov ecx, [EXT2_files_in_folder] + mov dword [edx], 1 ;version + xor eax, eax + mov [edx+4], ebx + mov [edx+8], ecx + lea edi, [edx + 12] + mov ecx, 20 / 4 + rep stosd + ret +;====================== end ext2_HdReadFolder + +;---------------------------------------------------------------- +; +; ext2_HdRead - read hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ext2_HdRead: + mov ebp, [ext2_data.root_inode] + + push ecx edx ebx + .next_folder: + push esi + @@: + lodsb + test al, al + jz .find_end + cmp al, '/' + jz .find_folder + jmp @B + + .find_end: + ;установим флаг что ищем файл или очередную папку + mov edi, 1 + jmp .find_any + .find_folder: + xor edi, edi + .find_any: + pop esi + + cmp byte [esi], 0 + jz .not_found + + or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode + mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков + add eax, [ext2_data.count_block_in_block] + mov [EXT2_end_block], eax + .next_block_folder: + mov eax, [ext2_data.count_block_in_block] + sub [EXT2_end_block], eax + jz .not_found + inc [EXT2_counter_blocks] + mov ecx, [EXT2_counter_blocks] + call ext2_get_inode_block + + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record + call ext2_get_block + + mov eax, esi + call ext2_test_block_by_name + cmp eax, esi ;нашли имя? + je .next_block_folder + + cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE + je .test_file + cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR + jne .not_found + .test_dir: + cmp edi, 0 + jne .this_is_folder + + mov eax, [ebx + EXT2_DIR_STRUC.inode] + mov ebx, [ext2_data.ext2_save_inode] ;все же папка. + call ext2_get_inode + mov ebp, ebx + jmp .next_folder + + .test_file: + cmp edi, 0 + je .not_found + + mov eax, [ebx + EXT2_DIR_STRUC.inode] + mov ebx, [ext2_data.ext2_save_inode] + call ext2_get_inode + jmp .get_file + + .not_found: + pop edx ecx ebx + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + .this_is_folder: + pop edx ecx ebx + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + .end_read: + ret + + ;-----------------------------------------------------------------------------final step + .get_file: + xchg bx, bx + mov ebp ,ebx + + ;pop eax edi ecx ; первый_блок память кол-во_байт + mov esi, [esp] + mov edi, [esp + 8] ;edi = нужно считать байт + + ;///// сравним хватит ли нам файла или нет + mov ebx, [esi+4] + mov eax, [esi] ; ebx : eax - стартовый номер байта + + mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl] + mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла + + cmp edx, ebx + ja .size_great + jb .size_less + + cmp ecx, eax + ja .size_great + + .size_less: + add esp, 12 + mov ebx, 0 + mov eax, 6 ;EOF + ret + .size_great: + ;прибавим к старту кол-во байт для чтения + add eax, edi + jnc @F + inc ebx + @@: + cmp edx, ebx + ja .size_great_great + jb .size_great_less + cmp ecx, eax + jae .size_great_great + ;jmp .size_great_less + ; а если равно, то не важно куда + .size_great_less: + or [EXT2_files_in_folder], 1 ;читаем по границе размера + sub ecx, [esi] + pop eax edi edx ;ecx - не меняем + jmp @F + + .size_great_great: + and [EXT2_files_in_folder], 0 ;читаем нормально + pop eax edi ecx + + @@: + push ecx ;сохраним размер считанных байт в стеке + test eax, eax + je .zero_start + + ;пока делаем п..ц криво =) + mov edx, [eax+4] + mov eax, [eax] + div [ext2_data.block_size] + + mov [EXT2_counter_blocks], eax ;номер блока запоминаем + + push ecx + mov ecx, eax + call ext2_get_inode_block + mov ebx , [ext2_data.ext2_save_block] + mov eax, ecx + call ext2_get_block + pop ecx + add ebx, edx + + neg edx + add edx,[ext2_data.block_size] ;block_size - стартоый блок = сколько байт 1-го блока + cmp ecx, edx + jbe .only_one_block + + mov eax, ecx + sub eax, edx + mov ecx, edx + + mov esi, ebx + rep movsb ;кусок 1-го блока + + .zero_start: + mov ebx, edi ;чтение блока прям в ebx + ;теперь в eax кол-во оставшихся байт для чтения + xor edx, edx + div [ext2_data.block_size] + mov [EXT2_end_block], eax ;кол-во целых блоков + @@: + cmp [EXT2_end_block], 0 + jz .finish_block + inc [EXT2_counter_blocks] + mov ecx, [EXT2_counter_blocks] + call ext2_get_inode_block + + mov eax, ecx ;а ebx уже забит нужным значением + call ext2_get_block + add ebx, [ext2_data.block_size] + + dec [EXT2_end_block] + jmp @B + + .finish_block: ;в edx - кол-во байт в последнем блоке + cmp edx, 0 + je .end_read + + mov ecx, [EXT2_counter_blocks] + inc ecx + call ext2_get_inode_block + + mov edi, ebx + mov eax, ecx + mov ebx, [ext2_data.ext2_save_block] + call ext2_get_block + + mov ecx, edx + + .only_one_block: + mov esi, ebx + rep movsb ;кусок 1-го блока (последнего) + pop ebx + cmp [EXT2_files_in_folder], 0 + jz @F + + mov eax, 6 ;EOF + ret + @@: + xor eax, eax + ret +;======================== + +ext2_HdRewrite: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + +ext2_HdWrite: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret +ext2_HdSetFileEnd: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret +ext2_HdGetFileInfo: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret +ext2_HdSetFileInfo: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret +ext2_HdDelete: +; xchg bx, bx + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index 40dd7d5045..7742e11b7c 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -169,7 +169,6 @@ reserve_hd_channel: call clear_hd_cache @@: pop eax - sti .ret: ret @@ -1049,6 +1048,8 @@ fs_HdRead: jz @f cmp [fs_type], 1 jz ntfs_HdRead + cmp [fs_type], 2 + jz ext2_HdRead or ebx, -1 mov eax, ERROR_UNKNOWN_FS ret @@ -1200,6 +1201,8 @@ fs_HdRead: fs_HdReadFolder: cmp [fs_type], 1 jz ntfs_HdReadFolder + cmp [fs_type], 2 + jz ext2_HdReadFolder cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -1586,6 +1589,8 @@ fs_HdRewrite: .common: cmp [fs_type], 1 jz ntfs_HdRewrite + cmp [fs_type], 2 + jz ext2_HdRewrite cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2120,6 +2125,8 @@ fs_HdWrite.ret11: fs_HdWrite: cmp [fs_type], 1 jz ntfs_HdWrite + cmp [fs_type], 2 + jz ext2_HdWrite cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2463,6 +2470,8 @@ hd_extend_file: fs_HdSetFileEnd: cmp [fs_type], 1 jz ntfs_HdSetFileEnd + cmp [fs_type], 2 + jz ext2_HdSetFileEnd cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2695,6 +2704,8 @@ fs_HdSetFileEnd: fs_HdGetFileInfo: cmp [fs_type], 1 jz ntfs_HdGetFileInfo + cmp [fs_type], 2 + jz ext2_HdGetFileInfo cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2723,6 +2734,8 @@ fs_HdGetFileInfo: fs_HdSetFileInfo: cmp [fs_type], 1 jz ntfs_HdSetFileInfo + cmp [fs_type], 2 + jz ext2_HdSetFileInfo cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2773,6 +2786,8 @@ fs_HdSetFileInfo: fs_HdDelete: cmp [fs_type], 1 jz ntfs_HdDelete + cmp [fs_type], 1 + jz ext2_HdDelete cmp [fs_type], 16 jz @f cmp [fs_type], 32 @@ -2915,4 +2930,5 @@ fs_HdDelete: @@: ret -; \end{diamond} +; \end{diamond} + diff --git a/kernel/trunk/fs/fs.inc b/kernel/trunk/fs/fs.inc index 71faa505c1..49c68eeb4b 100644 --- a/kernel/trunk/fs/fs.inc +++ b/kernel/trunk/fs/fs.inc @@ -388,7 +388,7 @@ choice_necessity_partition_1: .s: sub eax,ebx .f: - add eax,[fat32part] + add eax, [known_part] ; add eax,[fat32part] dec eax xor edx,edx imul eax,100 @@ -794,4 +794,5 @@ error: jmp i4 partition_string: dd 0 - db 32 + db 32 + diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 5aa7940278..1282f70366 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -104,7 +104,12 @@ file_system_lfn: ; 8 : delete file ; 9 : create directory -; parse file name +; parse file name + cmp dword [eax], 1 + jne @F + ;xchg bx,bx +@@: + ;up to file_system_lfn - TEMP!!! xchg ebx, eax lea esi, [ebx+20] lodsb @@ -169,8 +174,8 @@ file_system_lfn: cmp dword [ebx], 1 jnz .access_denied xor eax, eax - mov ebp, [ebx+12] - mov edx, [ebx+16] + mov ebp, [ebx+12] ;количество блоков для считывания + mov edx, [ebx+16] ;куда записывать рузельтат ; add edx, std_application_base_address push dword [ebx+4] ; first block mov ebx, [ebx+8] ; flags @@ -182,7 +187,7 @@ file_system_lfn: pop ecx mov byte [edx], 1 ; version .maindir_loop: - call esi + call esi ;!!!!!!!!!!!!!!!!!! jc .maindir_done inc dword [edx+8] dec dword [esp] @@ -537,7 +542,7 @@ fs_OnHdAndBd: mov dword [image_of_eax], 5 ; not found ret @@: - mov [fat32part], ecx + mov [known_part], ecx ; mov [fat32part], ecx push ebx esi call choice_necessity_partition_1 pop esi ebx @@ -1142,4 +1147,5 @@ get_full_file_name: test esi, esi jz .ret.ok mov byte [edi-1], '/' - jmp .set_copy_cont + jmp .set_copy_cont + diff --git a/kernel/trunk/fs/ntfs.inc b/kernel/trunk/fs/ntfs.inc index a28c48c93d..03799c67aa 100644 --- a/kernel/trunk/fs/ntfs.inc +++ b/kernel/trunk/fs/ntfs.inc @@ -8,7 +8,7 @@ $Revision$ -ntfs_test_bootsec: +ntfs_test_bootsec: ; in: ebx->buffer, edx=size of partition ; out: CF set <=> invalid ; 1. Name=='NTFS ' @@ -95,8 +95,8 @@ ntfs_test_bootsec: ntfs_setup: ; CODE XREF: part_set.inc ; By given bootsector, initialize some NTFS variables - call ntfs_test_bootsec - jc problem_fat_dec_count +; call ntfs_test_bootsec +; jc problem_fat_dec_count movzx eax, byte [ebx+13] mov [ntfs_data.sectors_per_cluster], eax mov eax, [ebx+0x28] @@ -1267,7 +1267,8 @@ ntfs_HdRead: ; eax = 0 ok read or other = errormsg ; ;-------------------------------------------------------------- -ntfs_HdReadFolder: +ntfs_HdReadFolder: + xchg bx, bx mov eax, 5 ; root cluster cmp byte [esi], 0 jz .doit @@ -1812,4 +1813,5 @@ ntfs_HdGetFileInfo: call ntfs_direntry_to_bdfe pop edi esi xor eax, eax - ret + ret + diff --git a/kernel/trunk/fs/part_set.inc b/kernel/trunk/fs/part_set.inc index 4d9ed4120f..acc5d9d566 100644 --- a/kernel/trunk/fs/part_set.inc +++ b/kernel/trunk/fs/part_set.inc @@ -26,7 +26,7 @@ align 4 ;****************************************************** PARTITION_START dd 0x3f PARTITION_END dd 0 -fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 +fs_type db 0 ; 0=none, 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32 align 4 fs_dependent_data_start: @@ -55,7 +55,7 @@ fs_dependent_data_end: file_system_data_size = $ - PARTITION_START if file_system_data_size > 96 ERROR: sizeof(file system data) too big! -end if +end if virtual at fs_dependent_data_start ; NTFS data @@ -76,8 +76,30 @@ ntfs_data: if $ > fs_dependent_data_end ERROR: increase sizeof(fs_dependent_data)! end if +end virtual + +virtual at fs_dependent_data_start +; EXT2 data +ext2_data: + .log_block_size dd ? + .block_size dd ? + .count_block_in_block dd ? + .blocks_per_group dd ? + .inodes_per_group dd ? + .global_desc_table dd ? + .root_inode dd ? ; pointer to root inode in memory + .inode_size dd ? + .count_pointer_in_block dd ? ; block_size / 4 + .count_pointer_in_block_square dd ? ; (block_size / 4)**2 + .ext2_save_block dd ? ; 1 楤 + .ext2_temp_block dd ? ; 楤 + .ext2_save_inode dd ? ; inode 楤 + .ext2_temp_inode dd ? ; inode 楤 +if $ > fs_dependent_data_end +ERROR: increase sizeof(fs_dependent_data)! +end if end virtual - + ;*************************************************************************** ; End place ; Mario79 @@ -104,7 +126,8 @@ iglobal db 0xd4 ; Old Multiuser DOS secured: fat16 <32M db 0xd6 ; Old Multiuser DOS secured: fat16 >32M db 0x07 ; NTFS - db 0x27 ; NTFS, hidden + db 0x17 ; NTFS, hidden + db 0x83 ; Linux native file system (ext2fs) partition_types_end: @@ -118,17 +141,15 @@ iglobal endg ; Partition chain used: -; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 -;========================================================== -; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- -; extended --+ extended --+ extended --+ extended --+ -; 0 0 0 0 -; 0 0 0 0 -; Notes: -; - extended partition need to be in second entry on table -; - it will skip over removed partitions - -set_FAT32_variables: +; MBR <--------------------- +; | | +; |-> PARTITION1 | +; |-> EXTENDED PARTITION - ;not need be second partition +; |-> PARTITION3 +; |-> PARTITION4 + +set_PARTITION_variables: +set_FAT32_variables: ;deprecated mov [problem_partition],0 call reserve_hd1 call reserve_hd_channel @@ -139,12 +160,12 @@ set_FAT32_variables: je problem_hd xor ecx,ecx ; partition count - mov edx,-1 ; flag for partition - xor eax,eax ; read MBR + or edx,-1 ; flag for partition + xor eax,eax ; address MBR xor ebp,ebp ; extended partition start -new_partition: - test ebp,ebp ; is there extended partition? +new_mbr: + test ebp,ebp ; is there extended partition? (MBR or EMBR) jnz extended_already_set ; yes xchg ebp,eax ; no. set it now @@ -158,26 +179,25 @@ extended_already_set: cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? jnz end_partition_chain cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition -; jz next_partition - jnz .next_primary_partition + jnz test_primary_partition_0 cmp dword [ebx+0x1be+0xc+16],0 - jnz next_primary_partition + jnz test_primary_partition_1 cmp dword [ebx+0x1be+0xc+16+16],0 - jnz next_primary_partition_1 + jnz test_primary_partition_2 cmp dword [ebx+0x1be+0xc+16+16+16],0 - jnz next_primary_partition_2 - jmp next_partition - -.next_primary_partition: + jnz test_primary_partition_3 + jmp end_partition_chain + +test_primary_partition_0: push eax mov al,[ebx+0x1be+4] ; get primary partition type call scan_partition_types pop eax - jnz next_primary_partition ; no. skip over + jnz test_primary_partition_1 ; no. skip over inc ecx - cmp ecx,[fat32part] ; is it wanted partition? - jnz next_primary_partition ; no + cmp ecx,[known_part] ; is it wanted partition? + jnz test_primary_partition_1 ; no mov edx, eax ; start sector add edx, [ebx+0x1be+8] ; add relative start @@ -190,16 +210,16 @@ extended_already_set: mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) pop edx -next_primary_partition: +test_primary_partition_1: push eax mov al,[ebx+0x1be+4+16] ; get primary partition type call scan_partition_types pop eax - jnz next_primary_partition_1 ; no. skip over + jnz test_primary_partition_2 ; no. skip over inc ecx - cmp ecx,[fat32part] ; is it wanted partition? - jnz next_primary_partition_1 ; no + cmp ecx,[known_part] ; is it wanted partition? + jnz test_primary_partition_2 ; no mov edx, eax add edx, [ebx+0x1be+8+16] @@ -211,16 +231,16 @@ next_primary_partition: mov [fs_type], dl pop edx -next_primary_partition_1: +test_primary_partition_2: push eax mov al,[ebx+0x1be+4+16+16] ; get primary partition type call scan_partition_types pop eax - jnz next_primary_partition_2 ; no. skip over + jnz test_primary_partition_3 ; no. skip over inc ecx - cmp ecx,[fat32part] ; is it wanted partition? - jnz next_primary_partition_2 ; no + cmp ecx,[known_part] ; is it wanted partition? + jnz test_primary_partition_3 ; no mov edx, eax add edx, [ebx+0x1be+8+16+16] @@ -232,16 +252,16 @@ next_primary_partition_1: mov [fs_type], dl pop edx -next_primary_partition_2: +test_primary_partition_3: push eax mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type call scan_partition_types pop eax - jnz next_partition ; no. skip over + jnz test_ext_partition_0 ; no. skip over inc ecx - cmp ecx,[fat32part] ; is it wanted partition? - jnz next_partition ; no + cmp ecx,[known_part] ; is it wanted partition? + jnz test_ext_partition_0 ; no mov edx, eax add edx, [ebx+0x1be+8+16+16+16] @@ -253,40 +273,40 @@ next_primary_partition_2: mov [fs_type], dl pop edx -next_partition: +test_ext_partition_0: push eax mov al,[ebx+0x1be+4] ; get extended partition type call scan_extended_types pop eax - jnz next_partition_1 + jnz test_ext_partition_1 mov eax,[ebx+0x1be+8] ; add relative start test eax,eax ; is there extended partition? - jnz new_partition ; yes. read it + jnz new_mbr ; yes. read it -next_partition_1: +test_ext_partition_1: push eax mov al,[ebx+0x1be+4+16] ; get extended partition type call scan_extended_types pop eax - jnz next_partition_2 + jnz test_ext_partition_2 - mov eax,[ebx+0x1be+8+16] ; add relative start + mov eax,[ebx+0x1be+8+16] ; add relative start test eax,eax ; is there extended partition? - jnz new_partition ; yes. read it + jnz new_mbr ; yes. read it -next_partition_2: +test_ext_partition_2: push eax mov al,[ebx+0x1be+4+16+16] ; get extended partition type call scan_extended_types pop eax - jnz next_partition_3 + jnz test_ext_partition_3 mov eax,[ebx+0x1be+8+16+16] ; add relative start test eax,eax ; is there extended partition? - jnz new_partition ; yes. read it - -next_partition_3: + jnz new_mbr ; yes. read it + +test_ext_partition_3: push eax mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type call scan_extended_types @@ -295,8 +315,8 @@ next_partition_3: mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition test eax,eax ; is there extended partition? - jnz new_partition ; yes. read it - + jnz new_mbr ; yes. read it + end_partition_chain: mov [partition_count],ecx @@ -366,14 +386,21 @@ hd_and_partition_ok: add eax, [PARTITION_START] call hd_read cmp [hd_error], 0 - jnz problem_fat_dec_count ; 졠... + jnz problem_fat_dec_count ; no chance... boot_read_ok: -; mov [hd_setup], 0 + ; if we are running on NTFS, check bootsector -; cmp [fs_type], 7 -; jz ntfs_setup - call ntfs_test_bootsec - jnc ntfs_setup + + call ntfs_test_bootsec ; test ntfs + jnc ntfs_setup + + call ext2_test_superblock ; test ext2fs + jnc ext2_setup + + mov eax, [PARTITION_START] ;ext2 test changes [buffer] + call hd_read + cmp [hd_error], 0 + jnz problem_fat_dec_count cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? jnz problem_fat_dec_count @@ -478,4 +505,5 @@ fat16_partition: mov [fs_type],16 ; Fat16 call free_hd_channel mov [hd1_status],0 ; free - ret + ret + diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 542d0597c0..6db891138e 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -216,7 +216,8 @@ include "fs/ntfs.inc" ; read / write for ntfs filesystem include "fs/fat12.inc" ; read / write for fat12 filesystem include "blkdev/rd.inc" ; ramdisk read /write include "fs/fs_lfn.inc" ; syscall, version 2 -include "fs/iso9660.inc" ; read for iso9660 filesystem CD +include "fs/iso9660.inc" ; read for iso9660 filesystem CD +include "fs/ext2.inc" ; read / write for ext2 filesystem ; sound @@ -285,4 +286,5 @@ include "core/conf_lib.inc" include "core/ext_lib.inc" ; list of external functions -include "imports.inc" +include "imports.inc" +