Subversion Repositories Kolibri OS

Rev

Rev 2 | 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 newprocess_inc
2
newprocess_inc_fix:
3
newprocess_inc fix newprocess_inc_fix
4
include "mem.inc"
5
include "memmanag.inc"
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
;;Working with new types of processes.
8
;;Author: Khalyavin Andrey halyavin@land.ru
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
iglobal
11
    new_process_loading db 'K : New Process - loading',13,10,0
12
    new_process_running db 'K : New Process - done',13,10,0
13
    start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
14
endg
15
;-----------------------------------------------------------------------------
16
 
17
find_new_process_place:
18
;input:
19
;  none
20
;result:
21
;  eax=[new_process_place]<>0 - ok
22
;      0 - failed.
23
;This function find least empty slot.
24
;It doesn't increase [0x3004]!
25
    mov    eax,0x3000+second_base_address
26
    push   ebx
27
    mov    ebx,[0x3004]
28
    inc    ebx
29
    shl    ebx,5
30
    add    ebx,eax               ;ebx - address of process information for (last+1) slot
31
.newprocessplace:
32
;eax = address of process information for current slot
33
    cmp    eax,ebx
34
    jz     .endnewprocessplace   ;empty slot after high boundary
35
    add    eax,0x20
36
    cmp    word [eax+0xa],9      ;check process state, 9 means that process slot is empty
37
    jnz    .newprocessplace
38
.endnewprocessplace:
39
    mov    ebx,eax
40
    sub    eax,0x3000+second_base_address
41
    shr    eax,5                 ;calculate slot index
42
    cmp    eax,256
43
    jge    .failed               ;it should be <256
44
    mov    word [ebx+0xa],9      ;set process state to 9 (for slot after hight boundary)
45
    mov    [new_process_place],eax ;save process slot
46
    pop    ebx
47
    ret
48
.failed:
49
    xor    eax,eax
50
    pop    ebx
51
    ret
52
;-----------------------------------------------------------------------------
53
 
54
new_start_application_floppy:
55
;input:
56
;  eax - pointer to filename
57
;  ebx - parameters to pass
58
;result:
59
;  eax - pid of new process
60
;        or 0 if call fails.
61
    pushad
62
    mov    esi,new_process_loading
63
    call   sys_msg_board_str     ;write to debug board
64
 
65
;wait application_table_status mutex
66
.table_status:
67
    cli
68
    cmp    [application_table_status],0
69
    jz     .stf
70
    sti
71
    call   change_task
72
    jmp    .table_status
73
.stf:
74
    call   set_application_table_status
75
;we can change system tables now
76
    push   edi
77
    push   ebx
78
    push   eax
79
    call   find_new_process_place ;find empty process slot
80
    sti
81
    test   eax,eax
82
    jz     .failed
83
 
84
    mov    edi,eax
85
    shl    edi,8
86
    add    edi,0x80000
87
    mov    ecx,256/4
88
    xor    eax,eax
89
    cld
90
    rep    stosd                 ;clean extended information about process
91
 
92
;set new process name
93
    mov    eax,[esp+8]
94
.find_last_byte:
95
    cmp    byte [eax],0
96
    jz     .find_last_byte_end
97
    inc    eax
98
    jmp    .find_last_byte
99
.find_last_byte_end:
100
    sub    eax,11                ;last 11 bytes = application name
101
;    mov    eax,[esp]             ;eax - pointer to file name
102
    mov    ebx,[new_process_place]
103
    shl    ebx,8
104
    add    ebx,0x80000
105
    mov    ecx,11
106
    call   memmove
107
 
108
;read header of file
109
    mov    eax,[esp]
110
    mov    ebx,1                 ;index of first block
111
    mov    ecx,2                 ;number of blocks
112
    mov    edx,0x90000           ;temp area
113
    mov    esi,12                ;file name length
114
    mov    edi,[esp+8]
115
;    cli
116
    call   floppy_fileread       ;read file from FD
117
;    sti
118
    cmp    eax,0
119
    jne    .cleanfailed
120
;check MENUET signature
121
    cmp    [0x90000],dword 'MENU'
122
    jnz    .cleanfailed
123
    cmp    [0x90004],word 'ET'
124
    jnz    .cleanfailed
125
 
126
    call   get_app_params        ;parse header fields
127
    cmp    esi,0
128
    jz     .cleanfailed
129
 
130
    mov    eax,[new_process_place]
131
    call   create_app_cr3_table   ;create page directory for new process
132
    test   eax,eax
133
    jz     .cleanfailed_mem
134
 
135
    call   MEM_Get_Linear_Address ;calculate linear address of it
136
 
137
    mov    ebx,std_application_base_address
138
    mov    ecx,[app_mem]
139
    add    ecx,4095
140
    shr    ecx,12
141
    mov    edx,eax
142
    call   mem_alloc_specified_region ;allocate memory for application
143
    test   eax,eax
144
    jz     .cleanfailed_mem
145
 
146
    mov    eax,[edx+(std_application_base_address shr 20)]
147
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
148
    call   MEM_Get_Linear_Address
149
    mov    edx,eax
150
 
151
;read file
152
    mov    ebx,1
153
    mov    esi,12                ;length of file name
154
.loop1:
155
;edx = linear address of current page table entry
156
;ebx = index of current block in file
157
    push   edx
158
    mov    eax,[edx]
159
    and    eax,not (4096-1)
160
    call   MEM_Get_Linear_Address
161
    mov    edx,eax               ;read file block to current page
162
    mov    eax,[esp+4]           ;restore pointer to file name
163
    mov    ecx,8                 ;number of blocks read
164
    push   ebx
165
    mov    edi,[esp+16]
166
;    cli
167
    call   floppy_fileread
