Subversion Repositories Kolibri OS

Rev

Rev 21 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 21 Rev 25
1
if ~defined mem_inc
1
if ~defined mem_inc
2
mem_inc_fix:
2
mem_inc_fix:
3
mem_inc fix mem_inc_fix
3
mem_inc fix mem_inc_fix
4
;include "memmanag.inc"
4
;include "memmanag.inc"
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;High-level memory management in MenuetOS. 
6
;;High-level memory management in MenuetOS. 
7
;;It uses memory manager in memmanager.inc 
7
;;It uses memory manager in memmanager.inc 
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
second_base_address=0xC0000000
9
second_base_address=0xC0000000
10
std_application_base_address=0x10000000
10
std_application_base_address=0x10000000
11
general_page_table_ dd 0
11
general_page_table_ dd 0
12
general_page_table=general_page_table_+second_base_address
12
general_page_table=general_page_table_+second_base_address
13
;-----------------------------------------------------------------------------
13
;-----------------------------------------------------------------------------
14
create_general_page_table:
14
create_general_page_table:
15
;input
15
;input
16
;  none
16
;  none
17
;output
17
;output
18
;  none
18
;  none
19
;Procedure create general page directory and write
19
;Procedure create general page directory and write
20
;it address to [general_page_table].
20
;it address to [general_page_table].
21
    pushad
21
    pushad
22
    mov   eax,1                  ;alloc 1 page
22
    mov   eax,1                  ;alloc 1 page
23
    mov   ebx,general_page_table ;write address to [general_page_table]
23
    mov   ebx,general_page_table ;write address to [general_page_table]
24
    call  MEM_Alloc_Pages        ;allocate page directory
24
    call  MEM_Alloc_Pages        ;allocate page directory
25
    mov   eax,[general_page_table]
25
    mov   eax,[general_page_table]
26
    call  MEM_Get_Linear_Address ;eax - linear address of page directory
26
    call  MEM_Get_Linear_Address ;eax - linear address of page directory
27
    mov   edi,eax
27
    mov   edi,eax
28
    mov   ebx,eax
28
    mov   ebx,eax
29
    xor   eax,eax
29
    xor   eax,eax
30
    mov   ecx,4096/4
30
    mov   ecx,4096/4
31
    cld
31
    cld
32
    rep   stosd                  ;clear page directory
32
    rep   stosd                  ;clear page directory
33
    
33
    
34
    mov   eax,4
34
    mov   eax,4
35
    mov   edx,eax
35
    mov   edx,eax
36
    call  MEM_Alloc_Pages        ;alloc page tables for 0x0-0x1000000 region 
36
    call  MEM_Alloc_Pages        ;alloc page tables for 0x0-0x1000000 region 
37
    cmp   eax,edx
37
    cmp   eax,edx
38
    jnz   $                      ;hang if not enough memory
38
    jnz   $                      ;hang if not enough memory
39
    
39
    
40
;fill page tables
40
;fill page tables
41
    xor   esi,esi  
41
    xor   esi,esi  
42
    mov   ebp,7
42
    mov   ebp,7
43
    
43
    
44
.loop:
44
.loop:
45
;esi - number of page in page directory
45
;esi - number of page in page directory
46
;ebp - current page address
46
;ebp - current page address
47
;ebx - linear address of page directory
47
;ebx - linear address of page directory
48
    mov   eax,[ebx+4*esi]
48
    mov   eax,[ebx+4*esi]
49
    add   dword [ebx+4*esi],7    ;add flags to address of page table
49
    add   dword [ebx+4*esi],7    ;add flags to address of page table
50
    call  MEM_Get_Linear_Address
50
    call  MEM_Get_Linear_Address
51
;eax - linear address of page table     
51
;eax - linear address of page table     
52
    mov   ecx,4096/4
52
    mov   ecx,4096/4
53
;ecx (counter) - number of pages in page table
53
;ecx (counter) - number of pages in page table
54
;current address=4Mb*esi     
54
;current address=4Mb*esi     
55
    cmp   esi,2
55
    cmp   esi,2
56
    jz    .start_lfb_map         ;lfb map begin at 0x800000
56
    jz    .start_lfb_map         ;lfb map begin at 0x800000
57
    cmp   esi,3
