Subversion Repositories Kolibri OS

Rev

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

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