168
;ebx=file size
169
;    sti
170
    pop    ecx
171
    shr    ebx,9
172
    cmp    ecx,ebx
173
    jg     .endloop1             ;if end of file?
174
    mov    ebx,ecx
175
    test   eax,eax
176
    jnz    .endloop1             ;check io errors
177
    pop    edx
178
    add    ebx,8                 ;go to next page
179
    add    edx,4
180
    jmp    .loop1
181
 
182
.endloop1:
183
    add    esp,8+4                 ;pop linear address of page table entry and pointer to file name
184
    call   new_start_application_fl.add_app_parameters
185
    mov    [esp+28],eax
186
    popad
187
    ret
188
.cleanfailed_mem:
189
    mov    esi,start_not_enough_memory
190
    call   sys_msg_board_str
191
.cleanfailed:                    ;clean process name
192
    mov    edi,[new_process_place]
193
    shl    edi,8
194
    add    edi,0x80000
195
    mov    ecx,11
196
    mov    eax,' '
197
    cld
198
    rep    stosb
199
.failed:
200
    add    esp,8+4
201
    mov    [application_table_status],0
202
    popad
203
    sti
204
    mov    eax,-1
205
    ret
206
 
207
;-----------------------------------------------------------------------------
208
new_start_application_fl:
209
;input:
210
;  eax - pointer to filename
211
;  ebx - parameters to pass
212
;result:
213
;  eax - pid of new process
214
;        or 0 if call fails.
215
    pushad
216
    mov    esi,new_process_loading
217
    call   sys_msg_board_str     ;write to debug board
218
 
219
;wait application_table_status mutex
220
.table_status:
221
    cli
222
    cmp    [application_table_status],0
223
    jz     .stf
224
    sti
225
    call   change_task
226
    jmp    .table_status
227
.stf:
228
    call   set_application_table_status
229
;we can change system tables now
230
    push   ebx
231
    push   eax
232
    call   find_new_process_place ;find empty process slot
233
    sti
234
    test   eax,eax
235
    jz     .failed
236
 
237
    mov    edi,eax
238
    shl    edi,8
239
    add    edi,0x80000
240
    mov    ecx,256/4
241
    xor    eax,eax
242
    cld
243
    rep    stosd                 ;clean extended information about process
244
 
245
;set new process name
246
    mov    eax,[esp]             ;eax - pointer to file name
247
    mov    ebx,[new_process_place]
248
    shl    ebx,8
249
    add    ebx,0x80000
250
    mov    ecx,11
251
    call   memmove
252
 
253
;read header of file
254
    mov    ebx,1                 ;index of first block
255
    mov    ecx,2                 ;number of blocks
256
    mov    edx,0x90000           ;temp area
257
    mov    esi,12                ;file name length
258
    cli
259
    call   fileread              ;read file from RD
260
    sti
261
    cmp    eax,0
262
    jne    .cleanfailed
263
;check MENUET signature
264
    cmp    [0x90000],dword 'MENU'
265
    jnz    .cleanfailed
266
    cmp    [0x90004],word 'ET'
267
    jnz    .cleanfailed
268
 
269
    call   get_app_params        ;parse header fields
270
    cmp    esi,0
271
    jz     .failed
272
 
273
    mov    eax,[new_process_place]
274
    call   create_app_cr3_table   ;create page directory for new process
275
    test   eax,eax
276
    jz     .cleanfailed_mem
277
 
278
    call   MEM_Get_Linear_Address ;calculate linear address of it
279
 
280
    mov    ebx,std_application_base_address
281
    mov    ecx,[app_mem]
282
    add    ecx,4095
283
    shr    ecx,12
284
    mov    edx,eax
285
    call   mem_alloc_specified_region ;allocate memory for application
286
    test   eax,eax
287
    jz     .cleanfailed_mem
288
 
289
    mov    eax,[edx+(std_application_base_address shr 20)]
290
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
291
    call   MEM_Get_Linear_Address
292
    mov    edx,eax
293
 
294
;read file
295
    mov    ebx,1
296
    mov    esi,12                ;length of file name
297
.loop1:
298
;edx = linear address of current page table entry
299
;ebx = index of current block in file
300
    push   edx
301
    mov    eax,[edx]
302
    and    eax,not (4096-1)
303
    call   MEM_Get_Linear_Address
304
    mov    edx,eax               ;read file block to current page
305
    mov    eax,[esp+4]           ;restore pointer to file name
306
    mov    ecx,8                 ;number of blocks read
307
    push   ebx
308
    cli
309
    call   fileread
310
;ebx=file size
311
    sti
312
    pop    ecx
313
    shr    ebx,9
314
    cmp    ecx,ebx
315
    jg     .endloop1             ;if end of file?
316
    mov    ebx,ecx
317
    test   eax,eax
318
    jnz    .endloop1             ;check io errors
319
    pop    edx
320
    add    ebx,8                 ;go to next page
321
    add    edx,4
322
    jmp    .loop1
323
 
324
.endloop1:
325
    add    esp,8                 ;pop linear address of page table entry and pointer to file name
326
    call   .add_app_parameters
327
    mov    [esp+28],eax
328
    popad
329
    ret
330
 
331
.cleanfailed_mem:
332
    mov    esi,start_not_enough_memory
333
    call   sys_msg_board_str
334
.cleanfailed:                    ;clean process name
335
    mov    edi,[new_process_place]
336
    shl    edi,8
337
    add    edi,0x80000
338
    mov    ecx,11
339
    mov    eax,' '
340
    cld
341
    rep    stosb
342
.failed:
343
    add    esp,8
344
    mov    [application_table_status],0
345
    popad
346
    sti
347
    mov    eax,-1
348
    ret
349
 