57
    cmp   esi,3
58
    jz    .end_lfb_map           ;lfb map end at 0xC00000
58
    jz    .end_lfb_map           ;lfb map end at 0xC00000
59
    jmp   .loop1
59
    jmp   .loop1
60
.start_lfb_map:
60
.start_lfb_map:
61
;current address=lfb address
61
;current address=lfb address
62
    mov   ebp,[0x2f0000+0x9018]
62
    mov   ebp,[0x2f0000+0x9018]
63
    add   ebp,7                  ;add flags
63
    add   ebp,7                  ;add flags
64
    jmp   .loop1
64
    jmp   .loop1
65
.end_lfb_map:
65
.end_lfb_map:
66
;current address=linear address
66
;current address=linear address
67
    mov   ebp,12*0x100000+7
67
    mov   ebp,12*0x100000+7
68
    
68
    
69
.loop1:
69
.loop1:
70
    mov   [eax],ebp              ;write page address (with flags) in page table 
70
    mov   [eax],ebp              ;write page address (with flags) in page table 
71
    add   eax,4
71
    add   eax,4
72
    add   ebp,4096               ;size of page=4096 bytes
72
    add   ebp,4096               ;size of page=4096 bytes
73
    loop  .loop1
73
    loop  .loop1
74
    
74
    
75
    inc   esi                    ;next page directory entry
75
    inc   esi                    ;next page directory entry
76
    cmp   esi,edx
76
    cmp   esi,edx
77
    jnz   .loop
77
    jnz   .loop
78
    
78
    
79
;map region 0x80000000-0x803fffff to 0x800000-0xcfffff
79
;map region 0x80000000-0x803fffff to 0x800000-0xcfffff
80
    mov   eax,1                  ;size of the region is 4Mb so only 1 page table needed
80
    mov   eax,1                  ;size of the region is 4Mb so only 1 page table needed
81
    mov   edx,ebx                ;ebx still contains linear address of the page directory
81
    mov   edx,ebx                ;ebx still contains linear address of the page directory
82
    add   ebx,0x800
82
    add   ebx,0x800
83
    call  MEM_Alloc_Pages        ;alloc page table for the region
83
    call  MEM_Alloc_Pages        ;alloc page table for the region
84
    mov   eax,[ebx]
84
    mov   eax,[ebx]
85
    add   dword [ebx],7          ;add flags
85
    add   dword [ebx],7          ;add flags
86
    call  MEM_Get_Linear_Address ;get linear address of the page table
86
    call  MEM_Get_Linear_Address ;get linear address of the page table
87
    mov   ebx,eax
87
    mov   ebx,eax
88
    mov   ecx,4096/4             ;number of pages in page table
88
    mov   ecx,4096/4             ;number of pages in page table
89
    mov   eax,8*0x100000+7
89
    mov   eax,8*0x100000+7
90
.loop3:
90
.loop3:
91
;ebx - linear address of page table
91
;ebx - linear address of page table
92
;eax - current linear address with flags
92
;eax - current linear address with flags
93
    mov   [ebx],eax
93
    mov   [ebx],eax
94
    add   ebx,4
94
    add   ebx,4
95
    add   eax,4096
95
    add   eax,4096
96
    loop  .loop3
96
    loop  .loop3
97
    
97
    
98
;map region 0xC0000000-* to 0x0-*
98
;map region 0xC0000000-* to 0x0-*
99
    mov   esi,edx                ;esi=linear address of the page directory 
99
    mov   esi,edx                ;esi=linear address of the page directory 
100
    lea   edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
100
    lea   edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
101
    mov   ecx,4
101
    mov   ecx,4
102
    rep   movsd                  ;first 16Mb of the region mapped as 0x0-0x1000000 block
102
    rep   movsd                  ;first 16Mb of the region mapped as 0x0-0x1000000 block
103
    mov   eax,[0xfe8c]           ;eax=memory size
103
    mov   eax,[0xfe8c]           ;eax=memory size
104
    add   eax,0x3fffff
104
    add   eax,0x3fffff
105
    shr   eax,22                 
105
    shr   eax,22                 
106
    mov   esi,eax         ;calculate number of entries in page directory
106
    mov   esi,eax         ;calculate number of entries in page directory
