Subversion Repositories Kolibri OS

Rev

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