350
.add_app_parameters:
351
;input:
352
;  [esp] - pointer to parameters
353
;  [esp+4]-[esp+36] pushad registers.
354
;result
355
;  eax - pid of new process
356
;        or zero if failed
357
    cli
358
    mov    ebx,[new_process_place]
359
    cmp    ebx,[0x3004]
360
    jle    .noinc
361
    inc    dword [0x3004]        ;update number of processes
362
.noinc:
363
 
364
;   mov    ebx,[new_process_place]
365
;set 0x8c field of extended information about process
366
;(size of application memory)
367
    shl    ebx,8
368
    mov    eax,[app_mem]
369
    mov    [second_base_address+0x80000+0x8c+ebx],eax
370
;set 0x10 field of information about process
371
;(application base address)
372
;    mov    ebx,[new_process_place]
373
;    shl    ebx,5
374
    shr    ebx,3
375
    mov    dword [second_base_address+0x3000+ebx+0x10],std_application_base_address
376
 
377
;add command line parameters
378
.add_command_line:
379
    mov    edx,[app_i_param]
380
    test   edx,edx
381
    jz     .no_command_line      ;application don't need parameters
382
    mov    eax,[esp+4]
383
    test   eax,eax
384
    jz     .no_command_line      ;no parameters specified
385
;calculate parameter length
386
    mov    esi,eax
387
    xor    ecx,ecx
388
.command_line_len:
389
    cmp    byte [esi],0
390
    jz     .command_line_len_end
391
    inc    esi
392
    inc    ecx
393
    cmp    ecx,256
394
    jl     .command_line_len
395
 
396
.command_line_len_end:
397
;ecx - parameter length
398
;edx - address of parameters in new process address space
399
    mov    ebx,eax               ;ebx - address of parameters in our address space
400
    mov    eax,[new_process_place]
401
    call   write_process_memory  ;copy parameters to new process address space
402
 
403
.no_command_line:
404
    mov    ebx,[new_process_place]
405
    mov    eax,ebx
406
    shl    ebx,5
407
    add    ebx,0x3000            ;ebx - pointer to information about process
408
    mov    [ebx+0xe],al          ;set window number on screen = process slot
409
 
410
    mov    [ebx],dword 1+2+4     ;set default event flags (see 40 function)
411
 
412
    inc    dword [process_number]
413
    mov    eax,[process_number]
414
    mov    [ebx+4],eax           ;set PID
415
 
416
    mov    ecx,ebx
417
    add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
418
;set draw data to full screen
419
    mov    [ecx+0],dword 0
420
    mov    [ecx+4],dword 0
421
    mov    eax,[0xfe00]
422
    mov    [ecx+8],eax
423
    mov    eax,[0xfe04]
424
    mov    [ecx+12],eax
425
;set cr3 register in TSS of application
426
    mov    ecx,[new_process_place]
427
    shl    ecx,8
428
    mov    eax,[0x800B8+ecx]
429
    add    eax,8+16              ;add flags
430
    mov    [l.cr3],eax
431
;write cr3 in TSS of System Call Handler
432
    mov    ecx,[new_process_place]
433
    shl    ecx,7
434
    mov    [0x298000+ecx+l.cr3-tss_sceleton],eax   ;write directy to TSS
435
 
436
    mov    eax,[app_start]
437
    mov    [l.eip],eax           ;set eip in TSS
438
    mov    eax,[app_esp]
439
    mov    [l.esp],eax           ;set stack in TSS
440
 
441
;gdt
442
    mov    ebx,[new_process_place]
443
    shl    ebx,3
444
    mov    ax,app_code           ;ax - selector of code segment
445
    add    ax,bx
446
    mov    [l.cs],ax
447
    mov    ax,app_data
448
    add    ax,bx                 ;ax - selector of data segment
449
    mov    [l.ss],ax
450
    mov    [l.ds],ax
451
    mov    [l.es],ax
452
    mov    [l.fs],ax
453
    mov    ax,graph_data         ;ax - selector of graphic segment
454
    mov    [l.gs],ax
455
    mov    [l.io],word 128
456
    mov    [l.eflags],dword 0x11202
457
    mov    [l.ss0],os_data
3 halyavin 458
    shl    ebx,9
459
    add    ebx,sysint_stack_data
460
    mov    [l.esp0],ebx
1 ha 461
;    mov    [l.esp1],0x56000
462
;    mov    [l.esp2],0x57000
463
 
464
;copy tss to it place
465
    mov    eax,tss_sceleton
466
    mov    ebx,[new_process_place]
467
    imul   ebx,tss_step
468
    add    ebx,tss_data          ;ebx - address of application TSS
469
    mov    ecx,120
470
    call   memmove
471
 
472
;Add IO access table - bit array of permitted ports
473
    or     eax,-1
474
    mov    edi,[new_process_place]
475
    imul   edi,tss_step
476
    add    edi,tss_data+128
477
    mov    ecx,2048
478
    cld
479
    rep    stosd                 ;full access to 2048*8=16384 ports
480
 
481
    mov    ecx,ebx               ;ecx - address of application TSS
482
    mov    edi,[new_process_place]
483
    shl    edi,3
484
;set TSS descriptor
485
    mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
486
    mov    [edi+gdts+tss0+2],cx  ;part of offset
487
    mov    eax,ecx
488
    shr    eax,16
489
    mov    [edi+gdts+tss0+4],al  ;part of offset
490
    mov    [edi+gdts+tss0+7],ah  ;part of offset
491
    mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
492
 
493
;set code and data segments
494
    mov    eax,[new_process_place]
495
    shl    eax,3
496
;set base address of code segment
497
    mov    word [eax+gdts+app_code-3+2],0
498
    mov    byte [eax+gdts+app_code-3+4],0