107
    sub   esi,4                  ;subtract entries for first 16Mb.
107
    sub   esi,4                  ;subtract entries for first 16Mb.
108
    mov   ebp,0x1000000+7        ;start physical address with flags
108
    mov   ebp,0x1000000+7        ;start physical address with flags
109
    
109
    
110
;mapping memory higher than 16Mb    
110
;mapping memory higher than 16Mb    
111
.loop4:
111
.loop4:
112
;esi (counter) - number of entries in page directory
112
;esi (counter) - number of entries in page directory
113
;edi - address of entry
113
;edi - address of entry
114
    test  esi,esi
114
    test  esi,esi
115
    jle   .loop4end
115
    jle   .loop4end
116
    call  MEM_Alloc_Page         ;alloc page table for entry in page directory
116
    call  MEM_Alloc_Page         ;alloc page table for entry in page directory
117
    mov   [edi],eax
117
    mov   [edi],eax
118
    add   dword [edi],7          ;write physical address of page table in page directory
118
    add   dword [edi],7          ;write physical address of page table in page directory
119
    add   edi,4                  ;move entry pointer
119
    add   edi,4                  ;move entry pointer
120
    call  MEM_Get_Linear_Address
120
    call  MEM_Get_Linear_Address
121
    mov   ecx,eax
121
    mov   ecx,eax
122
    xor   edx,edx
122
    xor   edx,edx
123
    
123
    
124
.loop5:
124
.loop5:
125
;ecx - linear address of page table
125
;ecx - linear address of page table
126
;edx - index of page in page table
126
;edx - index of page in page table
127
;ebp - current mapped physical address with flags
127
;ebp - current mapped physical address with flags
128
    mov   [ecx+4*edx],ebp        ;write address of page in page table
128
    mov   [ecx+4*edx],ebp        ;write address of page in page table
129
    add   ebp,0x1000             ;move to next page
129
    add   ebp,0x1000             ;move to next page
130
    inc   edx
130
    inc   edx
131
    cmp   edx,4096/4
131
    cmp   edx,4096/4
132
    jl    .loop5
132
    jl    .loop5
133
    
133
    
134
    dec   esi
134
    dec   esi
135
    jmp   .loop4
135
    jmp   .loop4
136
.loop4end:    
136
.loop4end:    
137
   
137
   
138
.set_cr3:
138
.set_cr3:
139
;set value of cr3 register to the address of page directory
139
;set value of cr3 register to the address of page directory
140
    mov   eax,[general_page_table]
140
    mov   eax,[general_page_table]
141
    add   eax,8+16               ;add flags
141
    add   eax,8+16               ;add flags
142
    mov   cr3,eax                ;now we have full access paging
142
    mov   cr3,eax                ;now we have full access paging
143
    
143
    
144
    popad
144
    popad
145
    ret
145
    ret
146
;-----------------------------------------------------------------------------
146
;-----------------------------------------------------------------------------
147
simple_clone_cr3_table:
147
simple_clone_cr3_table:
148
;Parameters:
148
;Parameters:
149
;  eax - physical address of cr3 table (page directory)
149
;  eax - physical address of cr3 table (page directory)
150
;result:
150
;result:
151
;  eax - physical address of clone of cr3 table.
151
;  eax - physical address of clone of cr3 table.
152
;Function copy only page directory.
152
;Function copy only page directory.
153
    push  ecx
153
    push  ecx
154
    push  edx
154
    push  edx
155
    push  esi
155
    push  esi
156
    push  edi
156
    push  edi
157
    call  MEM_Get_Linear_Address
157
    call  MEM_Get_Linear_Address
158
;eax - linear address of cr3 table    
158
;eax - linear address of cr3 table    
159
    mov   esi,eax                
159
    mov   esi,eax                
160
    call  MEM_Alloc_Page
160
    call  MEM_Alloc_Page
161
    test  eax,eax
161
    test  eax,eax
162
    jz    .failed
162
    jz    .failed
163
;eax - physical address of new page diretory
163
;eax - physical address of new page diretory
164
    mov   edx,eax                
164
    mov   edx,eax                
165
    call  MEM_Get_Linear_Address    
165
    call  MEM_Get_Linear_Address    
166
    mov   edi,eax
166
    mov   edi,eax
