Rev 4287 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4287 | Rev 5201 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 14... | Line 14... | ||
14 | DISK_STATUS_OK = 0 ; success |
14 | DISK_STATUS_OK = 0 ; success |
15 | DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable |
15 | DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable |
16 | DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters |
16 | DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters |
17 | DISK_STATUS_NO_MEDIA = 2 ; no media present |
17 | DISK_STATUS_NO_MEDIA = 2 ; no media present |
18 | DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data |
18 | DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data |
- | 19 | DISK_STATUS_NO_MEMORY = 4 ; insufficient memory for driver operation |
|
19 | ; Driver flags. Represent bits in DISK.DriverFlags. |
20 | ; Driver flags. Represent bits in DISK.DriverFlags. |
20 | DISK_NO_INSERT_NOTIFICATION = 1 |
21 | DISK_NO_INSERT_NOTIFICATION = 1 |
21 | ; Media flags. Represent bits in DISKMEDIAINFO.Flags. |
22 | ; Media flags. Represent bits in DISKMEDIAINFO.Flags. |
22 | DISK_MEDIA_READONLY = 1 |
23 | DISK_MEDIA_READONLY = 1 |
Line 99... | Line 100... | ||
99 | 100 | ||
100 | ; This structure represents the disk cache. To follow the old implementation, |
101 | ; This structure represents the disk cache. To follow the old implementation, |
101 | ; there are two distinct caches for a disk, one for "system" data,and the other |
102 | ; there are two distinct caches for a disk, one for "system" data,and the other |
102 | ; for "application" data. |
103 | ; for "application" data. |
103 | struct DISKCACHE |
- | |
104 | mutex MUTEX |
- | |
105 | ; Lock to protect the cache. |
104 | struct DISKCACHE |
106 | ; The following fields are inherited from data32.inc:cache_ideX. |
105 | ; The following fields are inherited from data32.inc:cache_ideX. |
107 | pointer dd ? |
106 | pointer dd ? |
108 | data_size dd ? ; unused |
107 | data_size dd ? ; unused |
109 | data dd ? |
108 | data dd ? |
110 | sad_size dd ? |
109 | sad_size dd ? |
- | 110 | search_start dd ? |
|
111 | search_start dd ? |
111 | sector_size_log dd ? |
Line 112... | Line 112... | ||
112 | ends |
112 | ends |
113 | 113 | ||
114 | ; This structure represents a disk device and its media for the kernel. |
114 | ; This structure represents a disk device and its media for the kernel. |
Line 167... | Line 167... | ||
167 | ; Number of partitions on this media. |
167 | ; Number of partitions on this media. |
168 | Partitions dd ? |
168 | Partitions dd ? |
169 | ; Pointer to array of .NumPartitions pointers to PARTITION structures. |
169 | ; Pointer to array of .NumPartitions pointers to PARTITION structures. |
170 | cache_size dd ? |
170 | cache_size dd ? |
171 | ; inherited from cache_ideX_size |
171 | ; inherited from cache_ideX_size |
- | 172 | CacheLock MUTEX |
|
- | 173 | ; Lock to protect both caches. |
|
172 | SysCache DISKCACHE |
174 | SysCache DISKCACHE |
173 | AppCache DISKCACHE |
175 | AppCache DISKCACHE |
174 | ; Two caches for the disk. |
176 | ; Two caches for the disk. |
175 | ends |
177 | ends |
Line 268... | Line 270... | ||
268 | ; filesystem operations are referencing the same filesystem data, this is |
270 | ; filesystem operations are referencing the same filesystem data, this is |
269 | ; better resolved at the level of the filesystem. |
271 | ; better resolved at the level of the filesystem. |
270 | endg |
272 | endg |
Line 271... | Line 273... | ||
271 | 273 | ||
272 | iglobal |
274 | iglobal |
273 | ; The function 'disk_scan_partitions' needs three 512-byte buffers for |
275 | ; The function 'disk_scan_partitions' needs three sector-sized buffers for |
274 | ; MBR, bootsector and fs-temporary sector data. It can not use the static |
276 | ; MBR, bootsector and fs-temporary sector data. It can not use the static |
275 | ; buffers always, since it can be called for two or more disks in parallel. |
277 | ; buffers always, since it can be called for two or more disks in parallel. |
276 | ; However, this case is not typical. We reserve three static 512-byte buffers |
278 | ; However, this case is not typical. We reserve three static 512-byte buffers |
277 | ; and a flag that these buffers are currently used. If 'disk_scan_partitions' |
279 | ; and a flag that these buffers are currently used. If 'disk_scan_partitions' |
278 | ; detects that the buffers are currently used, it allocates buffers from the |
280 | ; detects that the buffers are currently used, it allocates buffers from the |
279 | ; heap. |
281 | ; heap. Also, the heap is used when sector size is other than 512. |
280 | ; The flag is implemented as a global dword variable. When the static buffers |
282 | ; The flag is implemented as a global dword variable. When the static buffers |
281 | ; are not used, the value is -1. When the static buffers are used, the value |
283 | ; are not used, the value is -1. When the static buffers are used, the value |
282 | ; is normally 0 and temporarily can become greater. The function increments |
284 | ; is normally 0 and temporarily can become greater. The function increments |
283 | ; this value. If the resulting value is zero, it uses the buffers and |
285 | ; this value. If the resulting value is zero, it uses the buffers and |
Line 635... | Line 637... | ||
635 | ; esi = pointer to the DISK structure. |
637 | ; esi = pointer to the DISK structure. |
636 | disk_scan_partitions: |
638 | disk_scan_partitions: |
637 | ; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list. |
639 | ; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list. |
638 | and [esi+DISK.NumPartitions], 0 |
640 | and [esi+DISK.NumPartitions], 0 |
639 | and [esi+DISK.Partitions], 0 |
641 | and [esi+DISK.Partitions], 0 |
640 | ; 2. Currently we can work only with 512-bytes sectors. Check this restriction. |
- | |
641 | ; The only exception is 2048-bytes CD/DVD, but they are not supported yet by |
- | |
642 | ; this code. |
- | |
643 | cmp [esi+DISK.MediaInfo.SectorSize], 512 |
- | |
644 | jz .doscan |
- | |
645 | DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize] |
- | |
646 | ret |
- | |
647 | .doscan: |
- | |
648 | ; 3. Acquire the buffer for MBR and bootsector tests. See the comment before |
642 | ; 2. Acquire the buffer for MBR and bootsector tests. See the comment before |
649 | ; the 'partition_buffer_users' variable. |
643 | ; the 'partition_buffer_users' variable. |
- | 644 | mov eax, [esi+DISK.MediaInfo.SectorSize] |
|
- | 645 | cmp eax, 512 |
|
- | 646 | jnz @f |
|
650 | mov ebx, mbr_buffer ; assume the global buffer is free |
647 | mov ebx, mbr_buffer ; assume the global buffer is free |
651 | lock inc [partition_buffer_users] |
648 | lock inc [partition_buffer_users] |
652 | jz .buffer_acquired ; yes, it is free |
649 | jz .buffer_acquired ; yes, it is free |
653 | lock dec [partition_buffer_users] ; no, we must allocate |
650 | lock dec [partition_buffer_users] ; no, we must allocate |
- | 651 | @@: |
|
- | 652 | lea eax, [eax*3] |
|
654 | stdcall kernel_alloc, 512*3 |
653 | stdcall kernel_alloc, eax |
655 | test eax, eax |
654 | test eax, eax |
656 | jz .nothing |
655 | jz .nothing |
657 | xchg eax, ebx |
656 | xchg eax, ebx |
658 | .buffer_acquired: |
657 | .buffer_acquired: |
659 | ; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no |
658 | ; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no |
660 | ; more than MAX_NUM_PARTITION times. |
659 | ; more than MAX_NUM_PARTITION times. |
661 | ; 4. Prepare things for the loop. |
660 | ; 3. Prepare things for the loop. |
662 | ; ebp will hold the sector number for current MBR/EBR. |
661 | ; ebp will hold the sector number for current MBR/EBR. |
663 | ; [esp] will hold the sector number for current extended partition, if there |
662 | ; [esp] will hold the sector number for current extended partition, if there |
664 | ; is one. |
663 | ; is one. |
665 | ; [esp+4] will hold the counter that prevents long loops. |
664 | ; [esp+4] will hold the counter that prevents long loops. |
666 | push ebp ; save ebp |
665 | push ebp ; save ebp |
667 | push MAX_NUM_PARTITIONS ; the counter of max MBRs to process |
666 | push MAX_NUM_PARTITIONS ; the counter of max MBRs to process |
668 | xor ebp, ebp ; start from sector zero |
667 | xor ebp, ebp ; start from sector zero |
669 | push ebp ; no extended partition yet |
668 | push ebp ; no extended partition yet |
- | 669 | ; 4. MBR is 512 bytes long. If sector size is less than 512 bytes, |
|
- | 670 | ; assume no MBR, no partitions and go to 10. |
|
- | 671 | cmp [esi+DISK.MediaInfo.SectorSize], 512 |
|
- | 672 | jb .notmbr |
|
670 | .new_mbr: |
673 | .new_mbr: |
671 | ; 5. Read the current sector. |
674 | ; 5. Read the current sector. |
672 | ; Note that 'read' callback operates with 64-bit sector numbers, so we must |
675 | ; Note that 'read' callback operates with 64-bit sector numbers, so we must |
673 | ; push additional zero as a high dword of sector number. |
676 | ; push additional zero as a high dword of sector number. |
674 | mov al, DISKFUNC.read |
677 | mov al, DISKFUNC.read |
Line 983... | Line 986... | ||
983 | ; 1. Read the bootsector to the buffer. |
986 | ; 1. Read the bootsector to the buffer. |
984 | ; When disk_add_partition is called, ebx contains a pointer to |
987 | ; When disk_add_partition is called, ebx contains a pointer to |
985 | ; a three-sectors-sized buffer. This function saves ebx in the stack |
988 | ; a three-sectors-sized buffer. This function saves ebx in the stack |
986 | ; immediately before ebp. |
989 | ; immediately before ebp. |
987 | mov ebx, [ebp-4] ; get buffer |
990 | mov ebx, [ebp-4] ; get buffer |
988 | add ebx, 512 ; advance over MBR data to bootsector data |
991 | add ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data |
989 | add ebp, 8 ; ebp points to part of PARTITION structure |
992 | add ebp, 8 ; ebp points to part of PARTITION structure |
990 | xor eax, eax ; first sector of the partition |
993 | xor eax, eax ; first sector of the partition |
991 | call fs_read32_sys |
994 | call fs_read32_sys |
992 | push eax |
995 | push eax |
993 | ; 2. Run tests for all supported filesystems. If at least one test succeeded, |
996 | ; 2. Run tests for all supported filesystems. If at least one test succeeded, |
994 | ; go to 4. |
997 | ; go to 4. |
995 | ; For tests: |
998 | ; For tests: |
996 | ; ebp -> first three fields of PARTITION structure, .start, .length, .disk; |
999 | ; ebp -> first three fields of PARTITION structure, .start, .length, .disk; |
997 | ; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, |
1000 | ; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, |
998 | ; ebx points to the buffer for bootsector, |
1001 | ; ebx points to the buffer for bootsector, |
999 | ; ebx+512 points to 512-bytes buffer that can be used for anything. |
1002 | ; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything. |
1000 | call fat_create_partition |
1003 | call fat_create_partition |
1001 | test eax, eax |
1004 | test eax, eax |
1002 | jnz .success |
1005 | jnz .success |
1003 | call ntfs_create_partition |
1006 | call ntfs_create_partition |
1004 | test eax, eax |
1007 | test eax, eax |