499
    mov    byte [eax+gdts+app_code-3+7],std_application_base_address shr 24
500
;set limit of code segment
501
;    mov    ebx,[app_mem]
502
;    add    ebx,4095
503
;    shr    ebx,12
504
    mov    ebx,(0x80000000-std_application_base_address) shr 12
505
    mov    [eax+gdts+app_code-3+0],bx
506
    mov    [eax+gdts+app_code-3+5],word 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28)
507
;set base address of data segment
508
    mov    word [eax+gdts+app_data-3+2],0
509
    mov    byte [eax+gdts+app_data-3+4],0
510
    mov    byte [eax+gdts+app_data-3+7],std_application_base_address shr 24
511
;set limit of data segment
512
    mov    [eax+gdts+app_data-3+0],bx
513
    mov    [eax+gdts+app_data-3+5],word 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28)
514
 
515
 
516
;flush keyboard and buttons queue
517
    mov    [0xf400],byte 0
518
    mov    [0xf500],byte 0
519
 
520
    mov    edi,[new_process_place]
521
    shl    edi,5
522
    add    edi,window_data
523
    mov    ebx,[new_process_place]
524
    movzx  esi,word [0xC000+ebx*2]
525
    lea    esi,[0xC400+esi*2]
526
    call   windowactivate        ;gui initialization
527
 
528
    mov    ebx,[new_process_place]
529
    shl    ebx,5
530
    mov    [0x3000+ebx+0xa],byte 0 ;set process state - running
531
 
532
    mov    esi,new_process_running
533
    call   sys_msg_board_str     ;output information about succefull startup
534
 
535
;    add    esp,4                 ;pop pointer to parameters
536
;    popad
537
    mov    eax,[process_number]  ;set result
538
    mov    [application_table_status],0 ;unlock application_table_status mutex
539
    sti
540
    ret    4
541
;-----------------------------------------------------------------------------
542
new_sys_threads:
543
;eax=1 - create thread
544
;   ebx=thread start
545
;   ecx=thread stack value
546
;result:
547
;   eax=pid
548
    pushad
549
 
550
    cmp    eax,1
551
    jnz    .ret                  ;other subfunctions
552
    mov    esi,new_process_loading
553
    call   sys_msg_board_str
554
;lock application_table_status mutex
555
.table_status:
556
    cli
557
    cmp    [application_table_status],0
558
    je     .stf
559
    sti
560
    call   change_task
561
    jmp    .table_status
562
.stf:
563
    call   set_application_table_status
564
;find free process slot
565
 
566
    call   find_new_process_place
567
    test   eax,eax
568
    jz     .failed
569
 
570
;set parameters for thread
571
    xor    eax,eax
572
    mov    [app_i_param],eax
573
    mov    [app_i_icon],eax
574
    mov    [app_start],ebx
575
    mov    [app_esp],ecx
576
 
577
    mov    esi,[0x3000]
578
    shl    esi,8
579
    add    esi,0x80000
580
    mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
581
 
582
    mov    edi,[new_process_place]
583
    shl    edi,8
584
    add    edi,0x80000
585
    mov    edx,edi               ;edx=edi - pointer to extended infomation about new thread
586
    mov    ecx,256/4
587
    rep    stosd                 ;clean extended information about new thread
588
    mov    edi,edx
589
    mov    ecx,11
590
    rep    movsb                 ;copy process name
591
    mov    eax,[ebx+0x8c]
592
    mov    [app_mem],eax         ;set memory size
593
    mov    eax,[ebx+0xb8]
594
    mov    [edx+0xb8],eax        ;copy page directory
595
;    mov    eax,[new_process_place]
596
;    mov    ebx,[0x3000]
597
;    call   addreference_app_cr3_table
598
 
599
    push   0                     ;no parameters
600
    call    new_start_application_fl.add_app_parameters ;start thread
601
    mov    [esp+28],eax
602
    popad
603
    ret
604
 
605
.failed:
606
    sti
607
    popad
608
    mov    eax,-1
609
    ret
610
.ret:
611
    popad
612
    ret
613
;-----------------------------------------------------------------------------
614
new_mem_resize:
615
;input:
616
;  ebx - new size
617
;result:
618
;  [esp+36]:=0 - normal
619
;  [esp+36]:=1 - error
620
;This function set new application memory size.
621
    mov    esi,ebx               ;save new size
622
    add    ebx,4095
623
    and    ebx,not (4096-1)      ;round up size
624
    mov    ecx,[0x3000]
625
    shl    ecx,8
626
    mov    edx,[0x8008C+ecx]
627
    add    edx,4095
628
    and    edx,not (4096-1)      ;old size
629
    mov    eax,[0x800B8+ecx]
630
    call   MEM_Get_Linear_Address
631
;eax - linear address of page directory
632
    call   MEM_Heap_Lock         ;guarantee that two threads willn't
633
                                 ;change memory size simultaneously
634
    cmp    ebx,edx
635
;    mov    esi,ebx               ;save new size
636
    jg     .expand
637
 
638
.free:
639
    sub    edx,ebx
640
    jz     .unlock               ;do nothing
641
    mov    ecx,edx
642
    shr    ecx,12
643
    add    ebx,std_application_base_address
644
    call   mem_free_specified_region  ;free unnecessary pages
645
    jmp    .unlock
646
 
647
.expand:
648
    sub    ebx,edx
649
    mov    ecx,ebx
650
    shr    ecx,12
651
    mov    ebx,edx
652
    add    ebx,std_application_base_address
653
    call   mem_alloc_specified_region ;alloc necessary pages
654
    test   eax,eax
655
    jz     .failed               ;not enough memory
656
 
657
.unlock:
658
    mov    ebx,esi
659
    mov    eax,[0x3000]