167
    mov   ecx,4096/4
167
    mov   ecx,4096/4
168
    cld
168
    cld
169
;esi - address of old page directory
169
;esi - address of old page directory
170
;edi - address of new page directory     
170
;edi - address of new page directory     
171
    rep   movsd                  ;copy page directory
171
    rep   movsd                  ;copy page directory
172
    mov   eax,edx
172
    mov   eax,edx
173
.failed:                    
173
.failed:                    
174
    pop   edi
174
    pop   edi
175
    pop   esi
175
    pop   esi
176
    pop   edx
176
    pop   edx
177
    pop   ecx
177
    pop   ecx
178
    ret
178
    ret
179
        
179
        
180
;-----------------------------------------------------------------------------    
180
;-----------------------------------------------------------------------------    
181
create_app_cr3_table:
181
create_app_cr3_table:
182
;Parameters:
182
;Parameters:
183
;  eax - slot of process (index in 0x3000 table)
183
;  eax - slot of process (index in 0x3000 table)
184
;result:
184
;result:
185
;  eax - physical address of table.
185
;  eax - physical address of table.
186
;This function create page directory for new process and
186
;This function create page directory for new process and
187
;write it physical address to offset 0xB8 of extended 
187
;write it physical address to offset 0xB8 of extended 
188
;process information.
188
;process information.
189
    push  ebx
189
    push  ebx
190
 
190
 
191
    mov   ebx,eax
191
    mov   ebx,eax
192
    mov   eax,[general_page_table]
192
    mov   eax,[general_page_table]
193
    call  simple_clone_cr3_table ;clone general page table
193
    call  simple_clone_cr3_table ;clone general page table
194
    shl   ebx,8
194
    shl   ebx,8
195
    mov   [second_base_address+0x80000+ebx+0xB8],eax ;save address of page directory
195
    mov   [second_base_address+0x80000+ebx+0xB8],eax ;save address of page directory
196
    
196
    
197
    pop   ebx
197
    pop   ebx
198
    ret
198
    ret
199
;-----------------------------------------------------------------------------
199
;-----------------------------------------------------------------------------
200
get_cr3_table:
200
get_cr3_table:
201
;Input:
201
;Input:
202
;  eax - slot of process    
202
;  eax - slot of process    
203
;result:
203
;result:
204
;  eax - physical address of page directory
204
;  eax - physical address of page directory
205
   shl    eax,8                  ;size of process extended information=256 bytes
205
   shl    eax,8                  ;size of process extended information=256 bytes
206
   mov    eax,[second_base_address+0x80000+eax+0xB8]
206
   mov    eax,[second_base_address+0x80000+eax+0xB8]
207
   ret
207
   ret
208
;-----------------------------------------------------------------------------    
208
;-----------------------------------------------------------------------------    
209
dispose_app_cr3_table:
209
dispose_app_cr3_table:
210
;Input:
210
;Input:
211
;  eax - slot of process
211
;  eax - slot of process
212
;result:
212
;result:
213
;  none
213
;  none
214
;This procedure frees page directory, 
214
;This procedure frees page directory, 
215
;page tables and all memory of process.
215
;page tables and all memory of process.
216
    pushad
216
    pushad
217
    mov   ebp,eax
217
    mov   ebp,eax
218
;ebp = process slot in the procedure.
218
;ebp = process slot in the procedure.
219
    shl   eax,8
219
    shl   eax,8
220
    mov   eax,[second_base_address+0x80000+eax+0xB8]
220
    mov   eax,[second_base_address+0x80000+eax+0xB8]
221
    mov   ebx,eax
221
    mov   ebx,eax
222
;ebx = physical address of page directory    
222
;ebx = physical address of page directory    
223
    call  MEM_Get_Linear_Address
223
    call  MEM_Get_Linear_Address
224
    mov   edi,eax
224
    mov   edi,eax
225
;edi = linear address of page directory    
225
;edi = linear address of page directory    
226
    mov   eax,[edi+(std_application_base_address shr 20)]
226
    mov   eax,[edi+(std_application_base_address shr 20)]
227
    and   eax,not (4096-1)
227
    and   eax,not (4096-1)
228
    call  MEM_Get_Linear_Address
228
    call  MEM_Get_Linear_Address
229
    mov   esi,eax
