Subversion Repositories Kolibri OS

Rev

Rev 3626 | Rev 5201 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
527 diamond 2
;;                                                              ;;
4287 Serge 3
;; Copyright (C) KolibriOS team 2013. All rights reserved.      ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
527 diamond 6
;; RAMDISK functions                                            ;;
431 serge 7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 8
 
593 mikedld 9
$Revision: 4287 $
10
 
4287 Serge 11
iglobal
12
align 4
13
ramdisk_functions:
14
        dd      .size
15
        dd      0       ; no close() function
16
        dd      0       ; no closemedia() function
17
        dd      ramdisk_querymedia
18
        dd      ramdisk_read
19
        dd      ramdisk_write
20
        dd      0       ; no flush() function
21
        dd      ramdisk_adjust_cache_size
22
.size = $ - ramdisk_functions
23
endg
593 mikedld 24
 
4287 Serge 25
; See memmap.inc.
26
; Currently size of memory allocated for the ramdisk is fixed.
27
; This should be revisited when/if memory map would become more dynamic.
28
RAMDISK_CAPACITY = 2880 ; in sectors
1 ha 29
 
4287 Serge 30
iglobal
31
align 4
32
ramdisk_actual_size     dd      RAMDISK_CAPACITY
171 diamond 33
endg
34
 
4287 Serge 35
; This function is called early in boot process.
36
; It creates filesystem /rd/1 based on raw image data loaded by somebody before
37
; to memory named as RAMDISK with max size RAMDISK_CAPACITY, may be less.
38
proc ramdisk_init
83 diamond 39
iglobal
4287 Serge 40
ramdisk_name    db      'rd',0
83 diamond 41
endg
4287 Serge 42
        push    ebx esi ; save used registers to be stdcall
43
; 1. Register the device and the (always inserted) media in the disk subsystem.
44
        stdcall disk_add, ramdisk_functions, ramdisk_name, 0, 0
45
        test    eax, eax
46
        jz      .fail
47
        mov     ebx, eax
48
        stdcall disk_media_changed, eax, 1
49
; 2. We don't know actual size of loaded image,
50
; so try to calculate it using partition structure,
51
; assuming that file systems fill the real size based on contents of the partition.
52
; 2a. Prepare for loop over partitions.
3555 Serge 53
        xor     ecx, ecx
4287 Serge 54
        xor     edx, edx
55
; 2b. Check that at least one partition was recognized.
56
        cmp     [ebx+DISK.NumPartitions], ecx
57
        jz      .fail
58
; 2c. Loop over partitions.
59
.partitions:
60
; For every partition, set edx to maximum between edx and end of partition.
61
        mov     esi, [ebx+DISK.Partitions]
62
        mov     esi, [esi+ecx*4]
63
        mov     eax, dword [esi+PARTITION.FirstSector]
64
        add     eax, dword [esi+PARTITION.Length]
65
        cmp     eax, edx
66
        jb      @f
67
        mov     edx, eax
83 diamond 68
@@:
3555 Serge 69
        inc     ecx
4287 Serge 70
        cmp     ecx, [ebx+DISK.NumPartitions]
71
        jb      .partitions
72
; 3. Reclaim unused memory, if any.
73
        mov     [ramdisk_actual_size], edx
74
        add     edx, 7  ; aligning up
75
        shr     edx, 3  ; 512-byte sectors -> 4096-byte pages
76
        mov     esi, RAMDISK_CAPACITY / 8       ; aligning down
77
        sub     esi, edx
78
        jbe     .no_reclaim
79
        shl     edx, 12
80
        add     edx, RAMDISK - OS_BASE
83 diamond 81
@@:
4287 Serge 82
        mov     eax, edx
83
        call    free_page
84
        add     edx, 0x1000
85
        dec     esi
3555 Serge 86
        jnz     @b
4287 Serge 87
.no_reclaim:
88
        pop     esi ebx ; restore used registers to be stdcall
3555 Serge 89
        ret
4287 Serge 90
.fail:
91
        dbgstr 'Failed to initialize ramdisk'
92
        pop     esi ebx ; restore used registers to be stdcall
3555 Serge 93
        ret
4287 Serge 94
endp
83 diamond 95
 
4287 Serge 96
; Returns information about disk media.
97
proc ramdisk_querymedia
98
  virtual at esp+4
99
    .userdata dd ?
100
    .info dd ?