660
    shl    eax,8
661
    mov    [eax+0x8008c],ebx     ;write new memory size
662
;search threads and update
663
;application memory size infomation
664
    mov    ecx,[eax+0x800b8]
665
    mov    eax,2
666
 
667
.search_threads:
668
;eax = current slot
669
;ebx = new memory size
670
;ecx = page directory
671
    cmp    eax,[0x3004]
672
    jg     .search_threads_end
673
    mov    edx,eax
674
    shl    edx,5
675
    cmp    word [0x3000+edx+0xa],9 ;if slot empty?
676
    jz     .search_threads_next
677
    shl    edx,3
678
    cmp    [edx+0x800b8],ecx     ;if it is our thread?
679
    jnz    .search_threads_next
680
    mov    [edx+0x8008c],ebx     ;update memory size
681
.search_threads_next:
682
    inc    eax
683
    jmp    .search_threads
684
.search_threads_end:
685
 
686
    call   MEM_Heap_UnLock
687
    mov    dword [esp+36],0
688
    ret
689
 
690
.failed:
691
    call   MEM_Heap_UnLock
692
    mov    dword [esp+36],1
693
    ret
694
;-----------------------------------------------------------------------------
695
pid_to_slot:
696
;Input:
697
;  eax - pid of process
698
;Output:
699
;  eax - slot of process or 0 if process don't exists
700
;Search process by PID.
701
    push   ebx
702
    push   ecx
703
    mov    ebx,[0x3004]
704
    shl    ebx,5
705
    mov    ecx,2*32
706
 
707
.loop:
708
;ecx=offset of current process info entry
709
;ebx=maximum permitted offset
710
    cmp    byte [second_base_address+0x3000+ecx+0xa],9
711
    jz     .endloop              ;skip empty slots
712
    cmp    [second_base_address+0x3000+ecx+0x4],eax ;check PID
713
    jz     .pid_found
714
.endloop:
715
    add    ecx,32
716
    cmp    ecx,ebx
717
    jle    .loop
718
 
719
    pop    ecx
720
    pop    ebx
721
    xor    eax,eax
722
    ret
723
 
724
.pid_found:
725
    shr    ecx,5
726
    mov    eax,ecx               ;convert offset to index of slot
727
    pop    ecx
728
    pop    ebx
729
    ret
730
;-----------------------------------------------------------------------------
731
is_new_process:
732
;Input:
733
;  eax - process slot
734
;Output:
735
;  eax=1 - it is new process
736
;  eax=0 - it is old process
737
;    shl   eax,5
738
;    mov   eax,[second_base_address+0x3000+eax+0x10]
739
;    cmp   eax,std_application_base_address  ;check base address of application
740
;    jz    .new_process
741
;    xor   eax,eax
742
;    ret
743
 
744
;.new_process:
745
    mov   eax,1
746
    ret
747
;-----------------------------------------------------------------------------
748
write_process_memory:
749
;Input:
750
;  eax - process slot
751
;  ebx - buffer address
752
;  ecx - buffer size
753
;  edx - start address in other process
754
;Output:
755
;  eax - number of bytes written
756
    pushad
757
    shl  eax,8
758
    mov  eax,[0x80000+eax+0xB8]
759
    call MEM_Get_Linear_Address
760
    mov  ebp,eax
761
;ebp=linear address of page directory of other process.
762
    add  edx,std_application_base_address  ;convert to linear address
763
    test ecx,ecx
764
    jle  .ret
765
 
766
.write_loop:
767
;ebx = current buffer address
768
;ecx>0 = current size
769
;edx = current address in other process
770
;ebp = linear address of page directory
771
 
772
    call MEM_Heap_Lock           ;cli
773
    mov  esi,edx
774
    shr  esi,22
775
    mov  eax,[ebp+4*esi]         ;find page directory entry
776
    and  eax,not (4096-1)        ;clear flags
777
    test eax,eax
778
    jz   .page_not_found
779
    call MEM_Get_Linear_Address  ;calculate linear address of page table
780
    test eax,eax
781
    jz   .page_not_found
782
    mov  esi,edx
783
    shr  esi,12
784
    and  esi,1023
785
    mov  eax,[eax+4*esi]         ;find page table entry
786
    and  eax,not (4096-1)
787
    test eax,eax
788
    jz   .page_not_found
789
    call MEM_Get_Linear_Address  ;calculate linear address of page
790
    test eax,eax
791
    jz   .page_not_found
792
    mov  edi,eax
793
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
794
    call MEM_Heap_UnLock         ;sti
795
 
796
    mov  esi,edx
797
    and  esi,4095
798
    add  edi,esi                 ;add offset in page
799
;edi = linear address corresponding edx in other process
800
    sub  esi,4096
801
    neg  esi                     ;esi - number of remaining bytes in page
802
    cmp  esi,ecx
803
    jl   .min_ecx
804
    mov  esi,ecx
805
.min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
806
    sub  ecx,esi
807
    push ecx
808
    mov  ecx,esi                 ;ecx - number of bytes to write
809
    mov  esi,ebx                 ;esi - source, edi - destination
810
    add  edx,ecx                 ;move pointer in address space of other process
811
    push edi
812
 
813
;move ecx bytes
814
    test ecx,3
815
    jnz  .not_aligned
816
    shr  ecx,2
817
    rep  movsd
818
    jmp  .next_iter
819
.not_aligned:
820
    rep  movsb
821
.next_iter:
822
 
823
    pop  eax
824
    and  eax,not (4096-1)        ;eax - linear address of current page
825
    call MEM_Free_Page_Linear    ;free reference
826
    mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
827
    pop  ecx                     ;restore number of remaining bytes
828
    test ecx,ecx
829
    jnz  .write_loop