229
    mov   esi,eax
230
;esi = linear address of first page table
230
;esi = linear address of first page table
231
 
231
 
232
;search threads
232
;search threads
233
;    mov   ecx,0x200
233
;    mov   ecx,0x200
234
    xor   edx,edx
234
    xor   edx,edx
235
    mov   eax,0x2
235
    mov   eax,0x2
236
  
236
  
237
.loop:
237
.loop:
238
;eax = current slot of process  
238
;eax = current slot of process  
239
    mov   ecx,eax
239
    mov   ecx,eax
240
    shl   ecx,5
240
    shl   ecx,5
241
    cmp   byte [second_base_address+0x3000+ecx+0xa],9 ;if process running?
241
    cmp   byte [second_base_address+0x3000+ecx+0xa],9 ;if process running?
242
    jz    .next                  ;skip empty slots
242
    jz    .next                  ;skip empty slots
243
    shl   ecx,3
243
    shl   ecx,3
244
    cmp   [second_base_address+0x80000+ecx+0xB8],ebx  ;compare page directory addresses
244
    cmp   [second_base_address+0x80000+ecx+0xB8],ebx  ;compare page directory addresses
245
    jnz   .next
245
    jnz   .next
246
    inc   edx                    ;thread found
246
    inc   edx                    ;thread found
247
.next:
247
.next:
248
    inc   eax
248
    inc   eax
249
    cmp   eax,[0x3004]           ;exit loop if we look through all processes
249
    cmp   eax,[0x3004]           ;exit loop if we look through all processes
250
    jle   .loop
250
    jle   .loop
251
            
251
            
252
;edx = number of threads
252
;edx = number of threads
253
;our process is zombi so it isn't counted
253
;our process is zombi so it isn't counted
254
    test  edx,edx
254
    cmp   edx,1
255
    jnz   .threadsexists
255
    jg    .threadsexists
256
;if there isn't threads then clear memory.
256
;if there isn't threads then clear memory.
257
    add   edi,std_application_base_address shr 20
257
    add   edi,std_application_base_address shr 20
258
    
258
    
259
.loop1:    
259
.loop1:    
260
;edi = linear address of current directory entry
260
;edi = linear address of current directory entry
261
;esi = linear address of current page table
261
;esi = linear address of current page table
262
    test  esi,esi
262
    test  esi,esi
263
    jz    .loop1end
263
    jz    .loop1end
264
    xor   ecx,ecx
264
    xor   ecx,ecx
265
    
265
    
266
.loop2:
266
.loop2:
267
;ecx = index of page
267
;ecx = index of page
268
    mov   eax,[esi+4*ecx]
268
    mov   eax,[esi+4*ecx]
269
    test  eax,eax
269
    test  eax,eax
270
    jz    .loopend               ;skip empty entries
270
    jz    .loopend               ;skip empty entries
271
    and   eax,not (4096-1)       ;clear flags
271
    and   eax,not (4096-1)       ;clear flags
272
    push  ecx
272
    push  ecx
273
    call  MEM_Free_Page          ;free page
273
    call  MEM_Free_Page          ;free page
274
    pop   ecx
274
    pop   ecx
275
.loopend:    
275
.loopend:    
276
    inc   ecx
276
    inc   ecx
277
    cmp   ecx,1024               ;there are 1024 pages in page table
277
    cmp   ecx,1024               ;there are 1024 pages in page table
278
    jl    .loop2
278
    jl    .loop2
279
    
279
    
280
    mov   eax,esi
280
    mov   eax,esi
281
    call  MEM_Free_Page_Linear   ;free page table
281
    call  MEM_Free_Page_Linear   ;free page table
282
.loop1end:    
282
.loop1end:    
283
    add   edi,4                  ;move to next directory entry
283
    add   edi,4                  ;move to next directory entry
284
    mov   eax,[edi]
284
    mov   eax,[edi]
285
    and   eax,not (4096-1)
285
    and   eax,not (4096-1)
286
    call  MEM_Get_Linear_Address
286
    call  MEM_Get_Linear_Address
287
    mov   esi,eax                ;calculate linear address of new page table
287
    mov   esi,eax                ;calculate linear address of new page table
288
    test  edi,0x800
288
    test  edi,0x800