101
  end virtual
102
; Media is always present, sector size is always 512 bytes.
103
        mov     edx, [.userdata]
104
        mov     ecx, [.info]
105
        mov     [ecx+DISKMEDIAINFO.Flags], 0
106
        mov     [ecx+DISKMEDIAINFO.SectorSize], 512
107
        mov     eax, [ramdisk_actual_size]
108
        mov     dword [ecx+DISKMEDIAINFO.Capacity], eax
109
        mov     dword [ecx+DISKMEDIAINFO.Capacity+4], 0
110
; Return zero as an indicator of success.
3555 Serge 111
        xor     eax, eax
4287 Serge 112
        retn    8
113
endp
83 diamond 114
 
4287 Serge 115
; Common procedure for reading and writing.
116
; operation = 0 for reading, operation = 1 for writing.
117
; Arguments of ramdisk_read and ramdisk_write are the same.
118
macro ramdisk_read_write operation
119
{
120
        push    esi edi         ; save used registers to be stdcall
121
        mov     esi, [userdata]
122
        mov     edi, [numsectors_ptr]
123
; 1. Determine number of sectors to be transferred.
124
; This is either the requested number of sectors or number of sectors
125
; up to the disk boundary, depending of what is less.
3555 Serge 126
        xor     ecx, ecx
4287 Serge 127
; 1a. Test whether [start_sector] is less than RAMDISK_CAPACITY.
128
; If so, calculate number of sectors between [start_sector] and RAMDISK_CAPACITY.
129
; Otherwise, the actual number of sectors is zero.
130
        cmp     dword [start_sector+4], ecx
131
        jnz     .got_number
132
        mov     eax, [ramdisk_actual_size]
133
        sub     eax, dword [start_sector]
134
        jbe     .got_number
135
; 1b. Get the requested number of sectors.
136
        mov     ecx, [edi]
137
; 1c. If it is greater than number of sectors calculated in 1a, use the value
138
; from 1a.
3555 Serge 139
        cmp     ecx, eax
4287 Serge 140
        jb      .got_number
141
        mov     ecx, eax
142
.got_number:
143
; 2. Compare the actual number of sectors with requested. If they are
144
; equal, set eax (it will be the returned value) to zero. Otherwise,
145
; use DISK_STATUS_END_OF_MEDIA.
3555 Serge 146
        xor     eax, eax
4287 Serge 147
        cmp     ecx, [edi]
3555 Serge 148
        jz      @f
4287 Serge 149
        mov     al, DISK_STATUS_END_OF_MEDIA
3555 Serge 150
@@:
4287 Serge 151
; 3. Store the actual number of sectors.
152
        mov     [edi], ecx
153
; 4. Calculate source and destination addresses.
154
if operation = 0 ; reading?
155
        mov     esi, dword [start_sector]
156
        shl     esi, 9
157
        add     esi, RAMDISK
158
        mov     edi, [buffer]
159
else ; writing?
160
        mov     edi, dword [start_sector]
3555 Serge 161
        shl     edi, 9
4287 Serge 162
        add     edi, RAMDISK
163
        mov     esi, [buffer]
164
end if
165
; 5. Calculate number of dwords to be transferred.
166
        shl     ecx, 9-2
167
; 6. Copy data.
3555 Serge 168
        rep movsd
4287 Serge 169
; 7. Return. The value in eax was calculated in step 2.
170
        pop     edi esi         ; restore used registers to be stdcall
171
}
83 diamond 172
 
4287 Serge 173
; Reads one or more sectors from the device.
174
proc ramdisk_read userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
175
        ramdisk_read_write 0
3555 Serge 176
        ret
4287 Serge 177
endp
83 diamond 178
 
4287 Serge 179
; Writes one or more sectors to the device.
180
proc ramdisk_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
181
        ramdisk_read_write 1
3555 Serge 182
        ret
4287 Serge 183
endp
83 diamond 184
 
4287 Serge 185
; The kernel calls this function when initializing cache subsystem for
186
; the media. This call allows the driver to adjust the cache size.
187
proc ramdisk_adjust_cache_size
188
  virtual at esp+4
189
    .userdata dd ?
190
    .suggested_size dd ?
191
  end virtual
192
; Since ramdisk does not need cache, just return 0.
3555 Serge 193
        xor     eax, eax
4287 Serge 194
        retn    8
195
endp