830
.ret:
831
    popad
832
    mov  eax,ecx
833
    ret
834
 
835
.page_not_found:
836
    call MEM_Heap_UnLock         ;error has appeared in critical region
837
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
838
    neg  ecx                     ;ecx=number_of_written_bytes
839
    mov  [esp+28],ecx            ;[esp+28]<-->eax
840
    popad
841
    ret
842
;-----------------------------------------------------------------------------
843
syscall_test:
844
;for testing memory manager from applications.
845
    mov  edx,ecx
846
    mov  ecx,ebx
847
    call trans_address
848
    mov  ebx,eax
849
    mov  eax,[0x3000]
850
    call read_process_memory
851
    ret
852
;-----------------------------------------------------------------------------
853
read_process_memory:
854
;Input:
855
;  eax - process slot
856
;  ebx - buffer address
857
;  ecx - buffer size
858
;  edx - start address in other process
859
;Output:
860
;  eax - number of bytes read.
861
    pushad
862
    shl  eax,8
863
    mov  eax,[0x80000+eax+0xB8]
864
    call MEM_Get_Linear_Address
865
    mov  ebp,eax
866
    add  edx,std_application_base_address
867
.read_loop:
868
;ebx = current buffer address
869
;ecx>0 = current size
870
;edx = current address in other process
871
;ebp = linear address of page directory
872
 
873
    call MEM_Heap_Lock           ;cli
874
    mov  esi,edx
875
    shr  esi,22
876
    mov  eax,[ebp+4*esi]         ;find page directory entry
877
    and  eax,not (4096-1)
878
    test eax,eax
879
    jz   .page_not_found
880
    call MEM_Get_Linear_Address
881
    test eax,eax
882
    jz   .page_not_found
883
    mov  esi,edx
884
    shr  esi,12
885
    and  esi,1023
886
    mov  eax,[eax+4*esi]         ;find page table entry
887
    and  eax,not (4096-1)
888
    test eax,eax
889
    jz   .page_not_found
890
    call MEM_Get_Linear_Address  ;calculate linear address of page
891
    test eax,eax
892
    jz   .page_not_found
893
    mov  esi,eax
894
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
895
    call MEM_Heap_UnLock         ;sti
896
 
897
    mov  edi,edx
898
    and  edi,4095
899
    add  esi,edi                 ;add offset in page
900
;esi = linear address corresponding edx in other process
901
    sub  edi,4096
902
    neg  edi
903
 
904
;edi=min(edi,ecx) - number of bytes to copy
905
    cmp  edi,ecx
906
    jl   .min_ecx
907
    mov  edi,ecx
908
.min_ecx:
909
 
910
    sub  ecx,edi                 ;update size of remaining bytes
911
    add  edx,edi                 ;update current pointer in other address space.
912
    push ecx
913
    mov  ecx,edi                 ;ecx - number of bytes to read
914
    mov  edi,ebx                 ;esi - source, edi - destination
915
    push esi
916
;move ecx bytes
917
    test ecx,3
918
    jnz  .not_aligned
919
    shr  ecx,2
920
    rep  movsd
921
    jmp  .next_iter
922
.not_aligned:
923
    rep  movsb
924
.next_iter:
925
    pop  eax
926
    and  eax,not (4096-1)        ;eax - linear address of current page
927
    call MEM_Free_Page_Linear    ;free reference
928
    mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
929
    pop  ecx                     ;restore number of remaining bytes
930
    test ecx,ecx
931
    jnz  .read_loop
932
 
933
    popad
934
    mov  eax,ecx
935
    ret
936
 
937
.page_not_found:
938
    call MEM_Heap_UnLock         ;error has appeared in critical region
939
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
940
    neg  ecx                     ;ecx=number_of_read_bytes
941
    mov  [esp+28],ecx            ;[esp+28]<-->eax
942
    popad
943
    ret
944
;-----------------------------------------------------------------------------
945
check_region:
946
;input:
947
;  ebx - start of buffer
948
;  ecx - size of buffer
949
;result:
950
;  eax = 1 region lays in app memory
951
;  eax = 0 region don't lays in app memory
952
    mov  eax,[0x3000]
953
    jmp  check_process_region
954
;-----------------------------------------------------------------------------
955
check_process_region:
956
;input:
957
;  eax - slot
958
;  ebx - start of buffer
959
;  ecx - size of buffer
960
;result:
961
;  eax = 1 region lays in app memory
962
;  eax = 0 region don't lays in app memory
963
    test ecx,ecx
964
    jle  .ok
965
    shl  eax,5
966
    cmp  word [0x3000+eax+0xa],0
967
    jnz  .failed
968
    shl  eax,3
969
    mov  eax,[0x80000+eax+0xb8]
970
    test eax,eax
971
    jz   .failed
972
    call MEM_Get_Linear_Address
973
    push ebx
974
    push ecx
975
    push edx
976
    mov  edx,ebx
977
    and  edx,not (4096-1)
978
    sub  ebx,edx
979
    add  ecx,ebx
980
    mov  ebx,edx
981
    add  ecx,(4096-1)
982
    and  ecx,not (4096-1)
983
.loop:
984
;eax - linear address of page directory
985
;ebx - current page
986
;ecx - current size
987
    mov  edx,ebx
988
    shr  edx,22
989
    mov  edx,[eax+4*edx]
990
    and  edx,not (4096-1)
991
    test edx,edx
992
    jz   .failed1
993
    push eax
994
    mov  eax,edx
995
    call MEM_Get_Linear_Address
996
    mov  edx,ebx
997
    shr  edx,12
998
    and  edx,(1024-1)
999
    mov  eax,[eax+4*edx]
1000
    and  eax,not (4096-1)
1001
    test eax,eax