289
    jz    .loop1                 ;test if we at 0x80000000 address?
289
    jz    .loop1                 ;test if we at 0x80000000 address?
290
    
290
    
291
    and   edi,not (4096-1)       ;clear offset of page directory entry
291
    and   edi,not (4096-1)       ;clear offset of page directory entry
292
    mov   eax,edi
292
    mov   eax,edi
293
    call  MEM_Free_Page_Linear   ;free page directory 
293
    call  MEM_Free_Page_Linear   ;free page directory 
294
    popad
294
    popad
295
    ret
295
    ret
296
    
296
    
297
.threadsexists:                  ;do nothing   
297
.threadsexists:                  ;do nothing   
298
    popad                        ;last thread will free memory
298
    popad                        ;last thread will free memory
299
    ret    
299
    ret    
300
;-----------------------------------------------------------------------------
300
;-----------------------------------------------------------------------------
301
mem_alloc_specified_region:
301
mem_alloc_specified_region:
302
;eax - linear directory address
302
;eax - linear directory address
303
;ebx - start address (aligned to 4096 bytes)
303
;ebx - start address (aligned to 4096 bytes)
304
;ecx - size in pages
304
;ecx - size in pages
305
;result:
305
;result:
306
; eax=1 - ok
306
; eax=1 - ok
307
; eax=0 - failed
307
; eax=0 - failed
308
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
308
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
309
    pushad
309
    pushad
310
    mov   ebp,ebx                ;save start address for recoil
310
    mov   ebp,ebx                ;save start address for recoil
311
    mov   esi,eax
311
    mov   esi,eax
312
.gen_loop:    
312
.gen_loop:    
313
;esi = linear directory address
313
;esi = linear directory address
314
;ebx = current address
314
;ebx = current address
315
;ecx = remaining size in pages
315
;ecx = remaining size in pages
316
    mov   edx,ebx
316
    mov   edx,ebx
317
    shr   edx,22
317
    shr   edx,22
318
    mov   edi,[esi+4*edx]        ;find directory entry for current address
318
    mov   edi,[esi+4*edx]        ;find directory entry for current address
319
    test  edi,edi
319
    test  edi,edi
320
    jnz   .table_exists          ;check if page table allocated
320
    jnz   .table_exists          ;check if page table allocated
321
    call  MEM_Alloc_Page         ;alloc page table
321
    call  MEM_Alloc_Page         ;alloc page table
322
    test  eax,eax
322
    test  eax,eax
323
    jz    .failed
323
    jz    .failed
324
    mov   [esi+4*edx],eax
324
    mov   [esi+4*edx],eax
325
    add   dword [esi+4*edx],7    ;write it address with flags
325
    add   dword [esi+4*edx],7    ;write it address with flags
326
    call  MEM_Get_Linear_Address
326
    call  MEM_Get_Linear_Address
327
    call  mem_fill_page          ;clear page table
327
    call  mem_fill_page          ;clear page table
328
    jmp   .table_linear        
328
    jmp   .table_linear        
329
.table_exists:
329
.table_exists:
330
;calculate linear address of page table
330
;calculate linear address of page table
331
    mov   eax,edi
331
    mov   eax,edi
332
    and   eax,not (4096-1)       ;clear flags
332
    and   eax,not (4096-1)       ;clear flags
333
    call  MEM_Get_Linear_Address
333
    call  MEM_Get_Linear_Address
334
.table_linear:
334
.table_linear:
335
;eax = linear address of page table
335
;eax = linear address of page table
336
    mov   edx,ebx
336
    mov   edx,ebx
337
    shr   edx,12
337
    shr   edx,12
338
    and   edx,(1024-1)           ;calculate index in page table
338
    and   edx,(1024-1)           ;calculate index in page table
339
    mov   edi,eax
339
    mov   edi,eax
340
    
340
    
341
.loop:
341
.loop:
342
;edi = linear address of page table
342
;edi = linear address of page table
343
;edx = current page table index
343
;edx = current page table index
344
;ecx = remaining size in pages
344
;ecx = remaining size in pages
345
;ebx = current address
345
;ebx = current address
346
    test  ecx,ecx
346
    test  ecx,ecx
347
    jle   .endloop1              ;all requested pages allocated