1002
    pop  eax
1003
    jz   .failed1
1004
    add  ebx,4096
1005
    sub  ecx,4096
1006
    jg   .loop
1007
    pop  edx
1008
    pop  ecx
1009
    pop  ebx
1010
.ok:
1011
    mov  eax,1
1012
    ret
1013
 
1014
.failed1:
1015
    pop  edx
1016
    pop  ecx
1017
    pop  ebx
1018
.failed:
1019
    xor  eax,eax
1020
    ret
1021
;-----------------------------------------------------------------------------
1022
new_sys_ipc:
1023
;input:
1024
;  eax=1 - set ipc buffer area
1025
;    ebx=address of buffer
1026
;    ecx=size of buffer
1027
;  eax=2 - send message
1028
;    ebx=PID
1029
;    ecx=address of message
1030
;    edx=size of message
1031
    cmp  eax,1
1032
    jnz  .no_ipc_def
1033
;set ipc buffer area
1034
    mov  edi,[0x3000]
1035
    shl  edi,8
1036
    add  edi,0x80000
1037
    cli
1038
    mov  [edi+0xA0],ebx          ;set fields in extended information area
1039
    mov  [edi+0xA4],ecx
1040
    sti
1041
    mov  [esp+36],dword 0        ;success
1042
    ret
1043
 
1044
.no_ipc_def:
1045
    cmp  eax,2
1046
    jnz  .no_ipc_send
1047
;send message
1048
    cli
1049
;obtain slot from PID
1050
    mov  eax,ebx
1051
    call pid_to_slot
1052
    test eax,eax
1053
    jz   .no_pid
1054
    mov  ebp,eax
1055
;ebp = slot of other process
1056
    shl  eax,8
1057
    mov  edi,[eax+0x80000+0xa0]  ;is ipc area defined?
1058
    test edi,edi
1059
    jz   .no_ipc_area
1060
    mov  esi,[eax+0x80000+0xa4]  ;esi - size of buffer
1061
    push dword -1                ;temp variable for read_process_memory
1062
    mov  ebx,esp
1063
    push ecx
1064
    push edx
1065
    mov  ecx,4                   ;read 4 bytes
1066
    mov  eax,ebp
1067
    mov  edx,edi                 ;from beginning of buffer.
1068
    call read_process_memory
1069
    mov  eax,[esp+8]
1070
    test eax,eax
1071
    jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
1072
    add  edx,4                   ;move to next 4 bytes
1073
    mov  eax,ebp
1074
    call read_process_memory     ;read size of occupied space in buffer
1075
    sub  esi,8
1076
    sub  esi,[esp]
1077
    sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
1078
    js   .buffer_overflow        ;esi<0 - not enough memory in buffer
1079
    mov  esi,[esp+8]             ;previous offset
1080
    add  dword [esp+8],8
1081
    mov  edi,[esp]
1082
    add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
1083
    mov  eax,ebp
1084
    call write_process_memory
1085
    add  edx,esi
1086
    sub  edx,4                   ;move to beginning of place for our message
1087
    mov  eax,[second_base_address+0x3010]
1088
    mov  eax,[eax+0x4]           ;eax - our PID
1089
    mov  [esp+8],eax
1090
    mov  eax,ebp
1091
    call write_process_memory    ;write PID
1092
    mov  ebx,esp                 ;address of size of message
1093
    mov  eax,ebp
1094
    add  edx,4
1095
    call write_process_memory    ;write size of message
1096
    add  edx,4
1097
    pop  ecx                     ;ecx - size of message
1098
    pop  eax
1099
    call trans_address
1100
    mov  ebx,eax                 ;ebx - linear address of message
1101
    add  esp,4                   ;pop temporary variable
1102
    mov  eax,ebp
1103
    call write_process_memory    ;write message
1104
    sti
1105
;awake other process
1106
    shl  ebp,8
1107
    mov  eax,ebp
1108
    or   [eax+0x800A8],dword 0x40
1109
 
1110
    cmp  dword [check_idle_semaphore],20
1111
    jge  .ipc_no_cis
1112
    mov  dword [check_idle_semaphore],5
1113
.ipc_no_cis:
1114
    mov  dword [esp+36],0
1115
    ret
1116
.no_ipc_send:
1117
    mov  dword [esp+36],-1
1118
    ret
1119
.no_pid:
1120
    sti
1121
    mov  dword [esp+36],4
1122
    ret
1123
.no_ipc_area:
1124
    sti
1125
    mov  dword [esp+36],1
1126
    ret
1127
.ipc_blocked:
1128
    sti
1129
    add  esp,12
1130
    mov  dword [esp+36],2
1131
    ret
1132
.buffer_overflow:
1133
    sti
1134
    add  esp,12
1135
    mov  dword [esp+36],3
1136
    ret
1137
;-----------------------------------------------------------------------------
1138
trans_address:
1139
;Input
1140
;  eax - application address
1141
;Output
1142
;  eax - linear address for kernel
1143
    add   eax,std_application_base_address
1144
    ret
1145
;-----------------------------------------------------------------------------
1146
new_start_application_hd:
1147
;eax - file name (kernel address)
1148
;ebx - file name length
1149
;ecx - work area (kernel address)
1150
;ebp - parameters
1151
    pushad
1152
 
1153
    mov    esi,new_process_loading
1154
    call   sys_msg_board_str     ;write message to message board
1155
 
1156
;lock application_table_status mutex
1157
.table_status:
1158
    cli
1159
    cmp    [application_table_status],0
1160
    jz     .stf
1161
    sti
1162
    call   change_task
1163
    jmp    .table_status
1164
.stf:
1165
    call   set_application_table_status
1166
 
1167
    push   ebp
1168
    push   ebx
1169
    push   eax
1170
    push   ecx
1171
    call   find_new_process_place ;find new process slot
1172
    sti
1173
    test   eax,eax
1174
    jz     .failed
1175
 
1176
;write application name
1177
    mov    eax,[esp+4]
1178
.find_last_byte:
1179
    cmp    byte [eax],0
1180
    jz     .find_last_byte_end
1181
    inc    eax
1182
    jmp    .find_last_byte
1183
.find_last_byte_end:
1184
    lea    esi,[eax-11]          ;last 11 bytes = application name
1185
    mov    edi,[new_process_place]
1186
    shl    edi,8
1187
    add    edi,0x80000
1188
    mov    ecx,11
1189
    cld
1190
    rep    movsb                 ;copy name to extended information about process
1191
 
1192
;read header
1193
    mov    eax,[esp+4]           ;file name
1194
    mov    esi,[esp]             ;work area
1195
    mov    ecx,1                 ;read from first block
1196
    mov    edx,1                 ;read 1 block
1197
    call   read_hd_file
1198
    test   eax,eax
1199
    jnz    .cleanfailed
1200
 
1201
    mov    esi,[esp]
1202
;check menuet signature
1203
    cmp    [esi+1024+0],dword 'MENU'  ;read_hd_file function write file to +1024 offset
1204
    jnz    .cleanfailed
1205
    cmp    [esi+1024+4],word 'ET'
1206
    jnz    .cleanfailed
1207
    add    esi,1024
1208
    mov    edi,0x90000
1209
    mov    ecx,512/4
1210
    cld
1211
    rep    movsd                 ;copy first block to 0x90000 address for get_app_params function
1212
    call   get_app_params
1213
    test   esi,esi
1214
    jz     .cleanfailed
1215
 
1216
    mov    eax,[new_process_place]
1217
    call   create_app_cr3_table  ;create page directory
1218
    test   eax,eax
1219
    jz     .cleanfailed_mem
1220
 
1221
    call   MEM_Get_Linear_Address
1222
 
1223
    mov    ebx,std_application_base_address
1224
    mov    ecx,[app_mem]
1225
    add    ecx,4096-1
1226
    shr    ecx,12
1227
    mov    edx,eax               ;edx - linear address of page directory
1228
    call   mem_alloc_specified_region ;allocate memory for application
1229
    test   eax,eax
1230
    jz     .cleanfailed_mem
1231
 
1232
    add    edx,(std_application_base_address shr 20)
1233
    mov    eax,[edx]
1234
    and    eax,not (4096-1)
1235
    call   MEM_Get_Linear_Address
1236
    push   edx                   ;save pointer to first page table
1237
    mov    edx,eax
1238
;read file
1239
    mov    ecx,1
1240
    xor    ebp,ebp
1241
.loop1:
1242
;[esp] - pointer to current page directory entry
1243
;edx - pointer to current page table
1244
;ebp - offset in page
1245
;ecx - current cluster
1246
    push   edx
1247
    mov    eax,[esp+12]          ;file name
1248
    mov    ebx,[esp+16]          ;file name length
1249
    mov    esi,[esp+8]           ;work area
1250
    mov    edx,1                 ;number of blocks to read
1251
    push   ecx
1252
    push   ebp
1253
    cli
1254
    call   read_hd_file
1255
    sti
1256
    pop    ebp
1257
    test   eax,eax
1258
    jnz    .endloop1             ;check io errors
1259
 
1260
    mov    esi,[esp+8+4]         ;work area
1261
    add    esi,1024
1262
    mov    eax,[esp+4]           ;current page table
1263
    mov    eax,[eax]
1264
    and    eax,not (4096-1)
1265
    call   MEM_Get_Linear_Address;calculate linear page address
1266
    lea    edi,[eax+ebp]         ;add page offset
1267
    mov    ecx,512/4
1268
    cld
1269
    rep    movsd                 ;copy data
1270
 
1271
    pop    ecx
1272
    inc    ecx                   ;next block
1273
    mov    eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
1274
    add    eax,512-1
1275
    shr    eax,9                 ;calculate application image size
1276
    cmp    ecx,eax
1277
    jg     .endloop11
1278
    pop    edx
1279
    add    ebp,512               ;new offset
1280
    test   ebp,4096
1281
    jz     .loop1
1282
    xor    ebp,ebp
1283
    add    edx,4                 ;go to next page
1284
    test   edx,(4096-1)
1285
    jnz    .loop1
1286
    add    dword [esp],4         ;go to next directory entry
1287
    mov    eax,[esp]
1288
    mov    eax,[eax]
1289
    and    eax,not (4096-1)
1290
    call   MEM_Get_Linear_Address
1291
    mov    edx,eax
1292
    jmp    .loop1
1293
.endloop1:
1294
    add    esp,4                 ;pop ecx
1295
.endloop11:
1296
    add    esp,4+4               ;pop edx, pop edx
1297
 
1298
;add_app_parameters
1299
    add    esp,12                ;now pointer to parameters is on the top of the stack
1300
    call   new_start_application_fl.add_app_parameters ;start process
1301
    mov    [esp+28],eax
1302
    popad
1303
    ret
1304
 
1305
.cleanfailed_mem:
1306
    mov    esi,start_not_enough_memory
1307
    call   sys_msg_board_str
1308
.cleanfailed:                    ;clean process name
1309
    mov    edi,[new_process_place]
1310
    shl    edi,8
1311
    add    edi,0x80000
1312
    mov    ecx,11
1313
    mov    eax,' '
1314
    cld
1315
    rep    stosb
1316
.failed:
1317
    add    esp,16
1318
    popad
1319
    mov    eax,-1
1320
    mov    [application_table_status],0
1321
    sti
1322
    ret
1323
end if