347
    jle   .endloop1              ;all requested pages allocated
348
    
348
    
349
    call  MEM_Alloc_Page         ;alloc new page
349
    call  MEM_Alloc_Page         ;alloc new page
350
    test  eax,eax
350
    test  eax,eax
351
    jz    .failed
351
    jz    .failed
352
    mov   [edi+4*edx],eax
352
    mov   [edi+4*edx],eax
353
    add   dword [edi+4*edx],7    ;write it address with flags
353
    add   dword [edi+4*edx],7    ;write it address with flags
354
    call  MEM_Get_Linear_Address
354
    call  MEM_Get_Linear_Address
355
    call  mem_fill_page          ;clear new page
355
    call  mem_fill_page          ;clear new page
356
;go to next page table entry    
356
;go to next page table entry    
357
    dec   ecx
357
    dec   ecx
358
    add   ebx,4096
358
    add   ebx,4096
359
    inc   edx
359
    inc   edx
360
    test  edx,(1024-1)
360
    test  edx,(1024-1)
361
    jnz   .loop
361
    jnz   .loop
362
    
362
    
363
    jmp   .gen_loop
363
    jmp   .gen_loop
364
     
364
     
365
.endloop1:                          
365
.endloop1:                          
366
    popad
366
    popad
367
    mov   eax,1                  ;ok
367
    mov   eax,1                  ;ok
368
    ret
368
    ret
369
    
369
    
370
.failed:
370
.failed:
371
;calculate data for recoil
371
;calculate data for recoil
372
    sub   ebx,ebp
372
    sub   ebx,ebp
373
    shr   ebx,12
373
    shr   ebx,12
374
    mov   ecx,ebx                ;calculate number of allocated pages
374
    mov   ecx,ebx                ;calculate number of allocated pages
375
    mov   eax,esi                ;restore linear address of page directory
375
    mov   eax,esi                ;restore linear address of page directory
376
    mov   ebx,ebp                ;restore initial address
376
    mov   ebx,ebp                ;restore initial address
377
    call  mem_free_specified_region ;free all allocated pages
377
    call  mem_free_specified_region ;free all allocated pages
378
    popad
378
    popad
379
    xor   eax,eax                ;fail
379
    xor   eax,eax                ;fail
380
    ret
380
    ret
381
;-----------------------------------------------------------------------------    
381
;-----------------------------------------------------------------------------    
382
mem_fill_page:
382
mem_fill_page:
383
;Input:
383
;Input:
384
;  eax - address
384
;  eax - address
385
;result:
385
;result:
386
;  none
386
;  none
387
;set to zero 4096 bytes at eax address.
387
;set to zero 4096 bytes at eax address.
388
    push  ecx
388
    push  ecx
389
    push  edi
389
    push  edi
390
    mov   edi,eax
390
    mov   edi,eax
391
    mov   ecx,4096/4
391
    mov   ecx,4096/4
392
    xor   eax,eax
392
    xor   eax,eax
393
    rep   stosd
393
    rep   stosd
394
    lea   eax,[edi-4096]
394
    lea   eax,[edi-4096]
395
    pop   edi
395
    pop   edi
396
    pop   ecx
396
    pop   ecx
397
    ret
397
    ret
398
;-----------------------------------------------------------------------------    
398
;-----------------------------------------------------------------------------    
399
mem_free_specified_region:
399
mem_free_specified_region:
400
;eax - linear page directory address
400
;eax - linear page directory address
401
;ebx - start address (aligned to 4096 bytes)
401
;ebx - start address (aligned to 4096 bytes)
402
;ecx - size in pages
402
;ecx - size in pages
403
;result - none
403
;result - none
404
;Free pages in [ebx;ebx+4096*ecx) region.
404
;Free pages in [ebx;ebx+4096*ecx) region.
405
    pushad
405
    pushad
406
    mov   esi,eax
406
    mov   esi,eax
407
    xor   ebp,ebp
407
    xor   ebp,ebp
408
    
408
    
409
.gen_loop:    
409
.gen_loop:    
410
;esi = linear page directory address
410
;esi = linear page directory address
411
;ebx = current address
411
;ebx = current address
412
;ecx = remaining pages
412
;ecx = remaining pages
413
;ebp = 0 for first page table
413
;ebp = 0 for first page table
414
;      1 otherwise
414
;      1 otherwise
415
    mov   edx,ebx
415
    mov   edx,ebx
416
    shr   edx,22
416
    shr   edx,22
417
    mov   eax,[esi+4*edx]        ;find directory entry for current address
417
    mov   eax,[esi+4*edx]        ;find directory entry for current address
418
    and   eax,not (4096-1)
418
    and   eax,not (4096-1)
419
    test  eax,eax
419
    test  eax,eax
420
    jnz   .table_exists          
420
    jnz   .table_exists          
421
;skip absent page tables    
421
;skip absent page tables    
422
    mov   edx,ebx
422
    mov   edx,ebx
423
    shr   edx,12
423
    shr   edx,12
424
    and   edx,(1024-1)           ;edx - index of current page
424
    and   edx,(1024-1)           ;edx - index of current page
425
    add   ebx,1 shl 22
425
    add   ebx,1 shl 22
426
    add   ecx,edx
426
    add   ecx,edx
427
    and   ebx,not ((1 shl 22)-1)
427
    and   ebx,not ((1 shl 22)-1)
428
    mov   ebp,1                  ;set flag
428
    mov   ebp,1                  ;set flag
429
    sub   ecx,1024               ;ecx=ecx-(1024-edx)
429
    sub   ecx,1024               ;ecx=ecx-(1024-edx)
430
    jg    .gen_loop
430
    jg    .gen_loop
431
    popad
431
    popad
432
    ret
432
    ret
433
.table_exists:
433
.table_exists:
434
    call  MEM_Get_Linear_Address
434
    call  MEM_Get_Linear_Address
435
;eax - linear address of table
435
;eax - linear address of table
436
    mov   edx,ebx
436
    mov   edx,ebx
437
    shr   edx,12
437
    shr   edx,12
438
    and   edx,(1024-1)           ;edx - index of current page
438
    and   edx,(1024-1)           ;edx - index of current page
439
    mov   edi,eax
439
    mov   edi,eax
440
    
440
    
441
.loop:
441
.loop:
442
;edi = linear address of page table entry
442
;edi = linear address of page table entry
443
;edx = index of page table entry
443
;edx = index of page table entry
444
;ecx = remaining pages
444
;ecx = remaining pages
445
    test  ecx,ecx
445
    test  ecx,ecx
446
    jle   .endloop1
446
    jle   .endloop1
447
    
447
    
448
    mov   eax,[edi+4*edx]
448
    mov   eax,[edi+4*edx]
449
    and   eax,not (4096-1)
449
    and   eax,not (4096-1)
450
    call  MEM_Free_Page          ;free page
450
    call  MEM_Free_Page          ;free page
451
    mov   dword [edi+4*edx],0    ;and clear page table entry
451
    mov   dword [edi+4*edx],0    ;and clear page table entry
452
    dec   ecx
452
    dec   ecx
453
    inc   edx
453
    inc   edx
454
    cmp   edx,1024
454
    cmp   edx,1024
455
    jl    .loop
455
    jl    .loop
456
    
456
    
457
    test  ebp,ebp
457
    test  ebp,ebp
458
    jz    .first_page
458
    jz    .first_page
459
    mov   eax,edi                
459
    mov   eax,edi                
460
    call  MEM_Free_Page_Linear   ;free page table
460
    call  MEM_Free_Page_Linear   ;free page table
461
    mov   edx,ebx
461
    mov   edx,ebx
462
    shr   edx,22
462
    shr   edx,22
463
    mov   dword [esi+4*edx],0    ;and clear page directory entry
463
    mov   dword [esi+4*edx],0    ;and clear page directory entry
464
.first_page:
464
.first_page:
465
    add   ebx,1 shl 22
465
    add   ebx,1 shl 22
466
    and   ebx,not ((1 shl 22)-1) ;calculate new current address
466
    and   ebx,not ((1 shl 22)-1) ;calculate new current address
467
    mov   ebp,1                  ;set flag
467
    mov   ebp,1                  ;set flag
468
    jmp   .gen_loop 
468
    jmp   .gen_loop 
469
    
469
    
470
.endloop1:   
470
.endloop1:   
471
    popad
471
    popad
472
    ret
472
    ret
473
end if
473
end if