forked from KolibriOS/kolibrios
kolibri-acpi:update
git-svn-id: svn://kolibrios.org@4265 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
7450ef6270
commit
080b8dcdc4
@ -1006,6 +1006,9 @@ end virtual
|
||||
call ext2_create_partition
|
||||
test eax, eax
|
||||
jnz .success
|
||||
call xfs_create_partition
|
||||
test eax, eax
|
||||
jnz .success
|
||||
; 3. No file system has recognized the volume, so just allocate the PARTITION
|
||||
; structure without extra fields.
|
||||
movi eax, sizeof.PARTITION
|
||||
|
@ -512,7 +512,7 @@ disk_init_cache:
|
||||
|
||||
push edi
|
||||
mov edi, [esi+DISK.SysCache.pointer]
|
||||
lea ecx, [ecx*3]
|
||||
lea ecx, [(ecx+1)*3]
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
pop edi
|
||||
@ -527,7 +527,7 @@ disk_init_cache:
|
||||
|
||||
push edi
|
||||
mov edi, [esi+DISK.AppCache.pointer]
|
||||
lea ecx, [ecx*3]
|
||||
lea ecx, [(ecx+1)*3]
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
pop edi
|
||||
|
@ -162,7 +162,7 @@ FDCDataInput:
|
||||
mov [FDC_Status], FDC_Normal
|
||||
; Проверить готовность контроллера к передаче данных
|
||||
mov DX, 3F4h ;(порт состояния FDC)
|
||||
xor CX, CX ;установить счетчик тайм-аута
|
||||
mov ecx, 0x10000 ;установить счетчик тайм-аута
|
||||
@@TestRS_1:
|
||||
in AL, DX ;прочитать регистр RS
|
||||
and AL, 0C0h ;выдлить разряды 6 и 7
|
||||
@ -197,8 +197,6 @@ WaitFDCInterrupt:
|
||||
pusha
|
||||
; Сбросить байт состояния операции
|
||||
mov [FDC_Status], FDC_Normal
|
||||
; Сбросить флаг прерывани
|
||||
mov [FDD_IntFlag], 0
|
||||
; Обнулить счетчик тиков
|
||||
mov eax, [timer_ticks]
|
||||
mov [TickCounter], eax
|
||||
@ -372,6 +370,8 @@ RecalibrateFDD:
|
||||
SeekTrack:
|
||||
pusha
|
||||
call save_timer_fdd_motor
|
||||
; Сбросить флаг прерывания
|
||||
mov [FDD_IntFlag], 0
|
||||
; Подать команду "Поиск"
|
||||
mov AL, 0Fh
|
||||
call FDCDataOutput
|
||||
@ -431,6 +431,8 @@ SeekTrack:
|
||||
ReadSector:
|
||||
pushad
|
||||
call save_timer_fdd_motor
|
||||
; Сбросить флаг прерывания
|
||||
mov [FDD_IntFlag], 0
|
||||
; Установить скорость передачи 500 Кбайт/с
|
||||
mov AX, 0
|
||||
mov DX, 03F7h
|
||||
@ -531,6 +533,8 @@ ReadSectWithRetr:
|
||||
WriteSector:
|
||||
pushad
|
||||
call save_timer_fdd_motor
|
||||
; Сбросить флаг прерывания
|
||||
mov [FDD_IntFlag], 0
|
||||
; Установить скорость передачи 500 Кбайт/с
|
||||
mov AX, 0
|
||||
mov DX, 03F7h
|
||||
|
@ -51,18 +51,20 @@ getkey: ; Use BIOS INT 16h to read a key from the keyboa
|
||||
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
|
||||
; in: bx=range
|
||||
; out: ax=digit (1..9, 10 for 0)
|
||||
mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control
|
||||
int 16h ; to the caller until a key is available in the system type ahead buffer. On return,
|
||||
cmp al, bl ; 'al' contains the ASCII code for the key read from the buffer and 'ah' contains
|
||||
jb getkey ; the keyboard scan code. Here we compare 'al' with the range of accepted characters.
|
||||
cmp al, bh ; If the key pressed is not in the range, continue waiting for another key.
|
||||
ja getkey
|
||||
mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control to the caller
|
||||
int 16h ; until a key is available in the system type ahead buffer. On return, 'al' contains the ASCII
|
||||
cmp al, 27 ; code for the key read from the buffer and 'ah' contains the keyboard scan code. (27=>ESC)
|
||||
jz @f ; If ESC is pressed, return (user doesn't want to change any value).
|
||||
cmp al, bl ; Compare 'al' (ASCII code of key pressed) with 'bl' (lowest accepted char from the range).
|
||||
jb getkey ; ASCII code is below lowest accepted value => continue waiting for another key.
|
||||
cmp al, bh ; Compare 'al' (ASCII code of key pressed) with 'bh' (highest accepted char from the range).
|
||||
ja getkey ; ASCII code is above highest accepted value => continue waiting for another key.
|
||||
push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen.
|
||||
call putchar
|
||||
pop ax
|
||||
and ax, 0Fh ; ASCII code for '0' is 48 (110000b). 0F4=1111b. (110000b AND 1111b) = 0
|
||||
jnz @f ; So if key '0' was entered, return 10 in 'ax'
|
||||
mov al, 10
|
||||
and ax, 0Fh ; Convert ASCII code to number: '1'->1, '2'->2, etc. 0Fh=1111b.
|
||||
jnz @f ; ASCII code for '0' is 48 (110000b). (110000b AND 1111b) = 0
|
||||
mov al, 10 ; So if key '0' was entered, return 10 in 'ax'
|
||||
@@:
|
||||
ret
|
||||
|
||||
@ -79,6 +81,18 @@ macro _setcursor row,column
|
||||
call setcursor
|
||||
}
|
||||
|
||||
macro _ask_question question,range,variable_to_set
|
||||
{
|
||||
_setcursor 16,0
|
||||
mov si, question ; Print the question
|
||||
call print
|
||||
mov bx, range ; range accepted for answer
|
||||
call getkey
|
||||
cmp al, 27 ; If ESC was pressed, do not change the value
|
||||
jz .esc_pressed
|
||||
mov [variable_to_set], al
|
||||
}
|
||||
|
||||
boot_read_floppy:
|
||||
push si
|
||||
xor si, si
|
||||
@ -433,7 +447,7 @@ sayerr:
|
||||
mov [es:BOOT_IDE_PI_16], cx
|
||||
xor si, si ; device index = 0
|
||||
int 0x1A
|
||||
jnc .found_1 ; Parallel IDE Controller
|
||||
jnc .found ; Parallel IDE Controller
|
||||
; Controller not found!
|
||||
xor ax, ax
|
||||
mov [es:BOOT_IDE_PI_16], ax
|
||||
@ -775,25 +789,26 @@ end if
|
||||
cmp al, 'e' ; select boot origin
|
||||
jnz .show_remarks
|
||||
; e) preboot_device = from where to boot?
|
||||
_setcursor 16,0
|
||||
mov si, bdev
|
||||
call print
|
||||
if defined extended_primary_loader
|
||||
mov bx, '12' ; range accepted for answer: 1-2
|
||||
_ask_question bdev,'12',preboot_device ; range accepted for answer: 1-2
|
||||
else
|
||||
mov bx, '14' ; range accepted for answer: 1-4
|
||||
_ask_question bdev,'14',preboot_device ; range accepted for answer: 1-4
|
||||
end if
|
||||
call getkey
|
||||
mov [preboot_device], al
|
||||
_setcursor 14,0
|
||||
|
||||
.d:
|
||||
if ~ defined extended_primary_loader
|
||||
mov [.bSettingsChanged], 1
|
||||
end if
|
||||
.esc_pressed:
|
||||
call clear_vmodes_table ;clear vmodes_table
|
||||
jmp .printcfg
|
||||
|
||||
.change_a:
|
||||
call clear_vmodes_table ;clear vmodes_table
|
||||
|
||||
mov si, word [cursor_pos]
|
||||
mov word [cursor_pos_old], si
|
||||
.loops:
|
||||
call draw_vmodes_table
|
||||
_setcursor 25,0 ; out of screen
|
||||
@ -803,6 +818,13 @@ end if
|
||||
|
||||
mov si, word [cursor_pos]
|
||||
|
||||
cmp al, 27 ; If ESC was pressed, do not change the value
|
||||
jnz @f ; Just exit the resolution selection box
|
||||
|
||||
mov si, word [cursor_pos_old]
|
||||
mov word [cursor_pos], si
|
||||
jmp .esc_pressed
|
||||
@@:
|
||||
cmp ah, 0x48;x,0x48E0 ; up
|
||||
jne .down
|
||||
cmp si, modes_table
|
||||
@ -873,17 +895,13 @@ end if
|
||||
jmp .d
|
||||
|
||||
.change_b: ; b) preboot_biosdisk = use BIOS disks through V86 emulation?
|
||||
_setcursor 16,0
|
||||
; _setcursor 16,0
|
||||
; mov si, ask_dma // (earlier was: preboot_dma = use DMA access?)
|
||||
; call print
|
||||
; mov bx, '13' ; range accepted for answer: 1-3
|
||||
; call getkey
|
||||
; mov [preboot_dma], al
|
||||
mov si, ask_bd
|
||||
call print
|
||||
mov bx, '12' ; range accepted for answer: 1-2
|
||||
call getkey
|
||||
mov [preboot_biosdisk], al
|
||||
_ask_question ask_bd,'12',preboot_biosdisk ; range accepted for answer: 1-2
|
||||
_setcursor 11,0
|
||||
jmp .d
|
||||
;.change_c: ; // VRR is an obsolete functionality, used only with CRT monitors
|
||||
@ -896,21 +914,11 @@ end if
|
||||
; _setcursor 12,0
|
||||
; jmp .d
|
||||
.change_c: ; c) preboot_debug = duplicates kernel debug output to the screen
|
||||
_setcursor 16,0
|
||||
mov si, ask_debug
|
||||
call print
|
||||
mov bx, '12' ; range accepted for answer: 1-2
|
||||
call getkey
|
||||
mov [preboot_debug], al
|
||||
_ask_question ask_debug,'12',preboot_debug ; range accepted for answer: 1-2
|
||||
_setcursor 12,0
|
||||
jmp .d
|
||||
.change_d: ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
|
||||
_setcursor 16,0
|
||||
mov si, ask_launcher
|
||||
call print
|
||||
mov bx, '12' ; range accepted for answer: 1-2
|
||||
call getkey
|
||||
mov [preboot_launcher], al
|
||||
_ask_question ask_launcher,'12',preboot_launcher ; range accepted for answer: 1-2
|
||||
_setcursor 13,0
|
||||
jmp .d
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -15,10 +15,10 @@ $Revision: 2455 $
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COP'
|
||||
db 'YING for details ',186
|
||||
db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COPYING for details ',186
|
||||
db 186,' If you find any bugs, please report them at: http://board.kolibrios.org ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 2
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm db " APM x.x ", 0
|
||||
novesa db "Display: EGA/CGA",13,10,0
|
||||
@ -79,7 +79,7 @@ preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db "real floppy",13,10,0
|
||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
||||
else
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
|
||||
pdm1 db "real floppy",13,10,0
|
||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3 db "use already loaded image",13,10,0
|
||||
@ -93,13 +93,14 @@ save_quest db "Remember current settings? [y/n]: ",0
|
||||
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
|
||||
end if
|
||||
|
||||
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
|
||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
||||
remark2 db "If the system does not boot, try to disable the item [b].",0
|
||||
remarks dw remark1, remark2
|
||||
num_remarks = 2
|
||||
remark2 db "If the system does not boot, try to disable option [b]. If the system gets",0
|
||||
remark3 db "stuck after booting, enable option [c], disable option [d] and make photo.",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
@ -15,91 +15,92 @@ $Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
latin1 '║ KolibriOS kaasas IGASUGUSE GARANTIITA. Naha faili COPY'
|
||||
latin1 'ING detailid ║'
|
||||
latin1 '║ KolibriOS on IGASUGUSE GARANTIITA. Vaata faili COPYING info saamiseks. Kui ║'
|
||||
latin1 '║ leiate vigu, anna neist palun teada aadressil: http://board.kolibrios.org ║'
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 2
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm: latin1 " APM x.x ", 0
|
||||
novesa: latin1 "Ekraan: EGA/CGA",13,10,0
|
||||
s_vesa: latin1 "Vesa versioon: "
|
||||
msg_apm latin1 " APM x.x ", 0
|
||||
novesa latin1 "Ekraan: EGA/CGA",13,10,0
|
||||
s_vesa latin1 "Vesa versioon: "
|
||||
.ver db "?.?",13,10,0
|
||||
|
||||
gr_mode: latin1 "Vali videomode: ",13,10,0
|
||||
gr_mode latin1 "Vali video resolutsioon: ",13,10,0
|
||||
|
||||
ask_bd: latin1 "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0
|
||||
ask_bd latin1 "Lisa V86 reziimis BIOSle nähtavad kettad? [1-jah, 2-ei]: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
|
||||
bdev latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
|
||||
else
|
||||
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
|
||||
bdev latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
|
||||
latin1 13,10,"║ "
|
||||
latin1 "3-kasuta eellaaditud mäluketast kerneli restardist;"
|
||||
latin1 13,10,"║ "
|
||||
latin1 "4-loo tühi pilt]: ",0
|
||||
end if
|
||||
|
||||
prnotfnd: latin1 "Fataalne - Videoreziimi ei leitud.",0
|
||||
prnotfnd latin1 "Fataalne - Video resolutsiooni ei leitud.",0
|
||||
|
||||
not386: latin1 "Fataalne - CPU 386+ on vajalik.",0
|
||||
fatalsel: latin1 "Fataalne - Graafilist reziimi riistvara ei toeta.",0
|
||||
pres_key: latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0
|
||||
badsect: latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0
|
||||
memmovefailed:latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
|
||||
okt: latin1 " ... OK"
|
||||
linef: latin1 13,10,0
|
||||
diskload: latin1 "Loen disketti: 00 %",8,8,8,8,0
|
||||
pros: latin1 "00"
|
||||
backspace2:latin1 8,8,0
|
||||
not386 latin1 "Fataalne - CPU 386+ on vajalik.",0
|
||||
fatalsel latin1 "Fataalne - Riistvara ei toeta graafilist resolutsiooni.",0
|
||||
pres_key latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0
|
||||
badsect latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0
|
||||
memmovefailed latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
|
||||
okt latin1 " ... OK"
|
||||
linef latin1 13,10,0
|
||||
diskload latin1 "Loen disketti: 00 %",8,8,8,8,0
|
||||
pros latin1 "00"
|
||||
backspace2 latin1 8,8,0
|
||||
boot_dev db 0 ; 0=floppy, 1=hd
|
||||
start_msg:latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
|
||||
time_msg: latin1 " või oota "
|
||||
time_str: latin1 " 5 sekundit"
|
||||
start_msg latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
|
||||
time_msg latin1 " või oota "
|
||||
time_str latin1 " 5 sekundit"
|
||||
latin1 " automaatseks jätkamiseks",13,10,0
|
||||
current_cfg_msg:latin1 "Praegused seaded:",13,10,0
|
||||
curvideo_msg:latin1 " [a] Videoreziim: ",0
|
||||
current_cfg_msg latin1 "Praegused seaded:",13,10,0
|
||||
curvideo_msg latin1 " [a] Video resolutsioon: ",0
|
||||
|
||||
mode0: latin1 "320x200, EGA/CGA 256 värvi",0
|
||||
mode9: latin1 "640x480, VGA 16 värvi",0
|
||||
mode0 latin1 "320x200, EGA/CGA 256 värvi",0
|
||||
mode9 latin1 "640x480, VGA 16 värvi",0
|
||||
|
||||
usebd_msg:latin1 " [b] Lisa kettad nahtavaks BIOS:",0
|
||||
on_msg: latin1 " sees",13,10,0
|
||||
off_msg: latin1 " väljas",13,10,0
|
||||
usebd_msg latin1 " [b] Lisa BIOSle nähtavad kettad:",0
|
||||
on_msg latin1 " sees",13,10,0
|
||||
off_msg latin1 " väljas",13,10,0
|
||||
|
||||
debug_mode_msg: latin1 " [c] Duplicate siluda väljund ekraani:",0
|
||||
ask_debug: latin1 "Duplicate siluda väljund ekraani? [1-jah, 2-no]: ",0
|
||||
debug_mode_msg latin1 " [c] Dubleeri silumisinfo ekraanile:",0
|
||||
ask_debug latin1 "Dubleeri silumisinfo ekraanile? [1-jah, 2-ei]: ",0
|
||||
|
||||
launcher_msg: latin1 " [d] Alusta LAUNCHER pärast kernel on koormatud:",0
|
||||
ask_launcher: latin1 "Alusta esimese taotluse (LAUNCHER) pärast kernel laetakse? [1-jah, 2-no]: ",0
|
||||
launcher_msg latin1 " [d] Käivita LAUNCHER pärast kerneli laadimist:",0
|
||||
ask_launcher latin1 "Käivita esimese programm (LAUNCHER) peale kerneli laadimist? [1-jah, 2-ei]: ",0
|
||||
|
||||
preboot_device_msg:latin1 " [e] Disketi kujutis: ",0
|
||||
preboot_device_msg latin1 " [e] Disketi kujutis: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1: latin1 "reaalne diskett",13,10,0
|
||||
pdm2: latin1 "kolibri.img",13,10,0
|
||||
pdm1 latin1 "reaalne diskett",13,10,0
|
||||
pdm2 latin1 "kolibri.img",13,10,0
|
||||
else
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
||||
pdm1: latin1 "reaalne diskett",13,10,0
|
||||
pdm2: latin1 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3: latin1 "kasuta juba laaditud kujutist",13,10,0
|
||||
pdm4: latin1 "loo tühi pilt",13,10,0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
|
||||
pdm1 latin1 "reaalne diskett",13,10,0
|
||||
pdm2 latin1 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3 latin1 "kasuta juba laaditud kujutist",13,10,0
|
||||
pdm4 latin1 "loo tühi pilt",13,10,0
|
||||
end if
|
||||
|
||||
loading_msg:latin1 "Laadin KolibriOS...",0
|
||||
loading_msg latin1 "Laadin KolibriOS...",0
|
||||
|
||||
if ~ defined extended_primary_loader
|
||||
save_quest:latin1 "Jäta meelde praegused seaded? [y/n]: ",0
|
||||
loader_block_error:latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
|
||||
save_quest latin1 "Jäta meelde praegused seaded? [y/n]: ",0
|
||||
loader_block_error latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
|
||||
end if
|
||||
|
||||
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
|
||||
remark1:latin1 "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0
|
||||
remark2:latin1 "Kui susteem ei kaivitu, proovige lulitada kirje [b].",0
|
||||
remarks dw remark1, remark2
|
||||
num_remarks = 2
|
||||
remark1 latin1 "Vaikimisi väärtused on kasutatavad enamikes arvutites, kuid mitte kõigis.",0
|
||||
remark2 latin1 "Kui süsteem ei käivitu, proovige lülitada kirje [b] välja. Kui see läheb",0
|
||||
remark3 latin1 "kinni pärast käivitamist, võimaldama valik [c], keelake [d] ja teha foto.",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
@ -15,10 +15,8 @@ $Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. '
|
||||
db ' ',186
|
||||
db 186,' Details stehen in der Datei COPYING '
|
||||
db ' ',186
|
||||
db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. Details stehen in der ',186
|
||||
db 186,' Datei COPYING. Bitte melden Sie Fehler bei: http://board.kolibrios.org ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
@ -81,7 +79,7 @@ preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db "Echte Diskette",13,10,0
|
||||
pdm2 db "kolibri.img",13,10,0
|
||||
else
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
|
||||
pdm1 db "Echte Diskette",13,10,0
|
||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3 db "Nutze bereits geladenes Image",13,10,0
|
||||
@ -95,13 +93,15 @@ save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
|
||||
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
|
||||
end if
|
||||
|
||||
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
|
||||
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
|
||||
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
|
||||
remark1 db "Die Standardwerte sind fur die meisten gewahlt, aber nicht fur jedermann.",0
|
||||
remark2 db "Wenn das System nicht bootet, versuchen, das Element [b] deaktivieren.",0
|
||||
remarks dw remark1, remark2
|
||||
num_remarks = 2
|
||||
remark2 db "Wenn das System nicht bootet, das Option [b] deaktivieren versuchen. Wenn es",0
|
||||
remark3 db "nach dem Booten hangen bleibt, aktivieren Sie Option [c], deaktivieren [d]",0
|
||||
remark4 db "und machen Fotos.",0
|
||||
remarks dw remark1, remark2, remark3, remark4
|
||||
num_remarks = 4
|
@ -15,89 +15,90 @@ $Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║'
|
||||
cp866 '║ Подробнее смотрите в файле COPYING.TXT ║'
|
||||
cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. Подробнее смотрите в файле ║'
|
||||
cp866 '║ COPYING.TXT. О найденных ошибках сообщайте на http://board.kolibrios.org ║'
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm: cp866 " APM x.x ", 0
|
||||
novesa: cp866 "Видеокарта: EGA/CGA",13,10,0
|
||||
s_vesa: cp866 "Версия VESA: "
|
||||
msg_apm cp866 " APM x.x ", 0
|
||||
novesa cp866 "Видеокарта: EGA/CGA",13,10,0
|
||||
s_vesa cp866 "Версия VESA: "
|
||||
.ver db "?.?",13,10,0
|
||||
|
||||
gr_mode: cp866 "Выберите видеорежим: ",13,10,0
|
||||
gr_mode cp866 "Выберите видеорежим: ",13,10,0
|
||||
|
||||
ask_bd: cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0
|
||||
ask_bd cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
bdev: cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0
|
||||
bdev cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0
|
||||
else
|
||||
bdev: cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10
|
||||
bdev cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10
|
||||
cp866 "║ 3-использовать уже загруженный образ;",13,10
|
||||
cp866 "║ 4-создать чистый образ]: ",0
|
||||
end if
|
||||
|
||||
prnotfnd: cp866 "Ошибка - Видеорежим не найден.",0
|
||||
prnotfnd cp866 "Ошибка - Видеорежим не найден.",0
|
||||
|
||||
not386: cp866 "Ошибка - Требуется процессор 386+.",0
|
||||
fatalsel: cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0
|
||||
pres_key: cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0
|
||||
badsect: cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0
|
||||
memmovefailed:cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0
|
||||
okt: cp866 " ... OK"
|
||||
linef: cp866 13,10,0
|
||||
diskload: cp866 "Загрузка дискеты: 00 %",8,8,8,8,0
|
||||
pros: cp866 "00"
|
||||
backspace2:cp866 8,8,0
|
||||
not386 cp866 "Ошибка - Требуется процессор 386+.",0
|
||||
fatalsel cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0
|
||||
pres_key cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0
|
||||
badsect cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0
|
||||
memmovefailed cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0
|
||||
okt cp866 " ... OK"
|
||||
linef cp866 13,10,0
|
||||
diskload cp866 "Загрузка дискеты: 00 %",8,8,8,8,0
|
||||
pros cp866 "00"
|
||||
backspace2 cp866 8,8,0
|
||||
boot_dev db 0
|
||||
start_msg:cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
|
||||
time_msg: cp866 " или подождите "
|
||||
time_str: cp866 " 5 секунд "
|
||||
start_msg cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
|
||||
time_msg cp866 " или подождите "
|
||||
time_str cp866 " 5 секунд "
|
||||
cp866 " до автоматического продолжения",13,10,0
|
||||
current_cfg_msg:cp866 "Текущие настройки:",13,10,0
|
||||
curvideo_msg:cp866 " [a] Видеорежим: ",0
|
||||
current_cfg_msg cp866 "Текущие настройки:",13,10,0
|
||||
curvideo_msg cp866 " [a] Видеорежим: ",0
|
||||
|
||||
mode0: cp866 "320x200, EGA/CGA 256 цветов",13,10,0
|
||||
mode9: cp866 "640x480, VGA 16 цветов",13,10,0
|
||||
mode0 cp866 "320x200, EGA/CGA 256 цветов",13,10,0
|
||||
mode9 cp866 "640x480, VGA 16 цветов",13,10,0
|
||||
|
||||
usebd_msg:cp866 " [b] Добавить диски, видимые через BIOS:",0
|
||||
on_msg: cp866 " вкл",13,10,0
|
||||
off_msg: cp866 " выкл",13,10,0
|
||||
usebd_msg cp866 " [b] Добавить диски, видимые через BIOS:",0
|
||||
on_msg cp866 " вкл",13,10,0
|
||||
off_msg cp866 " выкл",13,10,0
|
||||
|
||||
debug_mode_msg: cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0
|
||||
ask_debug: cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0
|
||||
debug_mode_msg cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0
|
||||
ask_debug cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0
|
||||
|
||||
launcher_msg: cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0
|
||||
ask_launcher: cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0
|
||||
launcher_msg cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0
|
||||
ask_launcher cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0
|
||||
|
||||
preboot_device_msg:cp866 " [e] Образ дискеты: ",0
|
||||
preboot_device_msg cp866 " [e] Образ дискеты: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1: cp866 "настоящая дискета",13,10,0
|
||||
pdm2: cp866 "kolibri.img из папки загрузки",13,10,0
|
||||
pdm1 cp866 "настоящая дискета",13,10,0
|
||||
pdm2 cp866 "kolibri.img из папки загрузки",13,10,0
|
||||
else
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4
|
||||
pdm1: cp866 "настоящая дискета",13,10,0
|
||||
pdm2: cp866 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3: cp866 "использовать уже загруженный образ",13,10,0
|
||||
pdm4: cp866 "создать чистый образ",13,10,0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
|
||||
pdm1 cp866 "настоящая дискета",13,10,0
|
||||
pdm2 cp866 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3 cp866 "использовать уже загруженный образ",13,10,0
|
||||
pdm4 cp866 "создать чистый образ",13,10,0
|
||||
end if
|
||||
|
||||
loading_msg:cp866 "Идёт загрузка KolibriOS...",0
|
||||
loading_msg cp866 "Идёт загрузка KolibriOS...",0
|
||||
|
||||
if ~ defined extended_primary_loader ; saving not supported in this case
|
||||
save_quest:cp866 "Запомнить текущие настройки? [y/n]: ",0
|
||||
loader_block_error:cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0
|
||||
save_quest cp866 "Запомнить текущие настройки? [y/n]: ",0
|
||||
loader_block_error cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0
|
||||
end if
|
||||
|
||||
_st:cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0
|
||||
_r1:cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0
|
||||
_r2:cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0
|
||||
_rs:cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0
|
||||
_bt:cp866 '║ └───────────────────────────────┴─┘ ',13,10,0
|
||||
_st cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0
|
||||
_r1 cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0
|
||||
_r2 cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0
|
||||
_rs cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0
|
||||
_bt cp866 '║ └───────────────────────────────┴─┘ ',13,10,0
|
||||
|
||||
remark1:cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех.",0
|
||||
remark2:cp866 "Если у Вас не грузится система, попробуйте отключить пункт [b].",0
|
||||
remarks dw remark1, remark2
|
||||
num_remarks = 2
|
||||
remark1 cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех. Если у",0
|
||||
remark2 cp866 "Вас не грузится система, попробуйте отключить пункт [b]. Если она зависла",0
|
||||
remark3 cp866 "после запуска, включите пункт [c], отключите пункт [d] и сделайте фото лога.",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
@ -17,93 +17,92 @@ $Revision: 2455 $
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
cp850 '║ KolibriOS y viene ABSOLUTAMENTE SIN GARANTíA. '
|
||||
cp850 ' ║'
|
||||
cp850 '║ Lee el archivo COPYING por más detalles '
|
||||
cp850 ' ║'
|
||||
cp850 '║ KolibriOS viene ABSOLUTAMENTE SIN GARANTíA. Lee el archivo COPYING por más ║'
|
||||
cp850 '║ detalles. Por favor, informar de los errores en: http://board.kolibrios.org ║'
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm: cp850 " APM x.x ", 0
|
||||
novesa: cp850 "Monitor: EGA/CGA",13,10,0
|
||||
s_vesa: cp850 "Versión de VESA: "
|
||||
msg_apm cp850 " APM x.x ", 0
|
||||
novesa cp850 "Monitor: EGA/CGA",13,10,0
|
||||
s_vesa cp850 "Versión de VESA: "
|
||||
.ver db "?.?",13,10,0
|
||||
|
||||
gr_mode: cp850 "Selecciona un modo de video: ",13,10,0
|
||||
gr_mode cp850 "Selecciona un modo de video: ",13,10,0
|
||||
|
||||
ask_bd: cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0
|
||||
ask_bd cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0
|
||||
bdev cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0
|
||||
else
|
||||
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);"
|
||||
bdev cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);"
|
||||
cp850 13,10,"║ "
|
||||
cp850 "3-usar imagen precargada en el reinicio del núcleo;"
|
||||
cp850 13,10,"║ "
|
||||
cp850 "4-crear imagen vacía]: ",0
|
||||
end if
|
||||
|
||||
prnotfnd: cp850 "Fatal - Modo de video no encontrado.",0
|
||||
prnotfnd cp850 "Fatal - Modo de video no encontrado.",0
|
||||
|
||||
not386: cp850 "Fatal - CPU 386+ requerido.",0
|
||||
fatalsel: cp850 "Fatal - Modo de gráficos no soportado por hardware.",0
|
||||
pres_key: cp850 "Presiona una tecla para seleccionar otro modo de video.",0
|
||||
badsect: cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0
|
||||
memmovefailed:cp850 13,10,"║ Fatal - Int 0x15 move failed.",0
|
||||
okt: cp850 " ... BIEN"
|
||||
linef: cp850 13,10,0
|
||||
diskload: cp850 "Cargando disquete: 00 %",8,8,8,8,0
|
||||
pros: cp850 "00"
|
||||
backspace2:cp850 8,8,0
|
||||
not386 cp850 "Fatal - CPU 386+ requerido.",0
|
||||
fatalsel cp850 "Fatal - Modo de gráficos no soportado por hardware.",0
|
||||
pres_key cp850 "Presiona una tecla para seleccionar otro modo de video.",0
|
||||
badsect cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0
|
||||
memmovefailed cp850 13,10,"║ Fatal - Int 0x15 move failed.",0
|
||||
okt cp850 " ... BIEN"
|
||||
linef cp850 13,10,0
|
||||
diskload cp850 "Cargando disquete: 00 %",8,8,8,8,0
|
||||
pros cp850 "00"
|
||||
backspace2 cp850 8,8,0
|
||||
boot_dev db 0 ; 0=floppy, 1=hd
|
||||
start_msg:cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0
|
||||
time_msg: cp850 " o espera "
|
||||
time_str: cp850 " 5 segundos"
|
||||
start_msg cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0
|
||||
time_msg cp850 " o espera "
|
||||
time_str cp850 " 5 segundos"
|
||||
cp850 " para que inicie automáticamente",13,10,0
|
||||
current_cfg_msg:cp850 "Configuración actual:",13,10,0
|
||||
curvideo_msg:cp850 " [a] Modo de video: ",0
|
||||
current_cfg_msg cp850 "Configuración actual:",13,10,0
|
||||
curvideo_msg cp850 " [a] Modo de video: ",0
|
||||
|
||||
mode0: cp850 "320x200, EGA/CGA 256 colores",13,10,0
|
||||
mode9: cp850 "640x480, VGA 16 colores",13,10,0
|
||||
mode0 cp850 "320x200, EGA/CGA 256 colores",13,10,0
|
||||
mode9 cp850 "640x480, VGA 16 colores",13,10,0
|
||||
|
||||
usebd_msg:cp850 " [b] Agregar discos visibles por el BIOS:",0
|
||||
on_msg: cp850 " activado",13,10,0
|
||||
off_msg: cp850 " desactivado",13,10,0
|
||||
usebd_msg cp850 " [b] Agregar discos visibles por el BIOS:",0
|
||||
on_msg cp850 " activado",13,10,0
|
||||
off_msg cp850 " desactivado",13,10,0
|
||||
|
||||
debug_mode_msg: cp850 " [c] Duplicar depurar salida a la pantalla:",0
|
||||
ask_debug: cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0
|
||||
debug_mode_msg cp850 " [c] Duplicar depurar salida a la pantalla:",0
|
||||
ask_debug cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0
|
||||
|
||||
launcher_msg: cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0
|
||||
ask_launcher: cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0
|
||||
launcher_msg cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0
|
||||
ask_launcher cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0
|
||||
|
||||
preboot_device_msg:cp850 " [e] Imagen de disquete: ",0
|
||||
preboot_device_msg cp850 " [e] Imagen de disquete: ",0
|
||||
|
||||
if defined extended_primary_loader
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1: cp850 "disquete real",13,10,0
|
||||
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm1 cp850 "disquete real",13,10,0
|
||||
pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0
|
||||
else
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
||||
pdm1: cp850 "disquete real",13,10,0
|
||||
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3: cp850 "usar imagen ya cargada",13,10,0
|
||||
pdm4: cp850 "crear imagen vacía",13,10,0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
|
||||
pdm1 cp850 "disquete real",13,10,0
|
||||
pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0
|
||||
pdm3 cp850 "usar imagen ya cargada",13,10,0
|
||||
pdm4 cp850 "crear imagen vacía",13,10,0
|
||||
end if
|
||||
|
||||
loading_msg:cp850 "Cargando KolibriOS...",0
|
||||
loading_msg cp850 "Cargando KolibriOS...",0
|
||||
|
||||
if ~ defined extended_primary_loader
|
||||
save_quest:cp850 "¿Recordar configuración actual? [s/n]: ",0
|
||||
loader_block_error:cp850 "Bootloader inválido, no puedo continuar. Detenido.",0
|
||||
save_quest cp850 "¿Recordar configuración actual? [s/n]: ",0
|
||||
loader_block_error cp850 "Bootloader inválido, no puedo continuar. Detenido.",0
|
||||
end if
|
||||
|
||||
_st:cp850 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1:cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0
|
||||
_r2:cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0
|
||||
_rs:cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt:cp850 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
_st cp850 '║ ┌───────────────────────────────┬─┐',13,10,0
|
||||
_r1 cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0
|
||||
_r2 cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0
|
||||
_rs cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
|
||||
_bt cp850 '║ └───────────────────────────────┴─┘',13,10,0
|
||||
|
||||
remark1:cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0
|
||||
remark2:cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b].",0
|
||||
remarks dw remark1, remark2
|
||||
num_remarks = 2
|
||||
remark1 cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0
|
||||
remark2 cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b]. Si se bloquea",0
|
||||
remark3 cp850 "después de arrancar, habilite la opción [c], desactivar [d] y hacer fotos.",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
@ -79,6 +79,7 @@ virtual at $A000
|
||||
modes_table:
|
||||
end virtual
|
||||
cursor_pos dw 0 ;временное хранение курсора.
|
||||
cursor_pos_old dw 0
|
||||
home_cursor dw 0 ;current shows rows a table
|
||||
end_cursor dw 0 ;end of position current shows rows a table
|
||||
scroll_start dw 0 ;start position of scroll bar
|
||||
|
@ -9,7 +9,7 @@ $Revision$
|
||||
|
||||
|
||||
; Full ASCII code font
|
||||
; only õ and ä added
|
||||
; only õ,ä,ü added
|
||||
; Kaitz
|
||||
ET_FNT:
|
||||
fontfile file "ETFONT.FNT"
|
||||
|
@ -105,6 +105,9 @@ ConfigPipe dd ?
|
||||
StatusPipe dd ?
|
||||
NumPorts dd ?
|
||||
; Number of downstream ports; from 1 to 255.
|
||||
MaxPacketSize dd ?
|
||||
; Maximum packet size for interrupt endpoint.
|
||||
; Usually equals ceil((1+NumPorts)/8), but some hubs give additional bytes.
|
||||
Actions dd ?
|
||||
; Bitfield with HUB_* constants.
|
||||
PoweredOnTime dd ?
|
||||
@ -250,10 +253,11 @@ end virtual
|
||||
; the pointer is in edx.
|
||||
; 2. Allocate memory for the hub descriptor.
|
||||
; Maximum length (assuming 255 downstream ports) is 40 bytes.
|
||||
; Allocate 4 extra bytes to keep wMaxPacketSize.
|
||||
; 2a. Save registers.
|
||||
push edx
|
||||
; 2b. Call the allocator.
|
||||
movi eax, 40
|
||||
movi eax, 44
|
||||
call malloc
|
||||
; 2c. Restore registers.
|
||||
pop ecx
|
||||
@ -267,7 +271,11 @@ end virtual
|
||||
movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress]
|
||||
movzx edx, [ecx+usb_endpoint_descr.bInterval]
|
||||
movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
|
||||
test ecx, (1 shl 11) - 1
|
||||
jz .free
|
||||
push ecx
|
||||
stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
|
||||
pop ecx
|
||||
; If failed, free the memory allocated in step 2,
|
||||
; say something to the debug board and return error.
|
||||
test eax, eax
|
||||
@ -275,6 +283,8 @@ end virtual
|
||||
; 4. Send control query for the hub descriptor,
|
||||
; pass status pipe as a callback parameter,
|
||||
; allow short packets.
|
||||
and ecx, (1 shl 11) - 1
|
||||
mov [esi+40], ecx
|
||||
mov dword [esi], 0xA0 + \ ; class-specific request
|
||||
(USB_GET_DESCRIPTOR shl 8) + \
|
||||
(0 shl 16) + \ ; descriptor index 0
|
||||
@ -352,8 +362,9 @@ end if
|
||||
cmp [length], edx
|
||||
jb .invalid
|
||||
; 5. Allocate the memory for usb_hub structure.
|
||||
; Total size of variable-length data is ALIGN_UP(2*(floor(NumPorts/8)+1),4)+8*NumPorts.
|
||||
lea edx, [sizeof.usb_hub+(edx-sizeof.usb_hub_descr)*2+3]
|
||||
; Total size of variable-length data is ALIGN_UP(floor(NumPorts/8)+1+MaxPacketSize,4)+8*NumPorts.
|
||||
add edx, [eax+40]
|
||||
add edx, sizeof.usb_hub - sizeof.usb_hub_descr + 3
|
||||
and edx, not 3
|
||||
lea eax, [edx+ecx*8]
|
||||
push ecx edx
|
||||
@ -374,6 +385,8 @@ end if
|
||||
mov [ebx+usb_hub.StatusPipe], eax
|
||||
push esi edi
|
||||
mov esi, [buffer]
|
||||
mov eax, [esi+40]
|
||||
mov [ebx+usb_hub.MaxPacketSize], eax
|
||||
; The following commands load bNbrPorts, wHubCharacteristics, bPwrOn2PwrGood.
|
||||
mov edx, dword [esi+usb_hub_descr.bNbrPorts]
|
||||
mov dl, 0
|
||||
@ -487,11 +500,8 @@ endp
|
||||
; Called when initial configuration is done and when a previous notification
|
||||
; has been processed.
|
||||
proc usb_hub_wait_change
|
||||
mov ecx, [eax+usb_hub.NumPorts]
|
||||
shr ecx, 3
|
||||
inc ecx
|
||||
stdcall usb_normal_transfer_async, [eax+usb_hub.StatusPipe], \
|
||||
[eax+usb_hub.StatusChangePtr], ecx, usb_hub_changed, eax, 1
|
||||
[eax+usb_hub.StatusChangePtr], [eax+usb_hub.MaxPacketSize], usb_hub_changed, eax, 1
|
||||
ret
|
||||
endp
|
||||
|
||||
@ -513,6 +523,7 @@ proc usb_hub_changed stdcall, pipe:dword, status:dword, buffer:dword, length:dwo
|
||||
shr ecx, 3
|
||||
inc ecx
|
||||
sub ecx, [length]
|
||||
jbe .restart
|
||||
push eax edi
|
||||
mov edi, [buffer]
|
||||
add edi, [length]
|
||||
|
@ -202,8 +202,7 @@ proc usb_new_device
|
||||
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
|
||||
; input and output, see usb_after_set_address. Later we will reallocate it
|
||||
; to actual size needed for descriptors.
|
||||
push sizeof.usb_device_data + 8
|
||||
pop eax
|
||||
movi eax, sizeof.usb_device_data + 8
|
||||
push ecx
|
||||
call malloc
|
||||
pop ecx
|
||||
@ -498,10 +497,7 @@ proc usb_after_set_endpoint_size
|
||||
pop edi esi
|
||||
call usb_reinit_pipe_list
|
||||
; 1d. Free the old memory.
|
||||
; Note that free destroys ebx.
|
||||
push ebx
|
||||
call free
|
||||
pop ebx
|
||||
pop eax
|
||||
; 2. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
|
||||
; restore length saved in step 1a
|
||||
|
148
kernel/branches/Kolibri-acpi/core/clipboard.inc
Normal file
148
kernel/branches/Kolibri-acpi/core/clipboard.inc
Normal file
@ -0,0 +1,148 @@
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
sys_clipboard:
|
||||
xor eax, eax
|
||||
dec eax
|
||||
; check availability of main list
|
||||
cmp [clipboard_main_list], eax
|
||||
je .exit_1 ; main list area not found
|
||||
|
||||
test ebx, ebx ; 0 - Get the number of slots in the clipboard
|
||||
jnz .1
|
||||
; get the number of slots
|
||||
mov eax, [clipboard_slots]
|
||||
jmp .exit_1
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
.1:
|
||||
dec ebx ; 1 - Read the data from the clipboard
|
||||
jnz .2
|
||||
; verify the existence of slot
|
||||
cmp ecx, [clipboard_slots]
|
||||
jae .exit_2
|
||||
; get a pointer to the data of slot
|
||||
shl ecx, 2
|
||||
add ecx, [clipboard_main_list]
|
||||
mov esi, [ecx]
|
||||
mov ecx, [esi]
|
||||
; allocate memory for application for copy the data of slots
|
||||
push ecx
|
||||
stdcall user_alloc, ecx
|
||||
pop ecx
|
||||
; copying data of slots
|
||||
mov edi, eax
|
||||
cld
|
||||
rep movsb
|
||||
jmp .exit_1
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
.2:
|
||||
dec ebx ; 2 - Write the data to the clipboard
|
||||
jnz .3
|
||||
; check the lock
|
||||
mov ebx, clipboard_write_lock
|
||||
xor eax, eax
|
||||
cmp [ebx], eax
|
||||
jne .exit_2
|
||||
; lock last slot
|
||||
inc eax
|
||||
mov [ebx], eax
|
||||
; check the overflow pointer of slots
|
||||
cmp [clipboard_slots], 1024
|
||||
jae .exit_3
|
||||
; get memory for new slot
|
||||
push ebx ecx edx
|
||||
stdcall kernel_alloc, ecx
|
||||
pop edx ecx ebx
|
||||
test eax, eax
|
||||
jz .exit_3
|
||||
; create a new slot
|
||||
mov edi, eax
|
||||
mov eax, [clipboard_slots]
|
||||
shl eax, 2
|
||||
add eax, [clipboard_main_list]
|
||||
mov [eax], edi
|
||||
; copy the data into the slot
|
||||
mov esi, edx
|
||||
mov eax, ecx
|
||||
cld
|
||||
stosd ; store size of slot
|
||||
sub ecx, 4
|
||||
add esi, 4
|
||||
rep movsb ; store slot data
|
||||
; increase the counter of slots
|
||||
inc [clipboard_slots]
|
||||
; unlock last slot
|
||||
xor eax, eax
|
||||
mov [ebx], eax
|
||||
jmp .exit_1
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
.3:
|
||||
dec ebx ; 3 - Delete the last slot in the clipboard
|
||||
jnz .4
|
||||
; check the availability of slots
|
||||
mov eax, [clipboard_slots]
|
||||
test eax, eax
|
||||
jz .exit_2
|
||||
; check the lock
|
||||
mov ebx, clipboard_write_lock
|
||||
xor eax, eax
|
||||
cmp [ebx], eax
|
||||
jne .exit_2
|
||||
; lock last slot
|
||||
inc eax
|
||||
mov [ebx], eax
|
||||
; decrease the counter of slots
|
||||
mov eax, clipboard_slots
|
||||
dec dword [eax]
|
||||
; free of kernel memory allocated for the slot
|
||||
mov eax, [eax]
|
||||
shl eax, 2
|
||||
add eax, [clipboard_main_list]
|
||||
mov eax, [eax]
|
||||
push ebx
|
||||
stdcall kernel_free, eax
|
||||
pop ebx
|
||||
; unlock last slot
|
||||
xor eax, eax
|
||||
mov [ebx], eax
|
||||
jmp .exit_1
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
.4:
|
||||
dec ebx ; 4 - Emergency discharge of clipboard
|
||||
jnz .exit
|
||||
; check the lock
|
||||
mov ebx, clipboard_write_lock
|
||||
xor eax, eax
|
||||
cmp [ebx], eax
|
||||
je .exit_2
|
||||
|
||||
; there should be a procedure for checking the integrity of the slots
|
||||
; and I will do so in the future
|
||||
|
||||
; unlock last slot
|
||||
mov [ebx], eax
|
||||
jmp .exit
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
.exit_3:
|
||||
; unlock last slot
|
||||
xor eax, eax
|
||||
mov [ebx], eax
|
||||
.exit_2:
|
||||
xor eax, eax
|
||||
inc eax ; error
|
||||
.exit_1:
|
||||
mov [esp + 32], eax
|
||||
.exit:
|
||||
ret
|
||||
;------------------------------------------------------------------------------
|
||||
uglobal
|
||||
align 4
|
||||
clipboard_slots dd ?
|
||||
clipboard_main_list dd ?
|
||||
clipboard_write_lock dd ?
|
||||
endg
|
||||
;------------------------------------------------------------------------------
|
@ -1,11 +1,11 @@
|
||||
; Éste archivo debe ser editado con codificación CP866
|
||||
|
||||
ugui_mouse_speed:cp850 'velocidad del ratón',0
|
||||
ugui_mouse_delay:cp850 'demora del ratón',0
|
||||
ugui_mouse_speed cp850 'velocidad del ratón',0
|
||||
ugui_mouse_delay cp850 'demora del ratón',0
|
||||
|
||||
udev:cp850 'disp',0
|
||||
unet:cp850 'red',0
|
||||
unet_active:cp850 'activa',0
|
||||
unet_addr:cp850 'direc',0
|
||||
unet_mask:cp850 'másc',0
|
||||
unet_gate:cp850 'puer',0
|
||||
udev cp850 'disp',0
|
||||
unet cp850 'red',0
|
||||
unet_active cp850 'activa',0
|
||||
unet_addr cp850 'direc',0
|
||||
unet_mask cp850 'másc',0
|
||||
unet_gate cp850 'puer',0
|
||||
|
@ -458,7 +458,6 @@ proc load_file_umode stdcall, file_name:dword
|
||||
push edi
|
||||
push ebx
|
||||
|
||||
|
||||
lea eax, [attr]
|
||||
stdcall get_fileinfo, [file_name], eax ;find file and get info
|
||||
test eax, eax
|
||||
@ -484,11 +483,26 @@ proc load_file_umode stdcall, file_name:dword
|
||||
|
||||
mov ebx, [eax+4] ;get real size of file
|
||||
mov [file_size], ebx
|
||||
stdcall user_alloc, ebx ;and allocate memory from user heap
|
||||
stdcall user_alloc, ebx ;and allocate space from user heap
|
||||
mov [um_file], eax
|
||||
test eax, eax
|
||||
jz .err_2
|
||||
|
||||
mov edx, [file_size] ;preallocate page memory
|
||||
shr eax, 10
|
||||
lea edi, [page_tabs+eax]
|
||||
add edx, 4095
|
||||
shr edx, 12
|
||||
@@:
|
||||
call alloc_page
|
||||
test eax, eax
|
||||
jz .err_3
|
||||
|
||||
or eax, PG_UW
|
||||
stosd
|
||||
dec edx
|
||||
jnz @B
|
||||
|
||||
pushad
|
||||
mov ecx, unpack_mutex
|
||||
call mutex_lock
|
||||
@ -501,15 +515,28 @@ proc load_file_umode stdcall, file_name:dword
|
||||
|
||||
stdcall kernel_free, [km_file] ;we don't need packed file anymore
|
||||
.exit:
|
||||
|
||||
mov edi, [um_file]
|
||||
mov esi, [um_file]
|
||||
mov eax, [file_size]
|
||||
mov edx, eax
|
||||
|
||||
add edi, eax ;cleanup remain space
|
||||
mov ecx, 4096 ;from file end
|
||||
and eax, 4095
|
||||
jz @f
|
||||
sub ecx, eax
|
||||
xor eax, eax
|
||||
cld
|
||||
rep stosb
|
||||
@@:
|
||||
mov eax, [um_file]
|
||||
mov edx, [file_size]
|
||||
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
|
||||
.raw_file: ; sometimes we load unpacked file
|
||||
stdcall user_alloc, ebx ; allocate space from user heap
|
||||
mov [um_file], eax
|
||||
@ -533,13 +560,14 @@ proc load_file_umode stdcall, file_name:dword
|
||||
@@:
|
||||
lodsd
|
||||
and eax, 0xFFFFF000
|
||||
or eax, PG_USER
|
||||
or eax, PG_UW
|
||||
stosd
|
||||
loop @B
|
||||
|
||||
stdcall free_kernel_space, [km_file] ; release allocated kernel space
|
||||
jmp .exit ; physical pages still in use
|
||||
|
||||
.err_3:
|
||||
stdcall user_free, [um_file]
|
||||
.err_2:
|
||||
stdcall kernel_free, [km_file]
|
||||
.err_1:
|
||||
|
@ -81,6 +81,8 @@ __exports:
|
||||
register_keyboard, 'RegKeyboard', \
|
||||
delete_keyboard, 'DelKeyboard', \
|
||||
get_cpu_freq, 'GetCpuFreq', \
|
||||
\
|
||||
new_sys_threads, 'CreateThread', \ ; ebx, ecx, edx
|
||||
\
|
||||
srv_handler, 'ServiceHandler', \
|
||||
fpu_save, 'FpuSave', \
|
||||
|
@ -1,4 +1,4 @@
|
||||
; Éste archivo debe ser editado con codificación CP866
|
||||
|
||||
msg_sel_ker: cp850 "núcleo", 0
|
||||
msg_sel_app: cp850 "aplicación", 0
|
||||
msg_sel_ker cp850 "núcleo", 0
|
||||
msg_sel_app cp850 "aplicación", 0
|
||||
|
@ -247,6 +247,83 @@ show_error_parameters:
|
||||
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
|
||||
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
|
||||
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
|
||||
|
||||
DEBUGF 1, "K : Stack dump:\n"
|
||||
push eax ebx ecx edx
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, "K : [ESP+00]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+04]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+08]: %x\n",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, "K : [ESP+12]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+16]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+20]: %x\n",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, "K : [ESP+24]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+28]: %x",[ebx]
|
||||
add ebx, 4
|
||||
call .check_ESP
|
||||
test eax, eax
|
||||
jnz .error_ESP
|
||||
DEBUGF 1, " [ESP+32]: %x\n",[ebx]
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
.error_ESP:
|
||||
pop edx ecx ebx eax
|
||||
DEBUGF 1, "\n"
|
||||
DEBUGF 1, "K : Unexpected end of the stack\n"
|
||||
ret
|
||||
;--------------------------------------
|
||||
.check_ESP:
|
||||
push ebx
|
||||
shr ebx, 12
|
||||
mov ecx, ebx
|
||||
shr ecx, 10
|
||||
mov edx, [master_tab+ecx*4]
|
||||
test edx, PG_MAP
|
||||
jz .fail ;page table is not created
|
||||
;incorrect address in the program
|
||||
|
||||
mov eax, [page_tabs+ebx*4]
|
||||
test eax, 2
|
||||
jz .fail ;address not reserved for use. error
|
||||
|
||||
pop ebx
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.fail:
|
||||
pop ebx
|
||||
xor eax, eax
|
||||
dec eax
|
||||
ret
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
|
@ -184,7 +184,7 @@ iglobal
|
||||
dd syscall_threads ; 51-Threads
|
||||
dd undefined_syscall ; 52- deprecated Stack driver status
|
||||
dd undefined_syscall ; 53- deprecated Socket interface
|
||||
dd undefined_syscall ; 54-reserved
|
||||
dd sys_clipboard ; 54-Custom clipboard
|
||||
dd sound_interface ; 55-Sound interface
|
||||
dd undefined_syscall ; 56-reserved
|
||||
dd sys_pcibios ; 57-PCI BIOS32
|
||||
|
@ -924,10 +924,17 @@ proc write_process_memory
|
||||
ret
|
||||
endp
|
||||
|
||||
;ebx = 1 - kernel thread
|
||||
;ecx=thread entry point
|
||||
;edx=thread stack pointer
|
||||
;creation flags 0x01 - debugged
|
||||
; 0x02 - kernel
|
||||
|
||||
align 4
|
||||
proc new_sys_threads
|
||||
locals
|
||||
slot dd ?
|
||||
flags dd ?
|
||||
app_cmdline dd ? ;0x00
|
||||
app_path dd ? ;0x04
|
||||
app_eip dd ? ;0x08
|
||||
@ -935,16 +942,15 @@ proc new_sys_threads
|
||||
app_mem dd ? ;0x10
|
||||
endl
|
||||
|
||||
cmp ebx, 1
|
||||
jne .failed ;other subfunctions
|
||||
shl ebx, 1
|
||||
mov [flags], ebx
|
||||
|
||||
xor eax, eax
|
||||
mov [app_eip], ecx
|
||||
mov [app_cmdline], eax
|
||||
mov [app_esp], edx
|
||||
mov [app_path], eax
|
||||
;mov esi,new_process_loading
|
||||
;call sys_msg_board_str
|
||||
|
||||
call lock_application_table
|
||||
|
||||
call get_new_process_place
|
||||
@ -998,10 +1004,8 @@ proc new_sys_threads
|
||||
|
||||
lea eax, [app_cmdline]
|
||||
stdcall set_app_params , [slot], eax, dword 0, \
|
||||
dword 0,dword 0
|
||||
dword 0, [flags]
|
||||
|
||||
;mov esi,new_process_running
|
||||
;call sys_msg_board_str ;output information about succefull startup
|
||||
mov eax, [process_number] ;set result
|
||||
call unlock_application_table
|
||||
ret
|
||||
@ -1207,14 +1211,13 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
||||
mov [ebx+REG_EIP], eax;app_entry
|
||||
mov [ebx+REG_CS], dword app_code
|
||||
mov ecx, USER_PRIORITY
|
||||
mov eax, [CURRENT_TASK]
|
||||
shl eax, 8 ; created by kernel?
|
||||
cmp [SLOT_BASE+eax+APPDATA.dir_table], sys_pgdir - OS_BASE
|
||||
jnz @f
|
||||
cmp [app_path], 0 ; it is a thread?
|
||||
jnz @f
|
||||
|
||||
test byte [flags], 2
|
||||
jz @F
|
||||
|
||||
mov [ebx+REG_CS], dword os_code ; kernel thread
|
||||
mov ecx, MAX_PRIORITY
|
||||
|
||||
@@:
|
||||
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
|
||||
|
||||
@ -1238,8 +1241,6 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
||||
mov [CURRENT_TASK+ebx+TASKDATA.state], dl
|
||||
lea edx, [SLOT_BASE+ebx*8]
|
||||
call scheduler_add_thread
|
||||
;mov esi,new_process_running
|
||||
;call sys_msg_board_str ;output information about succefull startup
|
||||
ret
|
||||
endp
|
||||
|
||||
|
@ -49,48 +49,50 @@ keymap_alt:
|
||||
|
||||
|
||||
if lang eq ru
|
||||
boot_initirq: cp866 'Инициализация IRQ',0
|
||||
boot_picinit: cp866 'Инициализация PIC',0
|
||||
boot_v86machine: cp866 'Инициализация системы V86 машины',0
|
||||
boot_inittimer: cp866 'Инициализация системного таймера (IRQ0)',0
|
||||
boot_initapic: cp866 'Попытка инициализации APIC',0
|
||||
boot_enableirq: cp866 'Включить прерывания 2, 13',0
|
||||
boot_disabling_ide:cp866 'Запрещение прерываний в контроллере IDE',0
|
||||
boot_enabling_ide:cp866 'Разрешение прерываний в контроллере IDE',0
|
||||
boot_set_int_IDE: cp866 'Установка обработчиков прерываний IDE',0
|
||||
boot_detectfloppy:cp866 'Поиск floppy дисководов',0
|
||||
boot_detecthdcd: cp866 'Поиск жестких дисков и ATAPI приводов',0
|
||||
boot_getcache: cp866 'Получение памяти для кэша',0
|
||||
boot_detectpart: cp866 'Поиск разделов на дисковых устройствах',0
|
||||
boot_init_sys: cp866 'Инициализация системного каталога /sys',0
|
||||
boot_loadlibs: cp866 'Загрузка библиотек (.obj)',0
|
||||
boot_memdetect: cp866 'Количество оперативной памяти',' ',' Мб',0
|
||||
boot_tss: cp866 'Установка TSSs',0
|
||||
boot_cpuid: cp866 'Чтение CPUIDs',0
|
||||
; boot_devices: cp866 'Поиск устройств',0
|
||||
boot_timer: cp866 'Установка таймера',0
|
||||
boot_irqs: cp866 'Переопределение IRQ',0
|
||||
boot_setmouse: cp866 'Установка мыши',0
|
||||
boot_windefs: cp866 'Установка настроек окон по умолчанию',0
|
||||
boot_bgr: cp866 'Установка фона',0
|
||||
boot_resirqports: cp866 'Резервирование IRQ и портов',0
|
||||
boot_setrports: cp866 'Установка адресов IRQ',0
|
||||
boot_setostask: cp866 'Создание процесса ядра',0
|
||||
boot_allirqs: cp866 'Открытие всех IRQ',0
|
||||
boot_tsc: cp866 'Чтение TSC',0
|
||||
boot_cpufreq: cp866 'Частота процессора ',' ',' МГц',0
|
||||
boot_pal_ega: cp866 'Установка EGA/CGA 320x200 палитры',0
|
||||
boot_pal_vga: cp866 'Установка VGA 640x480 палитры',0
|
||||
boot_failed: cp866 'Загрузка первого приложения не удалась',0
|
||||
boot_mtrr: cp866 'Установка MTRR',0
|
||||
boot_initirq cp866 'Инициализация IRQ',0
|
||||
boot_picinit cp866 'Инициализация PIC',0
|
||||
boot_v86machine cp866 'Инициализация системы V86 машины',0
|
||||
boot_inittimer cp866 'Инициализация системного таймера (IRQ0)',0
|
||||
boot_initapic cp866 'Попытка инициализации APIC',0
|
||||
boot_enableirq cp866 'Включить прерывания 2, 13',0
|
||||
boot_disabling_ide cp866 'Запрещение прерываний в контроллере IDE',0
|
||||
boot_enabling_ide cp866 'Разрешение прерываний в контроллере IDE',0
|
||||
boot_set_int_IDE cp866 'Установка обработчиков прерываний IDE',0
|
||||
boot_detectfloppy cp866 'Поиск floppy дисководов',0
|
||||
boot_detecthdcd cp866 'Поиск жестких дисков и ATAPI приводов',0
|
||||
boot_getcache cp866 'Получение памяти для кэша',0
|
||||
boot_detectpart cp866 'Поиск разделов на дисковых устройствах',0
|
||||
boot_init_sys cp866 'Инициализация системного каталога /sys',0
|
||||
boot_loadlibs cp866 'Загрузка библиотек (.obj)',0
|
||||
boot_memdetect cp866 'Количество оперативной памяти',' ',' Мб',0
|
||||
boot_tss cp866 'Установка TSSs',0
|
||||
boot_cpuid cp866 'Чтение CPUIDs',0
|
||||
; boot_devices cp866 'Поиск устройств',0
|
||||
boot_timer cp866 'Установка таймера',0
|
||||
boot_irqs cp866 'Переопределение IRQ',0
|
||||
boot_setmouse cp866 'Установка мыши',0
|
||||
boot_windefs cp866 'Установка настроек окон по умолчанию',0
|
||||
boot_bgr cp866 'Установка фона',0
|
||||
boot_resirqports cp866 'Резервирование IRQ и портов',0
|
||||
boot_setrports cp866 'Установка адресов IRQ',0
|
||||
boot_setostask cp866 'Создание процесса ядра',0
|
||||
boot_allirqs cp866 'Открытие всех IRQ',0
|
||||
boot_tsc cp866 'Чтение TSC',0
|
||||
boot_cpufreq cp866 'Частота процессора ',' ',' МГц',0
|
||||
boot_pal_ega cp866 'Установка EGA/CGA 320x200 палитры',0
|
||||
boot_pal_vga cp866 'Установка VGA 640x480 палитры',0
|
||||
boot_failed cp866 'Загрузка первого приложения не удалась',0
|
||||
boot_mtrr cp866 'Установка MTRR',0
|
||||
|
||||
boot_APIC_found: cp866 'APIC включен', 0
|
||||
boot_APIC_nfound: cp866 'APIC не найден', 0
|
||||
boot_APIC_found cp866 'APIC включен', 0
|
||||
boot_APIC_nfound cp866 'APIC не найден', 0
|
||||
if preboot_blogesc
|
||||
boot_tasking: cp866 'Все готово для запуска, нажмитре ESC для старта',0
|
||||
boot_tasking cp866 'Все готово для запуска, нажмитре ESC для старта',0
|
||||
end if
|
||||
else if lang eq sp
|
||||
include 'data32sp.inc'
|
||||
else if lang eq et
|
||||
include 'data32et.inc'
|
||||
else
|
||||
boot_initirq db 'Initialize IRQ',0
|
||||
boot_picinit db 'Initialize PIC',0
|
||||
@ -163,7 +165,7 @@ read_firstapp db '/sys/'
|
||||
firstapp db 'LAUNCHER',0
|
||||
notifyapp db '@notify',0
|
||||
if lang eq ru
|
||||
ud_user_message: cp866 'Ошибка: неподдерживаемая инструкция процессора',0
|
||||
ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0
|
||||
else if ~ lang eq sp
|
||||
ud_user_message db 'Error: unsupported processor instruction',0
|
||||
end if
|
||||
@ -385,7 +387,7 @@ end if
|
||||
REDRAW_BACKGROUND rb 4
|
||||
|
||||
align 4
|
||||
draw_data: rb 16*256
|
||||
draw_data: rb 32*256
|
||||
BPSLine_calc_area rd 1440
|
||||
d_width_calc_area rd 1140
|
||||
|
||||
|
37
kernel/branches/Kolibri-acpi/data32et.inc
Normal file
37
kernel/branches/Kolibri-acpi/data32et.inc
Normal file
@ -0,0 +1,37 @@
|
||||
boot_initirq latin1 'Algväärtustan IRQ',0
|
||||
boot_picinit latin1 'Algväärtustan PIC',0
|
||||
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0
|
||||
boot_inittimer latin1 'Algväärtustan süsteemi taimerit (IRQ0)',0
|
||||
boot_initapic latin1 'Proovin Algväärtustada APIC',0
|
||||
boot_enableirq latin1 'Luban katkestused 2, 13',0
|
||||
boot_disabling_ide latin1 'Keelan IDE kontrolleri katkestused',0
|
||||
boot_enabling_ide latin1 'Luban IDE kontrolleri katkestused',0
|
||||
boot_set_int_IDE latin1 'Määran IDE kontrolleri halduri',0
|
||||
boot_detectfloppy latin1 'Otsin floppi kettaid',0
|
||||
boot_detecthdcd latin1 'Otsin kõvakettaid ja ATAPI seadmeid',0
|
||||
boot_getcache latin1 'Küsin puhvri mälu',0
|
||||
boot_detectpart latin1 'Otsin kettaseadmete partitsioone',0
|
||||
boot_init_sys latin1 'Algväärtustan süsteemi kataloogi /sys',0
|
||||
boot_loadlibs latin1 'Laadin mooduleid (.obj)',0
|
||||
boot_memdetect latin1 'Avastan mälu mahtu',0
|
||||
boot_tss latin1 'Määran TSSe',0
|
||||
boot_cpuid latin1 'Loen CPUIDd',0
|
||||
; boot_devices db 'Detecting devices',0
|
||||
boot_setmouse latin1 'Seadistan hiirt',0
|
||||
boot_windefs latin1 'Seadistan akende vaikeväärtusi',0
|
||||
boot_bgr latin1 'Kalkuleerin tausta',0
|
||||
boot_resirqports latin1 'Reserveerin IRQsi ja porte',0
|
||||
boot_setostask latin1 'Seadistan OS protsessi',0
|
||||
boot_allirqs latin1 'Unmasking IRQs',0
|
||||
boot_tsc latin1 'Loen TSC',0
|
||||
boot_cpufreq latin1 'CPU sagedus on ',' ',' MHz',0
|
||||
boot_pal_ega latin1 'Seadistan EGA/CGA 320x200 paletti',0
|
||||
boot_pal_vga latin1 'Seadistan VGA 640x480 paletti',0
|
||||
boot_failed latin1 'Esimese programmi käivitamine ebaõnnestus',0
|
||||
boot_mtrr latin1 'Määran MTRR',0
|
||||
|
||||
boot_APIC_found latin1 'APIC aktiveeritud', 0
|
||||
boot_APIC_nfound latin1 'APIC ei leitud', 0
|
||||
if preboot_blogesc
|
||||
boot_tasking latin1 'Kõik valmis - vajuta ESC alustamiseks',0
|
||||
end if
|
92
kernel/branches/Kolibri-acpi/detect/vortex86.inc
Normal file
92
kernel/branches/Kolibri-acpi/detect/vortex86.inc
Normal file
@ -0,0 +1,92 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; 20/11/2013 yogev_ezra: Initial version ;;
|
||||
;; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4261 $
|
||||
|
||||
VORTEX86DEBUG = 0 ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1
|
||||
VORTEX86DEBUGVALUE = 0x35504d44 ; FAKE port output = used for testing
|
||||
|
||||
; Detect Vortex86 CPU and generate CPU name in string format (PCI address at 93H~90H in Vortex86 North Bridge contains SoC type)
|
||||
; Available Vortex86 CPU codes taken from Coreboot project. New codes should be added to "Vortex86SoClist" below
|
||||
; #define DMP_CPUID_SX 0x31504d44 ("DMP1")
|
||||
; #define DMP_CPUID_DX 0x32504d44 ("DMP2")
|
||||
; #define DMP_CPUID_MX 0x33504d44 ("DMP3")
|
||||
; #define DMP_CPUID_DX2 0x34504d44 ("DMP4")
|
||||
; #define DMP_CPUID_MX_PLUS 0x35504d44 ("DMP5")
|
||||
; #define DMP_CPUID_EX 0x37504d44 ("DMP7")
|
||||
|
||||
iglobal
|
||||
Vortex86CPUcode dd ? ; Vortex86 CPU code in HEX format (4 bytes), can be shown as string if converted to ASCII characters
|
||||
Vortex86CPUid db 0 ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...)
|
||||
Vortex86SoCname db 'Vortex86 ',0 ; This variable will hold the full name of Vortex86 SoC
|
||||
Vortex86SoClist: ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available
|
||||
db 0x31, 'SX ' ; id=1
|
||||
db 0x32, 'DX ' ; id=2
|
||||
db 0x33, 'MX ' ; id=3
|
||||
db 0x34, 'DX2' ; id=4
|
||||
db 0x35, 'MX+' ; id=5
|
||||
db 0x37, 'EX ' ; id=6
|
||||
Vortex86SoCnum = ($ - Vortex86SoClist) / 4 ; Calculate the total number of known Vortex86 CPUs (if id=Vortex86SoCnum+1 --> unknown SoC)
|
||||
endg
|
||||
|
||||
mov dx, 0xcf8 ; CF8h = Vortex86 PCI Configuration Address port
|
||||
mov eax, 0x80000090 ; 0x80000090 = Starting PCI address to read from (32-bit register - accessed as DWORD)
|
||||
out dx, eax ; Send request to PCI address port to retrieve data from this address
|
||||
mov dx, 0xcfc ; CFCh = Vortex86 PCI Configuration Data port
|
||||
in eax, dx ; Read data (SoC type) from PCI data port
|
||||
|
||||
if VORTEX86DEBUG
|
||||
; // Used for debug purposes: testing in emulator and in non-Vortex86 CPU computers
|
||||
mov eax, VORTEX86DEBUGVALUE
|
||||
end if
|
||||
|
||||
DEBUGF 1, "K : Vortex86 SoC register returned 0x"
|
||||
test eax, eax ; We need to break out in case the result is '\0' since otherwise we will fail at NULL string
|
||||
jz .nullPCIoutput
|
||||
mov [Vortex86CPUcode], eax
|
||||
DEBUGF 1, "%x (%s): ", eax, Vortex86CPUcode
|
||||
cmp ax, 4d44h ; Check whether it's Vortex86 family (all Vortex86 SoC have ID in form of "0xNN504d44")
|
||||
jnz .notVortex86
|
||||
shr eax, 16 ; Discard lower word in EAX which is always 4d44h in Vortex86 family
|
||||
cmp al, 50h ; The 3rd byte is always 50h in Vortex86 SoC
|
||||
jnz .notVortex86
|
||||
shr ax, 8 ; Discard 3rd byte in EAX, the highest byte determines the SoC type
|
||||
mov bl, al ; Copy SoC type to BL since EAX (that contains AL) is used implicitly in "LODSD" command below
|
||||
mov esi, Vortex86SoClist ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below)
|
||||
xor ecx, ecx ; Zero ECX (it is used as counter)
|
||||
cld ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI)
|
||||
@@:
|
||||
cmp ecx, Vortex86SoCnum ; Check if we iterated Vortex86SoCnum times already (i.e. went over the entire Vortex86SoClist)
|
||||
ja .unknownVortex86 ; If the entire list was tested and our CPU is not in that list, it is unknown Vortex86 SoC
|
||||
inc ecx ; Increment our counter
|
||||
lodsd ; Load DWORD at address DS:ESI into EAX (puts 1 line from Vortex86SoClist into EAX, then increments ESI)
|
||||
cmp bl, al ; Check if our CPU matches the current record in the list
|
||||
jne @b ; No match --> repeat with next record
|
||||
|
||||
shr eax, 8 ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0
|
||||
mov dword [Vortex86SoCname+8], eax ; Concatenate it with prefix to receive complete SoC name (\0 is string termination)
|
||||
mov [Vortex86CPUid], cl ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., Vortex86SoCnum+1=Unknown Vortex86)
|
||||
|
||||
DEBUGF 1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1
|
||||
jmp .Vortex86end ; Say what we have found (CPU name and id) and exit
|
||||
|
||||
.nullPCIoutput: ; Emulators and non-Vortex86 CPU computers will usually return \0 in this register
|
||||
DEBUGF 1, "0 (NULL)\n"
|
||||
jmp .Vortex86end
|
||||
|
||||
.unknownVortex86:
|
||||
mov [Vortex86CPUid], cl ; Save the CPUid (Vortex86SoCnum+1=Unknown Vortex86)
|
||||
DEBUGF 1, "unknown Vortex86 CPU (has id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum
|
||||
jmp .Vortex86end
|
||||
|
||||
.notVortex86: ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
|
||||
DEBUGF 1, "not a Vortex86 CPU\n"
|
||||
|
||||
.Vortex86end:
|
232
kernel/branches/Kolibri-acpi/docs/events_subsystem.txt
Normal file
232
kernel/branches/Kolibri-acpi/docs/events_subsystem.txt
Normal file
@ -0,0 +1,232 @@
|
||||
Дата последней правки 26/07/2013.
|
||||
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
|
||||
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
|
||||
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
|
||||
|
||||
struc EVENT
|
||||
{
|
||||
.magic dd ? ; 'EVNT'
|
||||
.destroy dd ? ; internal destructor
|
||||
.fd dd ? ; next object in list
|
||||
.bk dd ? ; prev object in list
|
||||
.pid dd ? ; owner id. идентификатор владельца (потока)
|
||||
.id dd ? ; event uid. уникальный идентификатор события (просто номерок)
|
||||
.state dd ? ; internal flags; см. далее.
|
||||
.code dd ? ; старший байт класс события, ; следующий байт приоритет
|
||||
; (будет использоваться только внутри ядра, при чтении всегда 0),
|
||||
; Чем больше численное значение двойного слова тем важнее событие.
|
||||
; два младших байта код события.
|
||||
rd 5 ; .data - точная структура этого поля не определена и зависит
|
||||
; от поля .code. (Здесь можно передавать какие-то свои данные,
|
||||
; при необходимости :)
|
||||
.size = $ - .magic
|
||||
.codesize = $ - .code
|
||||
}
|
||||
|
||||
События реального времени получили класс 0хFF. Пока определёны только:
|
||||
EVENT.code= ;(Используется в звуковой подсистеме).
|
||||
RT_INP_EMPTY equ 0xFF000001
|
||||
RT_OUT_EMPTY equ 0xFF000002
|
||||
RT_INP_FULL equ 0xFF000003
|
||||
RT_OUT_FULL equ 0xFF000004
|
||||
|
||||
|
||||
Флаги поля EVENT.state определены в gui/event.inc.
|
||||
EVENT_SIGNALED equ 0x20000000 ;Бит 29 событие активно/неактивно;
|
||||
EVENT_WATCHED equ 0x10000000 ;бит 28, поток-владелец ожидает активации события;
|
||||
MANUAL_RESET equ 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
|
||||
MANUAL_DESTROY equ 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
|
||||
|
||||
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
|
||||
и выглядит так:
|
||||
|
||||
struct APPOBJ ; common object header
|
||||
magic dd ? ;
|
||||
destroy dd ? ; internal destructor
|
||||
fd dd ? ; next object in list
|
||||
bk dd ? ; prev object in list
|
||||
pid dd ? ; owner id
|
||||
ends
|
||||
|
||||
struct EVENT APPOBJ
|
||||
id dd ? ;event uid
|
||||
state dd ? ;internal flags
|
||||
code dd ?
|
||||
rd 5 ; .data
|
||||
ends
|
||||
|
||||
Код находится в gui/event.inc.
|
||||
Сами события как обьекты существуют в памяти ядра в виде двусвязного списка (см. поля .bk и .fd).
|
||||
При инициализации ядро резервирует память и создает 512 таких обьектов, помещая их в список FreeEvents
|
||||
(свободных событий). При нехватке событий (все заняты, а нужно ещё) ядро создает ещё 512 свободных
|
||||
и т.д. Каждый поток имеет свои (двусвязные) списки (в которые может быть помещено событие):
|
||||
ObjList - список объектов ядра, ассоциированных с этим потоком;
|
||||
EventList - список событий ядра для потока.
|
||||
Сами события, физически, при перемещении между списками и смене очередности в списке не перемещаются
|
||||
и не копируются. Это происходит только благодаря модификации полей .fd и .bk. Принцип работы списков,
|
||||
как очередей - FIFO. Использутся неблокирующая отправка и блокирующее получение. Адресация - прямая
|
||||
(у события всегда есть поток-владелец), по идентификатору потока.
|
||||
|
||||
Жизненый цикл событий определяется флагами при создании. По умолчанию ядро использует значения
|
||||
MANUAL_RESET = 0 и MANUAL_DESTROY = 0. Такое событие является "одноразовым", и автоматически освобождается
|
||||
ядром, возвращаясь в список свободных событий после получения.
|
||||
Событие с флагом MANUAL_DESTROY = 1 после получения переходит в неактивное состояние, но остаётся в списке
|
||||
объектов потока и может использоваться снова. Событие с флагами MANUAL_DESTROY =1 и MANUAL_RESET = 1
|
||||
остаётся активным после получения и может быть сброшено вызовом ClearEvent.
|
||||
|
||||
Пример (вариант) жизненного цикла события из звуковой подсистемы:
|
||||
Для зукового буфера (их может быть несколько) драйвер создает событие в списке ObjList с помощью
|
||||
CreateEvent и флагом MANUAL_DESTROY. Далее драйвер вызывает WaitEvent для этого события (ожидает флага
|
||||
EVENT_SIGNALED в событии) и блокируется, в ожидании запроса на пополнение буфера. Запрос отправляется
|
||||
с помощью RaiseEvent из другого потока. Отправка (RaiseEvent) и получение (WaitEvent) циклически
|
||||
повторяются при опустошении буфера. При остановке воспроизведения драйвер деактивирует событие с помощью
|
||||
ClearEvent.
|
||||
|
||||
Вообще говоря, структура события приведена здесь только лишь для понимания принципов работы подсистемы.
|
||||
Самостоятельная работа с полями не приветствуется, ввиду возможных в будущем проблем с совместимостью.
|
||||
Работа должна производится только через API (функции подсистемы), с доступом только к тем полям, доступ к
|
||||
которым предоставляет функция. При этом пару "указатель на событие" и "уникальный идентификатор события"
|
||||
следует рассматривать как один 64-х битный уникальный идентификатор. (Если вы вызвали CreateEvent, напимер,
|
||||
его нужно запомнить где-нибудь [если это нужно] для дальнейшей работы с событием).
|
||||
|
||||
Функции для работы с событиями экспортитуемые ядром:
|
||||
(для драйверов и т.п.; вызываются в режиме ядра)
|
||||
|
||||
CreateEvent
|
||||
RaiseEvent
|
||||
ClearEvent
|
||||
SendEvent
|
||||
DestroyEvent
|
||||
WaitEvent
|
||||
WaitEventTimeout
|
||||
GetEvent
|
||||
Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
|
||||
|
||||
---------------------------------------------------------------------------------------------
|
||||
CreateEvent:
|
||||
Создаёт новое событие в очереди ObjList текущего потока.
|
||||
Устанавливает:
|
||||
EVENT.destroy <= внутренний деструктор по умолчанию;
|
||||
EVENT.pid <= текущий Process id;
|
||||
EVENT.id <= уникальный идентификатор;
|
||||
EVENT.state <= ecx - флаги;
|
||||
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
|
||||
Возвращает:
|
||||
eax - указатель на событие или 0 при ошибке.
|
||||
edx - Event.id.
|
||||
Портит: eax,ebx,edx,ecx,esi,edi
|
||||
---------------------------------------------------------------------------------------------
|
||||
RaiseEvent:
|
||||
Активирует уже существующее событие (может принадлежать другому потоку) установкой
|
||||
флага EVENT_SIGNALED. Если необходимо, - устанавливает данные EVENT.code.
|
||||
Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает.
|
||||
Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
|
||||
{EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
|
||||
Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации
|
||||
события.
|
||||
Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
|
||||
Принимает:
|
||||
eax - указатель на событие;
|
||||
ebx - id, уникальный идентификатор события;
|
||||
edx - флаги для операции (формат EVENT.state);
|
||||
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
|
||||
Возвращает: ?
|
||||
Портит: eax,ebx,edx,ecx,esi,edi .
|
||||
---------------------------------------------------------------------------------------------
|
||||
ClearEvent:
|
||||
Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
|
||||
Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),
|
||||
ничего не делает.
|
||||
Принимает:
|
||||
eax - указатель на событие;
|
||||
ebx - id, уникальный идентификатор события.
|
||||
Возвращает: ?
|
||||
Портит: eax,ebx,ecx,edi .
|
||||
---------------------------------------------------------------------------------------------
|
||||
SendEvent:
|
||||
Создаёт новое событие в списке событий целевого потока. Устанавливает в событии
|
||||
флаг EVENT_SIGNALED.
|
||||
Принимает:
|
||||
EVENT.pid <= eax - pid, идентификатор целевого потока;
|
||||
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
|
||||
Возвращает:
|
||||
eax - указатель на событие или 0 при ошибке.
|
||||
edx - Event.id. уникальный идентификатор.
|
||||
Портит: eax,ebx,ecx,esi,edi .
|
||||
---------------------------------------------------------------------------------------------
|
||||
DestroyEvent:
|
||||
Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
|
||||
Событие может принадлежать другому потоку.
|
||||
Принимает:
|
||||
eax - указатель на событие;
|
||||
ebx - id, уникальный идентификатор события.
|
||||
Возвращает:
|
||||
eax - 0 при ошибке, не 0 при успехе.
|
||||
Портит: eax,ebx,ecx .
|
||||
---------------------------------------------------------------------------------------------
|
||||
WaitEvent:
|
||||
Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
|
||||
вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
|
||||
RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
|
||||
Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
|
||||
Если в полученном событии НЕ установлен MANUAL_RESET, то:
|
||||
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
|
||||
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
|
||||
а при активном - перемещается в список ObjList текущего слота.}
|
||||
Принимает:
|
||||
eax - указатель на событие;
|
||||
ebx - id, уникальный идентификатор события.
|
||||
Возвращает: ?
|
||||
Портит: eax,ebx,edx,ecx,esi,edi .
|
||||
---------------------------------------------------------------------------------------------
|
||||
WaitEventTimeout:
|
||||
Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
|
||||
вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
|
||||
RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
|
||||
Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
|
||||
Если в полученном событии НЕ установлен MANUAL_RESET, то:
|
||||
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
|
||||
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
|
||||
а при активном - перемещается в список ObjList текущего слота.}
|
||||
Принимает:
|
||||
eax - указатель на событие;
|
||||
ebx - id, уникальный идентификатор события.
|
||||
ecx - время ожидания в тиках системного таймера.
|
||||
Возвращает:
|
||||
eax - 0 - таймаут, если событие не активировалось, или
|
||||
не 0, если было активировано.
|
||||
Портит: eax,ebx,edx,ecx,esi,edi .
|
||||
---------------------------------------------------------------------------------------------
|
||||
GetEvent:
|
||||
Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
|
||||
путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
|
||||
по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
|
||||
Если в полученном событии НЕ установлен MANUAL_RESET, то:
|
||||
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
|
||||
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
|
||||
а при активном - перемещается в список ObjList текущего слота.}
|
||||
Принимает:
|
||||
edi - указатель на буфер, куда копировать данные.
|
||||
Возвращает:
|
||||
буфер, содержащий следующую информацию:
|
||||
+0: (EVENT.code) dword: идентификатор последующих данных сигнала
|
||||
+4: (EVENT.data, поле формально не определено) данные принятого
|
||||
сигнала (5*dword), формат которых определяется первым dword-ом.
|
||||
Портит: eax,ebx,edx,ecx,esi,edi .
|
||||
--------------------------------------------------------------------------------------------
|
||||
Ф 68.14 для приложений: ;это тот же GetEvent, но с обёрткой.
|
||||
Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
|
||||
замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
|
||||
копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
|
||||
Принимает:
|
||||
eax - 68 - номер функции
|
||||
ebx - 14 - номер подфункции
|
||||
ecx - указатель на буфер для информации (размер 6*dword)
|
||||
Возвращает:
|
||||
буфер, на который указывает ecx, содержит следующую информацию:
|
||||
+0: (EVENT.code) dword: идентификатор последующих данных сигнала
|
||||
+4: (EVENT.data, поле формально не определено) данные принятого
|
||||
сигнала (5*dword), формат которых определяется первым dword-ом.
|
||||
Портит:
|
||||
eax .
|
||||
---------------------------------------------------------------------------------------------
|
@ -34,7 +34,7 @@
|
||||
вызов функции с такими Y игнорируется
|
||||
* RR, GG, BB = соответственно красная, зеленая, синяя
|
||||
составляющие цвета рабочей области окна
|
||||
(игнорируется для стиля Y=2)
|
||||
(игнорируется для стиля Y=1)
|
||||
* X = DCBA (биты)
|
||||
* A = 1 - у окна есть заголовок; для стилей Y=3,4 адрес строки
|
||||
заголовка задаётся в edi, для прочих стилей
|
||||
@ -47,7 +47,7 @@
|
||||
игнорируются для стилей Y=1,3:
|
||||
* esi = 0xXYRRGGBB - цвет заголовка
|
||||
* RR, GG, BB определяют сам цвет
|
||||
* Y=0 - обычное окно, Y=1 - неперемещаемое окно
|
||||
* Y=0 - обычное окно, Y=1 - неперемещаемое окно (работает для всех стилей окон)
|
||||
* X определяет градиент заголовка: X=0 - нет градиента,
|
||||
X=8 - обычный градиент,
|
||||
для окон типа II X=4 - негативный градиент
|
||||
@ -372,6 +372,7 @@
|
||||
* бит 1 (маска 2): окно минимизировано в панель задач
|
||||
* бит 2 (маска 4): окно свёрнуто в заголовок
|
||||
* +71 = +0x47: dword: маска событий
|
||||
* +75 = +0x4B: byte: режим ввода с клавиатуры(ASCII = 0; SCAN = 1)
|
||||
Замечания:
|
||||
* Слоты нумеруются с 1.
|
||||
* Возвращаемое значение не есть общее число потоков, поскольку
|
||||
@ -416,7 +417,7 @@
|
||||
положение и размеры этого окна полагаются нулями.
|
||||
* Координаты клиентской области окна берутся относительно окна.
|
||||
* В данный момент используется только часть буфера размером
|
||||
71 = 0x47 байта. Тем не менее рекомендуется использовать буфер
|
||||
76 = 0x4C байта. Тем не менее рекомендуется использовать буфер
|
||||
размером 1 Кб для будущей совместимости, в будущем могут быть
|
||||
добавлены некоторые поля.
|
||||
|
||||
@ -1803,7 +1804,7 @@ dd 1675
|
||||
sysdir_path rb 64
|
||||
Пример:
|
||||
dir_name1 db 'KolibriOS',0
|
||||
rb 64-8
|
||||
rb 64-10
|
||||
dir_path1 db 'HD0/1',0
|
||||
rb 64-6
|
||||
Возвращаемое значение:
|
||||
@ -2027,6 +2028,14 @@ dir_path1 db 'HD0/1',0
|
||||
* eax = 40 - номер функции
|
||||
* ebx = маска: бит i соответствует событию i+1 (см. список событий)
|
||||
(установленный бит разрешает извещение о событии)
|
||||
bit 31: фильтр активности событий мыши
|
||||
bit 31 = 0 - неактивное окно всегда получает события от мыши
|
||||
bit 31 = 1 - неактивное окно не получает события от мыши
|
||||
bit 30: фильтр позиции курсора
|
||||
bit 30 = 0 - окно принимает события мыши, если курсор
|
||||
за пределами окна
|
||||
bit 30 = 1 - окно не принимает события мыши, если курсор
|
||||
за пределами окна
|
||||
Возвращаемое значение:
|
||||
* eax = предыдущее значение маски
|
||||
Замечания:
|
||||
@ -2419,6 +2428,70 @@ dword-значение цвета 0x00RRGGBB
|
||||
* eax = -1 - ошибка (в системе слишком много потоков)
|
||||
* иначе eax = TID - идентификатор потока
|
||||
|
||||
======================================================================
|
||||
====================== Функция 54, подфункция 0 ======================
|
||||
============== Узнать количество слотов в буфере обмена. =============
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 54 - номер функции
|
||||
* ebx = 0 - номер подфункции
|
||||
Возвращаемое значение:
|
||||
* eax = количество слотов в буфере
|
||||
* eax = -1 - отсутствует область главного списка
|
||||
|
||||
======================================================================
|
||||
====================== Функция 54, подфункция 1 ======================
|
||||
================== Считать данные из буфера обмена. ==================
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 54 - номер функции
|
||||
* ebx = 1 - номер подфункции
|
||||
* eсx = номер слота
|
||||
Возвращаемое значение:
|
||||
* eax = если успешно - указатель на область памяти с данными
|
||||
* eax = 1 - ошибка
|
||||
* eax = -1 - отсутствует область главного списка
|
||||
|
||||
======================================================================
|
||||
====================== Функция 54, подфункция 2 ======================
|
||||
================== Записать данные в буфер обмена. ===================
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 54 - номер функции
|
||||
* ebx = 2 - номер подфункции
|
||||
* eсx = количество копируемых байт
|
||||
* edx = указатель на буфер под копируемые данные
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - успешно
|
||||
* eax = 1 - ошибка
|
||||
* eax = -1 - отсутствует область главного списка
|
||||
|
||||
======================================================================
|
||||
====================== Функция 54, подфункция 3 ======================
|
||||
========= Удалить последний слот с данными в буфере обмена ===========
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 54 - номер функции
|
||||
* ebx = 3 - номер подфункции
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - успешно
|
||||
* eax = 1 - ошибка
|
||||
* eax = -1 - отсутствует область главного списка
|
||||
|
||||
======================================================================
|
||||
====================== Функция 54, подфункция 4 ======================
|
||||
=================== Аварийный сброс блокировки буфера ================
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 54 - номер функции
|
||||
* ebx = 4 - номер подфункции
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - успешно
|
||||
* eax = -1 - отсутствует область главного списка или нет блокировки
|
||||
Замечания:
|
||||
* Используется в исключительных случаях, когда зависшее или убитое
|
||||
приложение заблокировало работу с буфером обмена.
|
||||
|
||||
======================================================================
|
||||
====================== Функция 55, подфункция 55 =====================
|
||||
========== Начать проигрывать данные на встроенном спикере. ==========
|
||||
@ -3494,6 +3567,32 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
обработчика исключений, установленного подфункцией 24. При этом
|
||||
номер сигнала соответствует номеру исключения.
|
||||
|
||||
======================================================================
|
||||
= Функция 68, подфункция 26 - освободить страницы памяти ============
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 68 - номер функции
|
||||
* ebx = 26 - номер подфункции
|
||||
* ecx = указатель на блок памяти выделенный подфункцией 12
|
||||
* edx = смещение от начала блока
|
||||
* esi = размер высвобождаемого блока памяти, в байтах
|
||||
Примечания:
|
||||
* функция освобождает страницы с ecx+edx по ecx+edx+esi
|
||||
и устанавливает виртуальную память в зарезервированное состояние.
|
||||
|
||||
======================================================================
|
||||
= Функция 68, подфункция 27 - загрузить файл ===================
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 68 - номер функции
|
||||
* ebx = 27 - номер подфункции
|
||||
* ecx = указатель на ASCIIZ-строку с именем файла
|
||||
Возвращаемое значение:
|
||||
* eax = указатель на загруженный файл или 0
|
||||
* edx = размер загруженного файла или 0
|
||||
Примечания:
|
||||
* функция загружает и, при необходимости, распаковывает файл (kunpack)
|
||||
|
||||
======================================================================
|
||||
======================== Функция 69 - отладка. =======================
|
||||
======================================================================
|
||||
|
@ -33,7 +33,7 @@ Parameters:
|
||||
* other possible values (from 5 up to 15) are reserved,
|
||||
function call with such Y is ignored
|
||||
* RR, GG, BB = accordingly red, green, blue components of a color
|
||||
of the working area of the window (are ignored for style Y=2)
|
||||
of the working area of the window (are ignored for style Y=1)
|
||||
* X = DCBA (bits)
|
||||
* A = 1 - window has caption; for styles Y=3,4 caption string
|
||||
must be passed in edi, for other styles use
|
||||
@ -46,7 +46,7 @@ Parameters:
|
||||
of a type I and II, and ignored for styles Y=1,3:
|
||||
* esi = 0xXYRRGGBB - color of the header
|
||||
* RR, GG, BB define color
|
||||
* Y=0 - usual window, Y=1 - unmovable window
|
||||
* Y=0 - usual window, Y=1 - unmovable window (works for all window styles)
|
||||
* X defines a gradient of header: X=0 - no gradient,
|
||||
X=8 - usual gradient,
|
||||
for windows of a type II X=4 - negative gradient
|
||||
@ -367,6 +367,7 @@ Returned value:
|
||||
* bit 1 (mask 2): window is minimized to panel
|
||||
* bit 2 (mask 4): window is rolled up
|
||||
* +71 = +0x47: dword: event mask
|
||||
* +75 = +0x4B: byte: keyboard mode(ASCII = 0; SCAN = 1)
|
||||
Remarks:
|
||||
* Slots are numbered starting from 1.
|
||||
* Returned value is not a total number of threads, because there
|
||||
@ -411,7 +412,7 @@ Remarks:
|
||||
of its window are considered to be zero.
|
||||
* Coordinates of the client area are relative to the window.
|
||||
* At the moment only the part of the buffer by a size
|
||||
71 = 0x37 bytes is used. Nevertheless it is recommended to use
|
||||
76 = 0x4C bytes is used. Nevertheless it is recommended to use
|
||||
1-Kb buffer for the future compatibility, in the future
|
||||
some fields can be added.
|
||||
|
||||
@ -1785,7 +1786,7 @@ Parameters:
|
||||
sysdir_path rb 64
|
||||
For example:
|
||||
dir_name1 db 'KolibriOS',0
|
||||
rb 64-8
|
||||
rb 64-10
|
||||
dir_path1 db 'HD0/1',0
|
||||
rb 64-6
|
||||
Returned value:
|
||||
@ -2010,7 +2011,7 @@ Parameters:
|
||||
* eax = 40 - function number
|
||||
* ebx = mask: bit i corresponds to event i+1 (see list of events)
|
||||
(set bit permits notice on event)
|
||||
bit 31: active/inactive filter
|
||||
bit 31: mouse active/inactive filter
|
||||
bit 31 = 0 - inactive window receive mouse events
|
||||
bit 31 = 1 - inactive window does not receive mouse events
|
||||
bit 30: cursor position filter
|
||||
@ -2410,6 +2411,70 @@ Returned value:
|
||||
* otherwise eax = TID - thread identifier
|
||||
</UL>
|
||||
|
||||
======================================================================
|
||||
==================== Function 54, subfunction 0 ======================
|
||||
============== Get the number of slots in the clipboard. =============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 54 - function number
|
||||
* ebx = 0 - subfunction number
|
||||
Returned value:
|
||||
* eax = slots in the clipboard
|
||||
* eax = -1 - main list area not found
|
||||
|
||||
======================================================================
|
||||
==================== Function 54, subfunction 1 ======================
|
||||
================= Read the data from the clipboard. ==================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 54 - function number
|
||||
* ebx = 1 - subfunction number
|
||||
* eсx = slot number
|
||||
Returned value:
|
||||
* eax = if successful - pointer to a memory with data
|
||||
* eax = 1 - error
|
||||
* eax = -1 - main list area not found
|
||||
|
||||
======================================================================
|
||||
==================== Function 54, subfunction 2 ======================
|
||||
================= Write the data to the clipboard. ===================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 54 - function number
|
||||
* ebx = 2 - subfunction number
|
||||
* eсx = the number of bytes to be copied
|
||||
* edx = a pointer to a buffer for data to be copied
|
||||
Returned value:
|
||||
* eax = 0 - success
|
||||
* eax = 1 - error
|
||||
* eax = -1 - main list area not found
|
||||
|
||||
======================================================================
|
||||
===================== Function 54, subfunction 3 =====================
|
||||
================ Delete the last slot in the clipboard ===============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 54 - function number
|
||||
* ebx = 3 - subfunction number
|
||||
Returned value:
|
||||
* eax = 0 - success
|
||||
* eax = 1 - error
|
||||
* eax = -1 - main list area not found
|
||||
|
||||
======================================================================
|
||||
===================== Function 54, subfunction 4 =====================
|
||||
===================== Alarm reset the lock buffer ====================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 54 - function number
|
||||
* ebx = 4 - subfunction number
|
||||
Returned value:
|
||||
* eax = 0 - success
|
||||
* eax = -1 - main list area not found or no blocking
|
||||
Remarks:
|
||||
* Used in exceptional cases, where no responsible or killed
|
||||
application blocked the clipboard operations.
|
||||
|
||||
======================================================================
|
||||
Function 55, subfunction 55 - begin to play data on built-in speaker.
|
||||
======================================================================
|
||||
@ -3953,7 +4018,7 @@ Format of the information structure:
|
||||
* +0: dword: 2 = subfunction number
|
||||
* +4: dword: 0 (reserved)
|
||||
* +8: dword: 0 (reserved)
|
||||
* +12 = +0xC: dword: number of bytes to read
|
||||
* +12 = +0xC: dword: number of bytes to write
|
||||
* +16 = +0x10: dword: pointer to data
|
||||
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
|
||||
given in the general description
|
||||
|
249
kernel/branches/Kolibri-acpi/docs/usbapi_ru.txt
Normal file
249
kernel/branches/Kolibri-acpi/docs/usbapi_ru.txt
Normal file
@ -0,0 +1,249 @@
|
||||
Когда ядро обнаруживает подключенное устройство USB, оно настраивает его
|
||||
согласно USB-протокола - SET_ADDRESS + SET_CONFIGURATION. Всегда
|
||||
устанавливается первая конфигурация. Ядро также читает дескриптор
|
||||
устройства, чтобы показать некоторую информацию, читает и анализирует
|
||||
дескриптор конфигурации. Для каждого интерфейса ядро будет искать класс этого
|
||||
интерфейса и попытается загрузить соответствующий драйвер COFF. В настоящее
|
||||
время соответствие кодов классов и имен драйверов жестко прописано в коде ядра
|
||||
и выглядит следующим образом:
|
||||
3 = usbhid.obj,
|
||||
7 = usbprint.obj,
|
||||
8 = usbstor.obj,
|
||||
9 = поддерживаются самим ядром,
|
||||
другие = usbother.obj.
|
||||
|
||||
Драйвер должен быть стандартным драйвером в формате COFF, экспортирующим
|
||||
процедуру под названием "START" и переменную "version". Загрузчик вызывает
|
||||
процедуру "START" как STDCALL с одним параметром DRV_ENTRY = 1. При завершении
|
||||
работы системы, если инициализация драйвера была успешна, "START" процедуру
|
||||
также вызывает код остановки системы с одним параметром DRV_EXIT = -1.
|
||||
|
||||
Драйвер должен зарегистрировать себя в качестве драйвера USB в процедуре
|
||||
"START". Это делается путем вызова экспортируемой ядром функции RegUSBDriver и
|
||||
возврата её результата в качестве результата "START" процедуры.
|
||||
|
||||
void* __stdcall RegUSBDriver(
|
||||
const char* name,
|
||||
void* handler,
|
||||
const USBFUNC* usbfunc
|
||||
);
|
||||
|
||||
Параметр 'name' должен совпадать с именем драйвера, например "usbhid" для
|
||||
usbhid.obj.
|
||||
|
||||
Параметр 'handler' является необязательным. Если он не NULL, то он должен
|
||||
указывать на стандартный обработчик IOCTL интерфейса, как в обычном (не-USB)
|
||||
драйвере.
|
||||
|
||||
Параметр "Usbfunc" представляет собой указатель на следующую структуру:
|
||||
|
||||
struc USBFUNC
|
||||
{
|
||||
.strucsize dd ? ; размер структуры, включая это поле
|
||||
.add_device dd ? ; указатель на AddDevice процедуру в драйвере
|
||||
; (необходимо)
|
||||
.device_disconnect dd ? ; указатель на DeviceDisconnected процедуру в драйвере
|
||||
; опционально, может быть NULL
|
||||
; В будущем могут быть добавлены другие функции
|
||||
}
|
||||
|
||||
Драйвер ДОЛЖЕН реализовать функцию:
|
||||
|
||||
void* __stdcall AddDevice(
|
||||
void* pipe0,
|
||||
void* configdescr,
|
||||
void* interfacedescr
|
||||
);
|
||||
|
||||
Параметр "Pipe0" - хэндл контрольного канала для нулевой конечной точки
|
||||
устройства. Он может быть использован в качестве аргумента для
|
||||
USBControlTransferAsync (см. далее).
|
||||
|
||||
Параметр 'configdescr' указывает на дескриптор конфигурации и все связанные с
|
||||
ним данные, представленные так, как их возвращает запрос GET_DESCRIPTOR.
|
||||
Полный размер данных содержится в поле Length самого дескриптора.
|
||||
(см. USB2.0 spec.)
|
||||
|
||||
Параметр 'interfacedescr' указывает на дескриптор интерфейса инициализируемого
|
||||
в данный момент. Это указатель на данные находящиеся внутри структуры
|
||||
"configdescr". (Помним, что структура INTERFACE_DESCRIPTOR, находится внутри
|
||||
структуры CONFIGURATION_DESCRIPTOR. См. USB2.0 Spec.) Обратите внимание, что
|
||||
одно устройство может реализовывать много интерфейсов и AddDevice может быть
|
||||
вызвана несколько раз с одним "configdescr" но разными "interfacedescr".
|
||||
|
||||
Возвращенное значение NULL показывает, что инициализация не была успешной.
|
||||
Любое другое значение означает инициализацию устройства. Ядро не делает попыток
|
||||
как-то интерпретировать это значение. Это может быть, например, указатель на
|
||||
внутренние данные драйвера в памяти, выделенной с помощью Kmalloc или индексом
|
||||
в какой-то своей таблице. (Помните, что Kmalloc() НЕ stdcall-функция! Она
|
||||
портит регистр ebx!)
|
||||
|
||||
Драйвер МОЖЕТ реализовать функцию:
|
||||
|
||||
void __stdcall DeviceDisconnected(
|
||||
void* devicedata
|
||||
);
|
||||
|
||||
Если данная функция реализована, то ядро вызывает её, когда устройство
|
||||
отключено, посылая ей в качестве параметра "devicedata" то, что было возвращено
|
||||
ему функцией "AddDevice" при старте драйвера.
|
||||
|
||||
Драйвер может использовать следующие функции экспортируемые ядром:
|
||||
|
||||
void* __stdcall USBOpenPipe(
|
||||
void* pipe0,
|
||||
int endpoint,
|
||||
int maxpacketsize,
|
||||
int type,
|
||||
int interval
|
||||
);
|
||||
|
||||
Параметр "Pipe0" - хэндл контрольного канала для нулевой конечной точки
|
||||
устройства. Используется для идентификации устройства.
|
||||
|
||||
Параметр "endpoint" номер конечной точки USB. Младшие 4 бита, собственно, номер
|
||||
точки, а бит 7 имеет следующее значение: 0 - для OUT точки, 1 - для IN точки.
|
||||
Остальные биты должны быть равны нулю.
|
||||
|
||||
Параметр "maxpacketsize" устанавливает максимальный размер пакета для канала.
|
||||
|
||||
Параметр "type" устанавливает тип передачи для конечной точки, как это прописано
|
||||
в USB спецификации:
|
||||
|
||||
0 = control,
|
||||
1 = isochronous (сейчас не поддерживается),
|
||||
2 = bulk,
|
||||
3 = interrupt.
|
||||
|
||||
Параметр "interval" игнорируется для control и bulk передач. Для конечных точек
|
||||
по прерываниям устанавливает периодичность опроса в миллисекундах.
|
||||
|
||||
Функция возвращает хэндл канала при успешном его открытии либо NULL при ошибке.
|
||||
Хэндл канала обращается в NULL когда:
|
||||
а) канал будет явно закрыт функцией USBClosePipe (см. ниже);
|
||||
б) была выполнена предоставленная драйвером функция "DeviceDisconnected".
|
||||
|
||||
void __stdcall USBClosePipe(
|
||||
void* pipe
|
||||
);
|
||||
|
||||
Освобождает все ресурсы, связанные с выбранным каналом. Единственный параметр -
|
||||
указатель на хэндл, который был возвращен функцией USBOpenPipe при открытии
|
||||
канала. Когда устройство отключается, все связанные с ним каналы закрываются
|
||||
ядром; нет необходимости в самостоятельном вызове этой функции.
|
||||
|
||||
void* __stdcall USBNormalTransferAsync(
|
||||
void* pipe,
|
||||
void* buffer,
|
||||
int size,
|
||||
void* callback,
|
||||
void* calldata,
|
||||
int flags
|
||||
);
|
||||
void* __stdcall USBControlTransferAsync(
|
||||
void* pipe,
|
||||
void* setup,
|
||||
void* buffer,
|
||||
int size,
|
||||
void* callback,
|
||||
void* calldata,
|
||||
int flags
|
||||
);
|
||||
|
||||
Первая функция ставит в очередь bulk или interrupt передачу для выбранного
|
||||
канала. Тип и направление передачи фиксированы для bulk и interrupt типов
|
||||
конечных точек, как это было выбрано функцией USBOpenPipe.
|
||||
Вторая функция ставит в очередь control передачу для выбранного канала.
|
||||
Направление этой передачи определяется битом 7 байта 0 пакета "setup"
|
||||
(0 - для OUT, 1 - для IN передачи). Эта функция возвращает управление немедленно.
|
||||
По окончании передачи вызывается функция "callback" заданная как аргумент
|
||||
USB______TransferAsync.
|
||||
|
||||
Параметр "pipe" - хэндл, возвращенный функцией USBOpenPipe.
|
||||
|
||||
Параметр 'setup' функции USBControlTransferAsync указывает на 8-байтный
|
||||
конфигурационный пакет (см. USB2.0 Spec).
|
||||
|
||||
Параметр "buffer" - это указатель на буфер. Для IN передач он будет заполнен
|
||||
принятыми данными. Для OUT передач он должен быть заполнен данными, которые мы
|
||||
хотим передать. Указатель может быть NULL для пустых передач, либо для передач
|
||||
control, если дополнительных данных не требуется.
|
||||
|
||||
Параметр "size" - это размер данных для передачи. Он может быть равен 0 для
|
||||
пустых передач, либо для передач control, если дополнительных данных не требуется.
|
||||
|
||||
Параметр "callback" - это указатель на функцию, которая будет вызвана по
|
||||
окончании передачи.
|
||||
|
||||
Параметр "calldata" будет передан функции "callback" вызываемой по окончании
|
||||
передачи. Например, он может быть NULL или указывать на данные устройства или
|
||||
указывать на данные используемые как дополнительные параметры, передаваемые от
|
||||
вызывающей USB_____TransferAsync функции в callback функцию.
|
||||
|
||||
Другие данные, связанные с передачей, могут быть помещены до буфера (по смещению)
|
||||
или после него. Они могут быть использованы из callback-функции, при необходимости.
|
||||
|
||||
Параметр "flags" - это битовое поле. Бит 0 игнорируется для OUT передач. Для IN
|
||||
передач он означает, может ли устройство передать меньше данных (бит=1), чем
|
||||
определено в "size" или нет (бит=0). Остальные биты не используются и должны
|
||||
быть равны 0.
|
||||
|
||||
Возвращаемое функциями значение равно NULL в случае ошибки и не NULL если
|
||||
передача успешно поставлена в очередь. Если происходит ошибка при передаче, то
|
||||
callback функция будет об этом оповещена.
|
||||
|
||||
void __stdcall CallbackFunction(
|
||||
void* pipe,
|
||||
int status,
|
||||
void* buffer,
|
||||
int length,
|
||||
void* calldata
|
||||
);
|
||||
|
||||
Параметры 'pipe', 'buffer', 'calldata' значат то же, что и для
|
||||
USB_____TransferAsync.
|
||||
|
||||
Параметр "length" это счетчик переданных байт. Для control передач он отражает
|
||||
дополнительные 8 байт этапа SETUP. Т.е. 0 означает ошибку на этапе SETUP, а
|
||||
"size"+8 успешную передачу.
|
||||
|
||||
Параметр "status" не равен 0 в случае ошибки:
|
||||
USB_STATUS_OK = 0 ; без ошибок
|
||||
USB_STATUS_CRC = 1 ; ошибка контрольной суммы
|
||||
USB_STATUS_BITSTUFF = 2 ; ошибка инверсии битов (bitstuffing)
|
||||
USB_STATUS_TOGGLE = 3 ; data toggle mismatch
|
||||
; (Нарушение последовательности DAT0/DAT1)
|
||||
USB_STATUS_STALL = 4 ; устройство возвратило STALL статус (остановлено)
|
||||
USB_STATUS_NORESPONSE = 5 ; устройство не отвечает
|
||||
USB_STATUS_PIDCHECK = 6 ; ошибка в поле PacketID (PID)
|
||||
USB_STATUS_WRONGPID = 7 ; неожидаемое PacketID (PID) значение
|
||||
USB_STATUS_OVERRUN = 8 ; слишком много данных от конечной точки
|
||||
USB_STATUS_UNDERRUN = 9 ; слишком мало данных от конечной точки
|
||||
USB_STATUS_BUFOVERRUN = 12 ; переполнение внутреннего буфера контроллера
|
||||
; возможна только для изохронных передач
|
||||
USB_STATUS_BUFUNDERRUN = 13 ; опустошение внутреннего буфера контроллера
|
||||
; возможна только для изохронных передач
|
||||
USB_STATUS_CLOSED = 16 ; канал закрыт либо через ClosePipe, либо в
|
||||
; результате отключения устройства
|
||||
|
||||
Если несколько передач были поставлены в очередь для одного канала, то callback
|
||||
функции для них будут вызываться в порядке постановки передач в очередь.
|
||||
Если канал был закрыт ввиду USBClosePipe или отключения устройства, то callback
|
||||
функции (если очередь передач не пуста) получат USB_STATUS_CLOSED.
|
||||
Вызов DeviceDisconnected() последует после отработки всех оставшихся в очереди
|
||||
callback функций.
|
||||
|
||||
void* __stdcall USBGetParam(void* pipe0, int param);
|
||||
|
||||
Возвращает указатель на некоторые параметры устройства запомненные ядром при
|
||||
инициализации первой конфигурации. Не передает ничего устройству по шине.
|
||||
|
||||
pipe0 - хэндл контрольного канала для нулевой конечной точки устройства.
|
||||
|
||||
param - выбор возвращаемого параметра:
|
||||
0 - возвратить указатель на дескриптор устройства;
|
||||
1 - возвратить указатель на дескриптор конфигурации;
|
||||
2 - возвратить режим шины устройства:
|
||||
USB_SPEED_FS = 0 ; full-speed
|
||||
USB_SPEED_LS = 1 ; low-speed
|
||||
USB_SPEED_HS = 2 ; high-speed
|
@ -60,6 +60,7 @@ kernel_export \
|
||||
CreateRingBuffer,\
|
||||
\
|
||||
GetPid,\
|
||||
CreateThread,\
|
||||
CreateObject,\
|
||||
DestroyObject,\
|
||||
CreateEvent,\
|
||||
|
@ -1002,13 +1002,12 @@ proc inquiry_callback
|
||||
; to allow the USB thread to continue working and handling those requests.
|
||||
; 4. Thus, create a temporary kernel thread which would do it.
|
||||
mov edx, [esp+8]
|
||||
push ebx ecx
|
||||
movi eax, 51
|
||||
push ebx ecx esi edi
|
||||
movi ebx, 1
|
||||
mov ecx, new_disk_thread
|
||||
; edx = parameter
|
||||
int 0x40
|
||||
pop ecx ebx
|
||||
call CreateThread
|
||||
pop edi esi ecx ebx
|
||||
cmp eax, -1
|
||||
jnz .nothing
|
||||
; on error, reverse step 3
|
||||
|
@ -97,6 +97,12 @@ macro cp866 [arg]
|
||||
end while
|
||||
}
|
||||
|
||||
struc cp866 [arg]
|
||||
{
|
||||
common
|
||||
cp866 arg
|
||||
}
|
||||
|
||||
; Latin-1 encoding
|
||||
; 0x00-0xFF - trivial map
|
||||
macro latin1 [arg]
|
||||
@ -117,6 +123,12 @@ macro latin1 [arg]
|
||||
end while
|
||||
}
|
||||
|
||||
struc latin1 [arg]
|
||||
{
|
||||
common
|
||||
latin1 arg
|
||||
}
|
||||
|
||||
; CP850 encoding
|
||||
macro cp850 [arg]
|
||||
{ local offs, char, graph
|
||||
@ -147,3 +159,9 @@ macro cp850 [arg]
|
||||
end if
|
||||
end while
|
||||
}
|
||||
|
||||
struc cp850 [arg]
|
||||
{
|
||||
common
|
||||
cp850 arg
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
409
kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc
Normal file
409
kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc
Normal file
@ -0,0 +1,409 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Contains ext2 block handling code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Write ext2 block from memory to disk.
|
||||
; Input: eax = i_block (block number in ext2 terms);
|
||||
; ebx = buffer address
|
||||
; ebp = pointer to EXTFS
|
||||
; Output: eax = error code (0 implies no error)
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_write:
|
||||
push edx ebx ecx
|
||||
|
||||
mov edx, fs_write32_sys
|
||||
jmp ext2_block_modify
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Read ext2 block from disk to memory.
|
||||
; Input: eax = i_block (block number in ext2 terms);
|
||||
; ebx = address of where to read block
|
||||
; ebp = pointer to EXTFS
|
||||
; Output: eax = error code (0 implies no error)
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_read:
|
||||
push edx ebx ecx
|
||||
|
||||
mov edx, fs_read32_sys
|
||||
jmp ext2_block_modify
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Modify ext2 block.
|
||||
; Input: eax = i_block (block number in ext2 terms);
|
||||
; ebx = I/O buffer address;
|
||||
; edx = fs_read/write32_sys
|
||||
; ebp = pointer to EXTFS
|
||||
; edx, ebx, ecx on stack.
|
||||
; Output: eax = error code (0 implies no error)
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_modify:
|
||||
; Get block number in hard-disk terms in eax.
|
||||
mov ecx, [ebp + EXTFS.log_block_size]
|
||||
shl eax, cl
|
||||
mov ecx, eax
|
||||
push [ebp + EXTFS.count_block_in_block]
|
||||
|
||||
@@:
|
||||
mov eax, ecx
|
||||
call edx
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
inc ecx
|
||||
add ebx, 512
|
||||
dec dword[esp]
|
||||
jnz @B
|
||||
|
||||
xor eax, eax
|
||||
@@:
|
||||
pop ecx
|
||||
pop ecx ebx edx
|
||||
ret
|
||||
|
||||
.fail:
|
||||
mov eax, ERROR_DEVICE
|
||||
jmp @B
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Zeroes a block.
|
||||
; Input: ebx = block ID.
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: eax = error code.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_zero:
|
||||
push ebx
|
||||
|
||||
mov eax, ebx
|
||||
mov ebx, [ebp + EXTFS.ext2_temp_block]
|
||||
|
||||
call ext2_block_read
|
||||
test eax, eax
|
||||
jnz .return
|
||||
|
||||
push edi ecx
|
||||
xor eax, eax
|
||||
mov ecx, [ebp + EXTFS.block_size]
|
||||
mov edi, [ebp + EXTFS.ext2_temp_block]
|
||||
rep stosb
|
||||
pop ecx edi
|
||||
|
||||
mov eax, [esp]
|
||||
call ext2_block_write
|
||||
|
||||
.return:
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Allocates a block.
|
||||
; Input: eax = inode ID for "preference".
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: Block marked as set in block group.
|
||||
; eax = error code.
|
||||
; ebx = block ID.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_alloc:
|
||||
push [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_count]
|
||||
push EXT2_BLOCK_GROUP_DESC.free_blocks_count
|
||||
push [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_per_group]
|
||||
|
||||
lea ebx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_block_count]
|
||||
push ebx
|
||||
|
||||
push ext2_bg_read_blk_bitmap
|
||||
|
||||
call ext2_resource_alloc
|
||||
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Zero-allocates a block.
|
||||
; Input: eax = inode ID for "preference".
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: Block marked as set in block group.
|
||||
; eax = error code.
|
||||
; ebx = block ID.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_calloc:
|
||||
call ext2_block_alloc
|
||||
test eax, eax
|
||||
jnz @F
|
||||
|
||||
call ext2_block_zero
|
||||
@@:
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Frees a block.
|
||||
; Input: eax = block ID.
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: Block marked as free in block group.
|
||||
; eax = error code.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_free:
|
||||
push edi ecx
|
||||
|
||||
mov edi, ext2_bg_read_blk_bitmap
|
||||
xor ecx, ecx
|
||||
call ext2_resource_free
|
||||
|
||||
pop ecx edi
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Find parent from file path in block.
|
||||
; Input: esi = file path.
|
||||
; ebx = pointer to directory block.
|
||||
; ebp = pointer to EXTFS structure.
|
||||
; Output: esi = name without parent, or not changed.
|
||||
; ebx = directory record matched.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_find_parent:
|
||||
sub esp, 256 ; Space for EXT2 filename.
|
||||
mov edx, ebx
|
||||
add edx, [ebp + EXTFS.block_size] ; Save block end.
|
||||
|
||||
.start_rec:
|
||||
cmp [ebx + EXT2_DIR_STRUC.inode], 0
|
||||
jz .next_rec
|
||||
|
||||
mov edi, esp
|
||||
push esi
|
||||
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
|
||||
lea esi, [ebx + EXT2_DIR_STRUC.name]
|
||||
call utf8_to_cp866
|
||||
|
||||
mov ecx, edi
|
||||
lea edi, [esp + 4]
|
||||
sub ecx, edi ; Number of bytes in resulting string.
|
||||
|
||||
mov esi, [esp]
|
||||
|
||||
; esi: original file path.
|
||||
; edi: converted string stored on stack.
|
||||
; ecx: size of converted string.
|
||||
@@:
|
||||
; If no bytes left in resulting string, test it.
|
||||
jecxz .test_find
|
||||
dec ecx
|
||||
|
||||
lodsb
|
||||
call char_toupper
|
||||
|
||||
mov ah, [edi]
|
||||
inc edi
|
||||
xchg al, ah
|
||||
call char_toupper
|
||||
|
||||
; If both are same, check next byte.
|
||||
cmp al, ah
|
||||
je @B
|
||||
@@: ; Doesn't match.
|
||||
pop esi
|
||||
|
||||
.next_rec:
|
||||
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
|
||||
add ebx, eax ; Go to next record.
|
||||
cmp ebx, edx ; Check if this is the end.
|
||||
jb .start_rec
|
||||
|
||||
add esp, 256
|
||||
ret
|
||||
|
||||
.test_find:
|
||||
cmp byte [esi], 0
|
||||
je .ret ; The end reached.
|
||||
cmp byte [esi], '/' ; If not end of directory name, not matched.
|
||||
jne @B
|
||||
inc esi
|
||||
|
||||
.ret:
|
||||
add esp, 256 + 4
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Finds free space in a directory block, modifying last entry appropriately.
|
||||
; Input: ebp = pointer to EXTFS.
|
||||
; ecx = size of free space required.
|
||||
; [EXTFS.ext2_temp_block] contains the block relevant.
|
||||
; Output: edi = free entry.
|
||||
; rec_len of free entry is set.
|
||||
; eax = error code; if the block doesn't link to the next one, this is 0x00000001 on failure.
|
||||
; ; else, 0xFFFFFFFF.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_block_find_fspace:
|
||||
push ebx edx
|
||||
|
||||
mov edi, [ebp + EXTFS.ext2_temp_block]
|
||||
mov edx, edi
|
||||
add edx, [ebp + EXTFS.block_size]
|
||||
|
||||
@@:
|
||||
movzx eax, [edi + EXT2_DIR_STRUC.rec_len]
|
||||
test eax, eax
|
||||
jz .zero_len
|
||||
|
||||
cmp [edi + EXT2_DIR_STRUC.inode], 0
|
||||
je .unused_entry
|
||||
|
||||
; It's a used entry, so see if we can fit it between current one and next.
|
||||
; Subtract the size used by the name and the structure from rec_len.
|
||||
movzx ebx, [edi + EXT2_DIR_STRUC.name_len]
|
||||
add ebx, 8 + 3
|
||||
and ebx, 0xfffffffc ; Align it on the next 4-byte boundary.
|
||||
|
||||
sub eax, ebx
|
||||
add edi, ebx
|
||||
cmp eax, ecx
|
||||
jb .next_iter
|
||||
|
||||
sub edi, ebx
|
||||
mov [edi + EXT2_DIR_STRUC.rec_len], bx ; Make previous entry point to us.
|
||||
add edi, ebx
|
||||
|
||||
mov [edi + EXT2_DIR_STRUC.rec_len], ax ; Make current entry point to next one.
|
||||
jmp .found
|
||||
|
||||
.unused_entry:
|
||||
; It's an unused inode.
|
||||
cmp eax, ecx
|
||||
jge .found
|
||||
|
||||
.next_iter:
|
||||
add edi, eax
|
||||
cmp edi, edx
|
||||
jb @B
|
||||
|
||||
.not_found:
|
||||
xor eax, eax
|
||||
not eax
|
||||
jmp .ret
|
||||
|
||||
; Zero length entry means we have the rest of the block for us.
|
||||
.zero_len:
|
||||
mov eax, edx
|
||||
sub eax, edi
|
||||
|
||||
; Point to next block.
|
||||
mov [edi + EXT2_DIR_STRUC.rec_len], ax
|
||||
|
||||
cmp eax, ecx
|
||||
jge .fits
|
||||
|
||||
mov [edi + EXT2_DIR_STRUC.inode], 0
|
||||
|
||||
; It doesn't fit, but the block doesn't link to the next block.
|
||||
xor eax, eax
|
||||
inc eax
|
||||
jmp .ret
|
||||
|
||||
.fits:
|
||||
mov [edi + EXT2_DIR_STRUC.rec_len], cx
|
||||
|
||||
.found:
|
||||
xor eax, eax
|
||||
|
||||
.ret:
|
||||
pop edx ebx
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Gets the block group's descriptor.
|
||||
; Input: eax = block group.
|
||||
; Output: eax = if zero, error; else, points to block group descriptor.
|
||||
; [EXTFS.ext2_temp_block] contains relevant block.
|
||||
; ebp = pointer to EXTFS.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_bg_read_desc:
|
||||
push edx ebx
|
||||
mov edx, 32
|
||||
mul edx ; Get index of descriptor in global_desc_table.
|
||||
|
||||
; eax: block group descriptor offset relative to global descriptor table start
|
||||
; Find the block this block descriptor is in.
|
||||
div [ebp + EXTFS.block_size]
|
||||
add eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block]
|
||||
inc eax
|
||||
mov ebx, [ebp + EXTFS.ext2_temp_block]
|
||||
call ext2_block_read
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
add ebx, edx ; edx: local index of descriptor inside block
|
||||
mov eax, ebx
|
||||
|
||||
.return:
|
||||
pop ebx edx
|
||||
ret
|
||||
|
||||
.fail:
|
||||
xor eax, eax
|
||||
jmp .return
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Writes a block group's descriptor.
|
||||
; Input: eax = block group.
|
||||
; [EXTFS.ext2_temp_data] contains the block relevant.
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: eax = error code.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_bg_write_desc:
|
||||
push edx ebx
|
||||
mov edx, 32
|
||||
mul edx ; Get index of descriptor in global_desc_table.
|
||||
|
||||
; eax: block group descriptor offset relative to global descriptor table start
|
||||
; Find the block this block descriptor is in.
|
||||
div [ebp + EXTFS.block_size]
|
||||
add eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block]
|
||||
inc eax
|
||||
mov ebx, [ebp + EXTFS.ext2_temp_block]
|
||||
call ext2_block_write
|
||||
|
||||
.return:
|
||||
pop ebx edx
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Gets the block group's block bitmap.
|
||||
; Input: eax = block group.
|
||||
; Output: eax = if zero, error; else, points to block group descriptor.
|
||||
; ebx = block bitmap's block (hard disk).
|
||||
;---------------------------------------------------------------------
|
||||
ext2_bg_read_blk_bitmap:
|
||||
push ecx
|
||||
|
||||
call ext2_bg_read_desc
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [eax + EXT2_BLOCK_GROUP_DESC.block_bitmap] ; Block number of block group bitmap - in ext2 terms.
|
||||
|
||||
.return:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
.fail:
|
||||
xor eax, eax
|
||||
jmp .return
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Updates superblock, plus backups.
|
||||
; Input: ebp = pointer to EXTFS.
|
||||
; Output: eax = error code.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_sb_update:
|
||||
push ebx
|
||||
|
||||
mov eax, 2
|
||||
lea ebx, [ebp + EXTFS.superblock]
|
||||
call fs_write32_sys
|
||||
|
||||
pop ebx
|
||||
ret
|
1718
kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm
Normal file
1718
kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm
Normal file
File diff suppressed because it is too large
Load Diff
670
kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc
Normal file
670
kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc
Normal file
@ -0,0 +1,670 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Contains ext2 structures, and macros. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Future jobs for driver, in order of preference:
|
||||
; * clean up existing extents support.
|
||||
; * add b-tree directories support.
|
||||
; * add long file support.
|
||||
; * add journal support.
|
||||
; * add minor features that come with ext3/4.
|
||||
|
||||
; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course).
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Clears a bit.
|
||||
; Input: eax = index into bitmap.
|
||||
; [EXTFS.ext2_save_block] = address of bitmap.
|
||||
; ebp = address of EXTFS.
|
||||
; Output: Bit cleared.
|
||||
; eax = non-zero, if already cleared.
|
||||
;---------------------------------------------------------------------
|
||||
bitmap_clear_bit:
|
||||
push ebx ecx edx
|
||||
|
||||
xor edx, edx
|
||||
mov ecx, 8
|
||||
div ecx
|
||||
|
||||
add eax, [ebp + EXTFS.ext2_save_block]
|
||||
|
||||
; Get the mask.
|
||||
mov ebx, 1
|
||||
mov ecx, edx
|
||||
shl ebx, cl
|
||||
|
||||
test [eax], ebx
|
||||
jz .cleared
|
||||
|
||||
not ebx
|
||||
and [eax], ebx
|
||||
|
||||
xor eax, eax
|
||||
.return:
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
|
||||
; Already cleared.
|
||||
.cleared:
|
||||
xor eax, eax
|
||||
not eax
|
||||
jmp .return
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Finds free bit in the bitmap.
|
||||
; Input: ecx = number of bits in the bitmap.
|
||||
; [EXTFS.ext2_save_block] = address of bitmap.
|
||||
; ebp = address of EXTFS.
|
||||
; Output: eax = index of free bit in the bitmap; marked set.
|
||||
; 0xFFFFFFFF if no free bit found.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_find_free_bit:
|
||||
bitmap_find_free_bit:
|
||||
push esi ebx ecx edx
|
||||
mov esi, [ebp + EXTFS.ext2_save_block]
|
||||
|
||||
; Get total DWORDS in eax; total bits in last dword, if any, in edx.
|
||||
xor edx, edx
|
||||
mov eax, ecx
|
||||
mov ecx, 32
|
||||
div ecx
|
||||
|
||||
mov ecx, eax
|
||||
xor eax, eax
|
||||
push edx
|
||||
|
||||
test ecx, ecx
|
||||
jz .last_bits
|
||||
|
||||
; Check in the DWORDS.
|
||||
.dwords:
|
||||
mov ebx, [esi]
|
||||
not ebx
|
||||
|
||||
bsf edx, ebx
|
||||
|
||||
; If 0, then the original value would be 0xFFFFFFFF, hence no free bits.
|
||||
jz @F
|
||||
|
||||
; We found the value. Let's return with it.
|
||||
add esp, 4
|
||||
|
||||
add eax, edx
|
||||
jmp .return
|
||||
|
||||
@@:
|
||||
add esi, 4
|
||||
add eax, 32
|
||||
loop .dwords
|
||||
|
||||
.last_bits:
|
||||
; Check in the last few bits.
|
||||
pop ecx
|
||||
test ecx, ecx
|
||||
jz @F
|
||||
|
||||
mov ebx, [esi]
|
||||
not ebx
|
||||
bsf ebx, edx
|
||||
|
||||
; If 0, no free bits.
|
||||
jz @F
|
||||
|
||||
; If free bit is greater than the last known bit, then error.
|
||||
cmp edx, ecx
|
||||
jg @F
|
||||
|
||||
add eax, edx
|
||||
jmp .return
|
||||
|
||||
@@:
|
||||
; Didn't find any free bits.
|
||||
xor eax, eax
|
||||
not eax
|
||||
jmp @F
|
||||
|
||||
.return:
|
||||
mov ecx, edx
|
||||
mov edx, 1
|
||||
shl edx, cl
|
||||
or [esi], edx
|
||||
|
||||
@@:
|
||||
pop edx ecx ebx esi
|
||||
ret
|
||||
|
||||
; Recommended move to some kernel-wide string handling code.
|
||||
;---------------------------------------------------------------------
|
||||
; Find the length of a string.
|
||||
; Input: esi = source.
|
||||
; Output: length in ecx
|
||||
;---------------------------------------------------------------------
|
||||
strlen:
|
||||
push eax esi
|
||||
xor ecx, ecx
|
||||
|
||||
@@:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .ret
|
||||
|
||||
inc ecx
|
||||
jmp @B
|
||||
|
||||
.ret:
|
||||
pop esi eax
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Convert UTF-8 string to ASCII-string (codepage 866)
|
||||
; Input: esi = source.
|
||||
; edi = buffer.
|
||||
; ecx = length of source.
|
||||
; Output: destroys eax, esi, edi
|
||||
;---------------------------------------------------------------------
|
||||
utf8_to_cp866:
|
||||
; Check for zero-length string.
|
||||
jecxz .return
|
||||
|
||||
.start:
|
||||
lodsw
|
||||
cmp al, 0x80
|
||||
jb .ascii
|
||||
|
||||
xchg al, ah ; Big-endian.
|
||||
cmp ax, 0xd080
|
||||
jz .yo1
|
||||
|
||||
cmp ax, 0xd191
|
||||
jz .yo2
|
||||
|
||||
cmp ax, 0xd090
|
||||
jb .unk
|
||||
|
||||
cmp ax, 0xd180
|
||||
jb .rus1
|
||||
|
||||
cmp ax, 0xd190
|
||||
jb .rus2
|
||||
|
||||
.unk:
|
||||
mov al, '_'
|
||||
jmp .doit
|
||||
|
||||
.yo1:
|
||||
mov al, 0xf0 ; Ё capital.
|
||||
jmp .doit
|
||||
|
||||
.yo2:
|
||||
mov al, 0xf1 ; ё small.
|
||||
jmp .doit
|
||||
|
||||
.rus1:
|
||||
sub ax, 0xd090 - 0x80
|
||||
jmp .doit
|
||||
|
||||
.rus2:
|
||||
sub ax, 0xd18f - 0xEF
|
||||
|
||||
.doit:
|
||||
stosb
|
||||
sub ecx, 2
|
||||
ja .start
|
||||
ret
|
||||
|
||||
.ascii:
|
||||
stosb
|
||||
dec esi
|
||||
dec ecx
|
||||
jnz .start
|
||||
|
||||
.return:
|
||||
ret
|
||||
|
||||
; Recommended move to some kernel-wide time handling code.
|
||||
|
||||
; Total cumulative seconds till each month.
|
||||
cumulative_seconds_in_month:
|
||||
.january: dd 0 * (60 * 60 * 24)
|
||||
.february: dd 31 * (60 * 60 * 24)
|
||||
.march: dd 59 * (60 * 60 * 24)
|
||||
.april: dd 90 * (60 * 60 * 24)
|
||||
.may: dd 120 * (60 * 60 * 24)
|
||||
.june: dd 151 * (60 * 60 * 24)
|
||||
.july: dd 181 * (60 * 60 * 24)
|
||||
.august: dd 212 * (60 * 60 * 24)
|
||||
.september: dd 243 * (60 * 60 * 24)
|
||||
.october: dd 273 * (60 * 60 * 24)
|
||||
.november: dd 304 * (60 * 60 * 24)
|
||||
.december: dd 334 * (60 * 60 * 24)
|
||||
|
||||
current_bdfe_time:
|
||||
dd 0
|
||||
current_bdfe_date:
|
||||
dd 0
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Stores current unix time.
|
||||
; Input: edi = buffer to output Unix time.
|
||||
;---------------------------------------------------------------------
|
||||
current_unix_time:
|
||||
push eax esi
|
||||
mov esi, current_bdfe_time
|
||||
|
||||
; Just a small observation:
|
||||
; The CMOS is a pretty bad source to get time from. One shouldn't rely on it,
|
||||
; since it messes up the time by tiny bits. Of course, this is all technical,
|
||||
; but one can look it up on the osdev wiki. What is better is to get the time
|
||||
; from CMOS during boot, then update system time using a more accurate timer.
|
||||
; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!.
|
||||
|
||||
; Get time from CMOS.
|
||||
; Seconds.
|
||||
mov al, 0x00
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
mov [esi + 0], al
|
||||
|
||||
; Minute.
|
||||
mov al, 0x02
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
mov [esi + 1], al
|
||||
|
||||
; Hour.
|
||||
mov al, 0x04
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
mov [esi + 2], al
|
||||
|
||||
; Get date.
|
||||
|
||||
; Day.
|
||||
mov al, 0x7
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
mov [esi + 4], al
|
||||
|
||||
; Month.
|
||||
mov al, 0x8
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
mov [esi + 5], al
|
||||
|
||||
; Year.
|
||||
mov al, 0x9
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
call bcd2bin
|
||||
add ax, 2000 ; CMOS only returns last two digits.
|
||||
; Note that everywhere in KolibriOS this is used.
|
||||
; This is hacky, since the RTC can be incorrectly set
|
||||
; to something before 2000.
|
||||
mov [esi + 6], ax
|
||||
|
||||
call bdfe_to_unix_time
|
||||
pop esi eax
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Convert time+date from BDFE to Unix time.
|
||||
; Input: esi = pointer to BDFE time+date.
|
||||
; edi = buffer to output Unix time.
|
||||
;---------------------------------------------------------------------
|
||||
bdfe_to_unix_time:
|
||||
push eax ebx ecx edx
|
||||
mov dword[edi], 0x00000000
|
||||
|
||||
; The minimum representable time is 1901-12-13.
|
||||
cmp word[esi + 6], 1901
|
||||
jb .ret
|
||||
jg .max
|
||||
|
||||
cmp byte[esi + 5], 12
|
||||
jb .ret
|
||||
|
||||
cmp byte[esi + 4], 13
|
||||
jbe .ret
|
||||
jg .convert
|
||||
|
||||
; Check if it is more than the maximum representable time.
|
||||
.max:
|
||||
; The maximum representable time is 2038-01-19.
|
||||
cmp word[esi + 6], 2038
|
||||
jg .ret
|
||||
jb .convert
|
||||
|
||||
cmp byte[esi + 5], 1
|
||||
jg .ret
|
||||
|
||||
cmp byte[esi + 4], 19
|
||||
jge .ret
|
||||
|
||||
; Convert the time.
|
||||
.convert:
|
||||
; Get if current year is leap year in ECX.
|
||||
xor ecx, ecx
|
||||
mov ebx, 4
|
||||
xor edx, edx
|
||||
|
||||
cmp word[esi + 6], 1970
|
||||
jb .negative
|
||||
|
||||
movzx eax, word[esi + 6] ; Year.
|
||||
cmp byte[esi + 5], 3 ; If the month is less than March, than that year doesn't matter.
|
||||
jge @F
|
||||
|
||||
test eax, 3
|
||||
; Not a leap year.
|
||||
jnz @F
|
||||
|
||||
inc ecx
|
||||
@@:
|
||||
; Number of leap years between two years = ((end date - 1)/4) - (1970/4)
|
||||
dec eax
|
||||
div ebx
|
||||
sub eax, 1970/4
|
||||
|
||||
; EAX is the number of leap years.
|
||||
add eax, ecx
|
||||
mov ecx, (60 * 60 * 24) ; Seconds in a day.
|
||||
mul ecx
|
||||
|
||||
; Account for leap years, i.e., one day extra for each.
|
||||
add [edi], eax
|
||||
|
||||
; Get total days in EAX.
|
||||
movzx eax, byte[esi + 4]
|
||||
dec eax
|
||||
mul ecx
|
||||
|
||||
; Account for days.
|
||||
add [edi], eax
|
||||
|
||||
; Account for month.
|
||||
movzx eax, byte[esi + 5]
|
||||
dec eax
|
||||
mov eax, [cumulative_seconds_in_month + (eax * 4)]
|
||||
add [edi], eax
|
||||
|
||||
; Account for year.
|
||||
movzx eax, word[esi + 6]
|
||||
sub eax, 1970
|
||||
mov ecx, (60 * 60 * 24) * 365 ; Seconds in a year.
|
||||
mul ecx
|
||||
add [edi], eax
|
||||
|
||||
; Seconds.
|
||||
movzx eax, byte[esi + 0]
|
||||
add [edi], eax
|
||||
|
||||
; Minutes.
|
||||
movzx eax, byte[esi + 1]
|
||||
mov ecx, 60
|
||||
mul ecx
|
||||
add [edi], eax
|
||||
|
||||
; Hours.
|
||||
movzx eax, byte[esi + 2]
|
||||
mov ecx, (60 * 60)
|
||||
mul ecx
|
||||
add [edi], eax
|
||||
|
||||
; The time wanted is before the epoch; handle it here.
|
||||
.negative:
|
||||
; TODO.
|
||||
|
||||
.ret:
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
|
||||
; Recommended move to some kernel-wide alloc handling code.
|
||||
macro KERNEL_ALLOC store, label
|
||||
{
|
||||
call kernel_alloc
|
||||
mov store, eax
|
||||
test eax, eax
|
||||
jz label
|
||||
}
|
||||
|
||||
macro KERNEL_FREE data, label
|
||||
{
|
||||
cmp data, 0
|
||||
jz label
|
||||
push data
|
||||
call kernel_free
|
||||
}
|
||||
|
||||
struct EXTFS PARTITION
|
||||
lock MUTEX
|
||||
partition_flags dd ?
|
||||
log_block_size dd ?
|
||||
block_size dd ?
|
||||
count_block_in_block dd ?
|
||||
blocks_per_group dd ?
|
||||
global_desc_table dd ?
|
||||
root_inode dd ? ; Pointer to root inode in memory.
|
||||
inode_size dd ?
|
||||
count_pointer_in_block dd ? ; (block_size / 4)
|
||||
count_pointer_in_block_square dd ? ; (block_size / 4)**2
|
||||
ext2_save_block dd ? ; Block for 1 global procedure.
|
||||
ext2_temp_block dd ? ; Block for small procedures.
|
||||
ext2_save_inode dd ? ; inode for global procedures.
|
||||
ext2_temp_inode dd ? ; inode for small procedures.
|
||||
groups_count dd ?
|
||||
superblock rd 1024/4
|
||||
ends
|
||||
|
||||
; EXT2 revisions.
|
||||
EXT2_GOOD_OLD_REV = 0
|
||||
|
||||
; For fs_type.
|
||||
FS_TYPE_UNDEFINED = 0
|
||||
FS_TYPE_EXT = 2
|
||||
|
||||
; Some set inodes.
|
||||
EXT2_BAD_INO = 1
|
||||
EXT2_ROOT_INO = 2
|
||||
EXT2_ACL_IDX_INO = 3
|
||||
EXT2_ACL_DATA_INO = 4
|
||||
EXT2_BOOT_LOADER_INO = 5
|
||||
EXT2_UNDEL_DIR_INO = 6
|
||||
|
||||
; EXT2_SUPER_MAGIC.
|
||||
EXT2_SUPER_MAGIC = 0xEF53
|
||||
EXT2_VALID_FS = 1
|
||||
|
||||
; Flags defining i_mode values.
|
||||
EXT2_S_IFMT = 0xF000 ; Mask for file type.
|
||||
|
||||
EXT2_S_IFREG = 0x8000 ; Regular file.
|
||||
EXT2_S_IFDIR = 0x4000 ; Directory.
|
||||
|
||||
EXT2_S_IRUSR = 0x0100 ; User read
|
||||
EXT2_S_IWUSR = 0x0080 ; User write
|
||||
EXT2_S_IXUSR = 0x0040 ; User execute
|
||||
EXT2_S_IRGRP = 0x0020 ; Group read
|
||||
EXT2_S_IWGRP = 0x0010 ; Group write
|
||||
EXT2_S_IXGRP = 0x0008 ; Group execute
|
||||
EXT2_S_IROTH = 0x0004 ; Others read
|
||||
EXT2_S_IWOTH = 0x0002 ; Others write
|
||||
EXT2_S_IXOTH = 0x0001 ; Others execute
|
||||
|
||||
PERMISSIONS = EXT2_S_IRUSR or EXT2_S_IWUSR \
|
||||
or EXT2_S_IRGRP or EXT2_S_IWGRP \
|
||||
or EXT2_S_IROTH or EXT2_S_IWOTH
|
||||
|
||||
; File type defining values in directory entry.
|
||||
EXT2_FT_REG_FILE = 1 ; Regular file.
|
||||
EXT2_FT_DIR = 2 ; Directory.
|
||||
|
||||
; Flags used by KolibriOS.
|
||||
FS_FT_HIDDEN = 2
|
||||
FS_FT_DIR = 0x10 ; Directory.
|
||||
|
||||
; ext2 partition flags.
|
||||
EXT2_RO = 0x01
|
||||
|
||||
FS_FT_ASCII = 0 ; Name in ASCII.
|
||||
FS_FT_UNICODE = 1 ; Name in Unicode.
|
||||
|
||||
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry.
|
||||
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ; Extents.
|
||||
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ; Flexible block groups.
|
||||
|
||||
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x0002 ; Large file support (64-bit file size)
|
||||
|
||||
; Implemented ext[2,3,4] features.
|
||||
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
|
||||
or EXT4_FEATURE_INCOMPAT_EXTENTS \
|
||||
or EXT4_FEATURE_INCOMPAT_FLEX_BG
|
||||
|
||||
; Implemented features which otherwise require "read-only" mount.
|
||||
EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \
|
||||
or EXT2_FEATURE_RO_COMPAT_LARGE_FILE
|
||||
|
||||
; ext4 features not support for write.
|
||||
EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \
|
||||
or EXT4_FEATURE_INCOMPAT_FLEX_BG
|
||||
|
||||
; Flags specified in i_flags.
|
||||
EXT2_EXTENTS_FL = 0x00080000 ; Extents.
|
||||
|
||||
struct EXT2_INODE_STRUC
|
||||
i_mode dw ?
|
||||
i_uid dw ?
|
||||
i_size dd ?
|
||||
i_atime dd ?
|
||||
i_ctime dd ?
|
||||
i_mtime dd ?
|
||||
i_dtime dd ?
|
||||
i_gid dw ?
|
||||
i_links_count dw ?
|
||||
i_blocks dd ?
|
||||
i_flags dd ?
|
||||
i_osd1 dd ?
|
||||
i_block rd 15
|
||||
i_generation dd ?
|
||||
i_file_acl dd ?
|
||||
i_dir_acl dd ?
|
||||
i_faddr dd ?
|
||||
i_osd2 dd ? ; 12 bytes.
|
||||
ends
|
||||
|
||||
struct EXT2_DIR_STRUC
|
||||
inode dd ?
|
||||
rec_len dw ?
|
||||
name_len db ?
|
||||
file_type db ?
|
||||
name db ? ; 255 (max) bytes.
|
||||
ends
|
||||
|
||||
struct EXT2_BLOCK_GROUP_DESC
|
||||
block_bitmap dd ? ; +0
|
||||
inode_bitmap dd ? ; +4
|
||||
inode_table dd ? ; +8
|
||||
free_blocks_count dw ? ; +12
|
||||
free_inodes_count dw ? ; +14
|
||||
used_dirs_count dw ? ; +16
|
||||
pad dw ? ; +18
|
||||
reserved rb 12 ; +20
|
||||
ends
|
||||
|
||||
struct EXT2_SB_STRUC
|
||||
inodes_count dd ? ; +0
|
||||
blocks_count dd ? ; +4
|
||||
r_block_count dd ? ; +8
|
||||
free_block_count dd ? ; +12
|
||||
free_inodes_count dd ? ; +16
|
||||
first_data_block dd ? ; +20
|
||||
log_block_size dd ? ; +24
|
||||
log_frag_size dd ? ; +28
|
||||
blocks_per_group dd ? ; +32
|
||||
frags_per_group dd ? ; +36
|
||||
inodes_per_group dd ? ; +40
|
||||
mtime dd ? ; +44
|
||||
wtime dd ? ; +48
|
||||
mnt_count dw ? ; +52
|
||||
max_mnt_count dw ? ; +54
|
||||
magic dw ? ; +56
|
||||
state dw ? ; +58
|
||||
errors dw ? ; +60
|
||||
minor_rev_level dw ? ; +62
|
||||
lastcheck dd ? ; +64
|
||||
check_intervals dd ? ; +68
|
||||
creator_os dd ? ; +72
|
||||
rev_level dd ? ; +76
|
||||
def_resuid dw ? ; +80
|
||||
def_resgid dw ? ; +82
|
||||
first_ino dd ? ; +84
|
||||
inode_size dw ? ; +88
|
||||
block_group_nr dw ? ; +90
|
||||
feature_compat dd ? ; +92
|
||||
feature_incompat dd ? ; +96
|
||||
feature_ro_compat dd ? ; +100
|
||||
uuid rb 16 ; +104
|
||||
volume_name rb 16 ; +120
|
||||
last_mounted rb 64 ; +136
|
||||
algo_bitmap dd ? ; +200
|
||||
prealloc_blocks db ? ; +204
|
||||
preallock_dir_blocks db ? ; +205
|
||||
reserved_gdt_blocks dw ? ; +206
|
||||
journal_uuid rb 16 ; +208
|
||||
journal_inum dd ? ; +224
|
||||
journal_dev dd ? ; +228
|
||||
last_orphan dd ? ; +232
|
||||
hash_seed rd 4 ; +236
|
||||
def_hash_version db ? ; +252
|
||||
reserved rb 3 ; +253 (reserved)
|
||||
default_mount_options dd ? ; +256
|
||||
first_meta_bg dd ? ; +260
|
||||
mkfs_time dd ? ; +264
|
||||
jnl_blocks rd 17 ; +268
|
||||
blocks_count_hi dd ? ; +336
|
||||
r_blocks_count_hi dd ? ; +340
|
||||
free_blocks_count_hi dd ? ; +344
|
||||
min_extra_isize dw ? ; +348
|
||||
want_extra_isize dw ? ; +350
|
||||
flags dd ? ; +352
|
||||
raid_stride dw ? ; +356
|
||||
mmp_interval dw ? ; +358
|
||||
mmp_block dq ? ; +360
|
||||
raid_stripe_width dd ? ; +368
|
||||
log_groups_per_flex db ? ; +372
|
||||
ends
|
||||
|
||||
; Header block extents.
|
||||
struct EXT4_EXTENT_HEADER
|
||||
eh_magic dw ? ; Magic value of 0xF30A, for ext4.
|
||||
eh_entries dw ? ; Number of blocks covered by the extent.
|
||||
eh_max dw ? ; Capacity of entries.
|
||||
eh_depth dw ? ; Tree depth (if 0, extents in the array are not extent indexes)
|
||||
eh_generation dd ? ; ???
|
||||
ends
|
||||
|
||||
; Extent.
|
||||
struct EXT4_EXTENT
|
||||
ee_block dd ? ; First logical block extent covers.
|
||||
ee_len dw ? ; Number of blocks covered by extent.
|
||||
ee_start_hi dw ? ; Upper 16 bits of 48-bit address (unused in KOS)
|
||||
ee_start_lo dd ? ; Lower 32 bits of 48-bit address.
|
||||
ends
|
||||
|
||||
; Index on-disk structure; pointer to block of extents/indexes.
|
||||
struct EXT4_EXTENT_IDX
|
||||
ei_block dd ? ; Covers logical blocks from here.
|
||||
ei_leaf_lo dd ? ; Lower 32-bits of pointer to the physical block of the next level.
|
||||
ei_leaf_hi dw ? ; Higher 16-bits (unused in KOS).
|
||||
ei_unused dw ? ; Reserved.
|
||||
ends
|
1850
kernel/branches/Kolibri-acpi/fs/ext2/inode.inc
Normal file
1850
kernel/branches/Kolibri-acpi/fs/ext2/inode.inc
Normal file
File diff suppressed because it is too large
Load Diff
223
kernel/branches/Kolibri-acpi/fs/ext2/resource.inc
Normal file
223
kernel/branches/Kolibri-acpi/fs/ext2/resource.inc
Normal file
@ -0,0 +1,223 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Contains common resource allocation + freeing code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Frees a resource (block/inode).
|
||||
; Input: eax = resource ID.
|
||||
; edi = function pointer of ext2_bg_*_bitmap form, to
|
||||
; get bitmap of resource.
|
||||
; ecx = 0, block; 1, inode.
|
||||
; ebp = pointer to EXTFS.
|
||||
; Output: Block marked as free in block group.
|
||||
; eax = error code.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_resource_free:
|
||||
push ebx edx esi
|
||||
|
||||
; Get block group.
|
||||
sub eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block]
|
||||
xor edx, edx
|
||||
div [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_per_group]
|
||||
push eax edx
|
||||
|
||||
call edi
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov esi, eax
|
||||
|
||||
; Read the bitmap.
|
||||
mov eax, ebx
|
||||
mov edx, eax
|
||||
mov ebx, [ebp + EXTFS.ext2_save_block]
|
||||
call ext2_block_read
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
pop eax
|
||||
; Mark bit free.
|
||||
call bitmap_clear_bit
|
||||
test eax, eax
|
||||
jz @F
|
||||
|
||||
; No need to save anything.
|
||||
xor eax, eax
|
||||
|
||||
add esp, 4
|
||||
jmp .return
|
||||
|
||||
@@:
|
||||
mov eax, edx
|
||||
mov ebx, [ebp + EXTFS.ext2_save_block]
|
||||
call ext2_block_write
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
; Read the descriptor.
|
||||
mov eax, [esp]
|
||||
call ext2_bg_read_desc
|
||||
test eax, eax
|
||||
jz .fail_bg_desc_read
|
||||
|
||||
lea eax, [eax + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
|
||||
shl ecx, 1
|
||||
add eax, ecx
|
||||
inc word[eax]
|
||||
|
||||
lea eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_block_count]
|
||||
shl ecx, 1
|
||||
add eax, ecx
|
||||
inc dword[eax]
|
||||
|
||||
pop eax
|
||||
call ext2_bg_write_desc
|
||||
|
||||
.return:
|
||||
pop esi edx ebx
|
||||
ret
|
||||
|
||||
.fail:
|
||||
add esp, 4
|
||||
.fail_bg_desc_read:
|
||||
add esp, 4
|
||||
xor eax, eax
|
||||
not eax
|
||||
jmp .return
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Allocates a resource.
|
||||
; Input: eax = inode ID for "preference".
|
||||
; ebp = pointer to EXTFS.
|
||||
; [esp + 4], func pointer to ext2_bg_*_bitmap
|
||||
; [esp + 8], pointer to free_*_count in SB.
|
||||
; [esp + 12], *_per_group
|
||||
; [esp + 16], offset to free_*_count in bg descriptor.
|
||||
; [esp + 20], *_count
|
||||
; Output: Resource marked as set in block group.
|
||||
; eax = error code.
|
||||
; ebx = resource ID.
|
||||
;---------------------------------------------------------------------
|
||||
ext2_resource_alloc:
|
||||
; Block allocation is a pretty serious area, since bad allocation
|
||||
; can lead to fragmentation. Thus, the best way to allocate that
|
||||
; comes to mind is to allocate around an inode as much as possible.
|
||||
; On the other hand, this isn't about a single inode/file/directory,
|
||||
; and focusing just around the preferred inode would lead to
|
||||
; congestion. Thus, after much thought, the chosen allocation algorithm
|
||||
; is to search forward, then backward.
|
||||
push ecx edx esi edi
|
||||
|
||||
cmp dword[esp + 16 + 8], 0
|
||||
jnz @F
|
||||
|
||||
; No free blocks.
|
||||
xor eax, eax
|
||||
not eax
|
||||
pop edi esi edx ecx
|
||||
ret 20
|
||||
|
||||
@@:
|
||||
; Calculate which block group the preferred inode belongs to.
|
||||
dec eax
|
||||
xor edx, edx
|
||||
|
||||
; EAX = block group.
|
||||
div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group]
|
||||
push eax
|
||||
push eax
|
||||
|
||||
mov edi, .forward
|
||||
|
||||
.test_block_group:
|
||||
call dword[esp + 16 + 8 + 4]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov esi, eax
|
||||
|
||||
mov eax, ebx
|
||||
mov edx, eax
|
||||
mov ebx, [ebp + EXTFS.ext2_save_block]
|
||||
call ext2_block_read
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
mov ecx, [esp + 16 + 8 + 12]
|
||||
call ext2_find_free_bit
|
||||
cmp eax, 0xFFFFFFFF
|
||||
jne @F
|
||||
|
||||
mov eax, edi
|
||||
jmp eax
|
||||
|
||||
@@:
|
||||
mov ecx, eax
|
||||
|
||||
mov eax, edx
|
||||
mov ebx, [ebp + EXTFS.ext2_save_block]
|
||||
call ext2_block_write
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
|
||||
; ecx: the index of the matched entry.
|
||||
; [esp]: block group where we found.
|
||||
; [esp + 4]: starting block group.
|
||||
; esi: block group descriptor.
|
||||
mov eax, [esp] ; Index of block group in which we found.
|
||||
mul dword[esp + 16 + 8 + 12]
|
||||
add eax, ecx
|
||||
mov ebx, eax
|
||||
|
||||
mov eax, [esp + 16 + 8 + 8]
|
||||
dec dword[eax]
|
||||
|
||||
mov eax, esi
|
||||
add eax, [esp + 16 + 8 + 16]
|
||||
dec word[eax]
|
||||
|
||||
pop eax
|
||||
call ext2_bg_write_desc
|
||||
|
||||
add esp, 4
|
||||
jmp .return
|
||||
|
||||
; Continue forward.
|
||||
.forward:
|
||||
inc dword[esp]
|
||||
mov eax, [esp]
|
||||
mul dword[esp + 16 + 8 + 12]
|
||||
cmp eax, [esp + 16 + 8 + 20]
|
||||
jbe @F
|
||||
|
||||
; We need to go backward.
|
||||
mov eax, [esp + 4]
|
||||
mov [esp], eax
|
||||
mov edi, .backward
|
||||
jmp .backward
|
||||
|
||||
@@:
|
||||
mov eax, [esp]
|
||||
jmp .test_block_group
|
||||
|
||||
; Continue backward.
|
||||
.backward:
|
||||
cmp dword[esp], 0
|
||||
je .fail
|
||||
|
||||
dec dword[esp]
|
||||
mov eax, [esp]
|
||||
jmp .test_block_group
|
||||
|
||||
.return:
|
||||
pop edi esi edx ecx
|
||||
ret 20
|
||||
|
||||
.fail:
|
||||
add esp, 8
|
||||
xor eax, eax
|
||||
not eax
|
||||
jmp .return
|
12
kernel/branches/Kolibri-acpi/fs/fs-et.inc
Normal file
12
kernel/branches/Kolibri-acpi/fs/fs-et.inc
Normal file
@ -0,0 +1,12 @@
|
||||
dir0:
|
||||
db 'KÕVAKETAS '
|
||||
db 'MÄLUKETAS '
|
||||
db 'FLOPPIKETAS'
|
||||
db 0
|
||||
|
||||
dir1:
|
||||
db 'ESIMENE '
|
||||
db 'TEINE '
|
||||
db 'KOLAMS '
|
||||
db 'NELJAS '
|
||||
db 0
|
@ -24,6 +24,8 @@ iglobal
|
||||
|
||||
if lang eq sp
|
||||
include 'fs/fs-sp.inc'
|
||||
else if lang eq et
|
||||
include 'fs/fs-et.inc'
|
||||
else
|
||||
dir0:
|
||||
db 'HARDDISK '
|
||||
|
2769
kernel/branches/Kolibri-acpi/fs/xfs.asm
Normal file
2769
kernel/branches/Kolibri-acpi/fs/xfs.asm
Normal file
File diff suppressed because it is too large
Load Diff
518
kernel/branches/Kolibri-acpi/fs/xfs.inc
Normal file
518
kernel/branches/Kolibri-acpi/fs/xfs.inc
Normal file
@ -0,0 +1,518 @@
|
||||
; from stat.h
|
||||
; distinguish file types
|
||||
S_IFMT = 0170000o ; These bits determine file type.
|
||||
S_IFDIR = 0040000o ; Directory.
|
||||
S_IFCHR = 0020000o ; Character device.
|
||||
S_IFBLK = 0060000o ; Block device.
|
||||
S_IFREG = 0100000o ; Regular file.
|
||||
S_IFIFO = 0010000o ; FIFO.
|
||||
S_IFLNK = 0120000o ; Symbolic link.
|
||||
S_IFSOCK = 0140000o ; Socket.
|
||||
; end stat.h
|
||||
|
||||
|
||||
; XFS null constant: empty fields must be all ones, not zeros!
|
||||
XFS_NULL = -1
|
||||
|
||||
|
||||
; static sector numbers
|
||||
XFS_SECT_SB = 0
|
||||
XFS_SECT_AGF = 1
|
||||
XFS_SECT_AGI = 2
|
||||
XFS_SECT_AGFL = 3
|
||||
|
||||
|
||||
; signatures of file system structures
|
||||
; 'string' numbers are treated by fasm as big endian
|
||||
XFS_SB_MAGIC = 'XFSB'
|
||||
XFS_AGF_MAGIC = 'XAGF'
|
||||
XFS_AGI_MAGIC = 'XAGI'
|
||||
XFS_ABTB_MAGIC = 'ABTB'
|
||||
XFS_ABTC_MAGIC = 'ABTC'
|
||||
XFS_IBT_MAGIC = 'IABT'
|
||||
XFS_DINODE_MAGIC = 'IN'
|
||||
XFS_BMAP_MAGIC = 'BMAP'
|
||||
XFS_DA_NODE_MAGIC = 0xbefe ; those are little endian here
|
||||
XFS_ATTR_LEAF_MAGIC = 0xeefb ; but big endian in docs
|
||||
XFS_DIR2_LEAF1_MAGIC = 0xf1d2 ; pay attention!
|
||||
XFS_DIR2_LEAFN_MAGIC = 0xffd2 ;
|
||||
XFS_DIR2_BLOCK_MAGIC = 'XD2B'
|
||||
XFS_DIR2_DATA_MAGIC = 'XD2D'
|
||||
XFS_DIR2_FREE_MAGIC = 'XD2F'
|
||||
XFS_DQUOT_MAGIC = 'DQ'
|
||||
|
||||
|
||||
; bitfield lengths for packed extent
|
||||
; MSB to LSB / left to right
|
||||
BMBT_EXNTFLAG_BITLEN = 1
|
||||
BMBT_STARTOFF_BITLEN = 54
|
||||
BMBT_STARTBLOCK_BITLEN = 52
|
||||
BMBT_BLOCKCOUNT_BITLEN = 21
|
||||
|
||||
|
||||
; those constants are taken from linux source (xfs_dir2_leaf.h)
|
||||
; they are magic infile offsets for directories
|
||||
XFS_DIR2_DATA_ALIGN_LOG = 3 ; i.e., 8 bytes
|
||||
XFS_DIR2_LEAF_SPACE = 1
|
||||
XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG))
|
||||
XFS_DIR2_LEAF_OFFSET = (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
|
||||
XFS_DIR2_FREE_SPACE = 2
|
||||
XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG))
|
||||
XFS_DIR2_FREE_OFFSET = (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
|
||||
|
||||
|
||||
; data section magic constants for directories (xfs_dir2_data.h)
|
||||
XFS_DIR2_DATA_FD_COUNT = 3
|
||||
XFS_DIR2_DATA_FREE_TAG = 0xffff
|
||||
|
||||
|
||||
; valid inode formats
|
||||
; enum xfs_dinode_fmt (xfs_dinode.h)
|
||||
XFS_DINODE_FMT_DEV = 0 ; xfs_dev_t
|
||||
XFS_DINODE_FMT_LOCAL = 1 ; one inode is enough (shortdir)
|
||||
XFS_DINODE_FMT_EXTENTS = 2 ; one or more extents (leafdir, nodedir, regular files)
|
||||
XFS_DINODE_FMT_BTREE = 3 ; highly fragmented files or really huge directories
|
||||
XFS_DINODE_FMT_UUID = 4 ; uuid_t
|
||||
|
||||
|
||||
; size of the unlinked inode hash table in the agi
|
||||
XFS_AGI_UNLINKED_BUCKETS = 64
|
||||
|
||||
|
||||
; possible extent states
|
||||
; enum xfs_exntst_t (xfs_bmap_btree.h)
|
||||
XFS_EXT_NORM = 0
|
||||
XFS_EXT_UNWRITTEN = 1
|
||||
XFS_EXT_DMAPI_OFFLINE = 2
|
||||
XFS_EXT_INVALID = 3
|
||||
|
||||
|
||||
; values for inode core flags / di_flags (xfs_dinode.h)
|
||||
XFS_DIFLAG_REALTIME_BIT = 0 ; file's blocks come from rt area
|
||||
XFS_DIFLAG_PREALLOC_BIT = 1 ; file space has been preallocated
|
||||
XFS_DIFLAG_NEWRTBM_BIT = 2 ; for rtbitmap inode, new format
|
||||
XFS_DIFLAG_IMMUTABLE_BIT = 3 ; inode is immutable
|
||||
XFS_DIFLAG_APPEND_BIT = 4 ; inode is append-only
|
||||
XFS_DIFLAG_SYNC_BIT = 5 ; inode is written synchronously
|
||||
XFS_DIFLAG_NOATIME_BIT = 6 ; do not update atime
|
||||
XFS_DIFLAG_NODUMP_BIT = 7 ; do not dump
|
||||
XFS_DIFLAG_RTINHERIT_BIT = 8 ; create with realtime bit set
|
||||
XFS_DIFLAG_PROJINHERIT_BIT = 9 ; create with parents projid
|
||||
XFS_DIFLAG_NOSYMLINKS_BIT = 10 ; disallow symlink creation
|
||||
XFS_DIFLAG_EXTSIZE_BIT = 11 ; inode extent size allocator hint
|
||||
XFS_DIFLAG_EXTSZINHERIT_BIT = 12 ; inherit inode extent size
|
||||
XFS_DIFLAG_NODEFRAG_BIT = 13 ; do not reorganize/defragment
|
||||
XFS_DIFLAG_FILESTREAM_BIT = 14 ; use filestream allocator
|
||||
XFS_DIFLAG_REALTIME = (1 SHL XFS_DIFLAG_REALTIME_BIT)
|
||||
XFS_DIFLAG_PREALLOC = (1 SHL XFS_DIFLAG_PREALLOC_BIT)
|
||||
XFS_DIFLAG_NEWRTBM = (1 SHL XFS_DIFLAG_NEWRTBM_BIT)
|
||||
XFS_DIFLAG_IMMUTABLE = (1 SHL XFS_DIFLAG_IMMUTABLE_BIT)
|
||||
XFS_DIFLAG_APPEND = (1 SHL XFS_DIFLAG_APPEND_BIT)
|
||||
XFS_DIFLAG_SYNC = (1 SHL XFS_DIFLAG_SYNC_BIT)
|
||||
XFS_DIFLAG_NOATIME = (1 SHL XFS_DIFLAG_NOATIME_BIT)
|
||||
XFS_DIFLAG_NODUMP = (1 SHL XFS_DIFLAG_NODUMP_BIT)
|
||||
XFS_DIFLAG_RTINHERIT = (1 SHL XFS_DIFLAG_RTINHERIT_BIT)
|
||||
XFS_DIFLAG_PROJINHERIT = (1 SHL XFS_DIFLAG_PROJINHERIT_BIT)
|
||||
XFS_DIFLAG_NOSYMLINKS = (1 SHL XFS_DIFLAG_NOSYMLINKS_BIT)
|
||||
XFS_DIFLAG_EXTSIZE = (1 SHL XFS_DIFLAG_EXTSIZE_BIT)
|
||||
XFS_DIFLAG_EXTSZINHERIT = (1 SHL XFS_DIFLAG_EXTSZINHERIT_BIT)
|
||||
XFS_DIFLAG_NODEFRAG = (1 SHL XFS_DIFLAG_NODEFRAG_BIT)
|
||||
XFS_DIFLAG_FILESTREAM = (1 SHL XFS_DIFLAG_FILESTREAM_BIT)
|
||||
|
||||
|
||||
; superblock _ondisk_ structure (xfs_sb.h)
|
||||
; this is _not_ the partition structure
|
||||
; for XFS partition structure see XFS below
|
||||
struct xfs_sb
|
||||
sb_magicnum dd ? ; signature, must be XFS_SB_MAGIC
|
||||
sb_blocksize dd ? ; block is the minimal file system unit, in bytes
|
||||
sb_dblocks dq ? ; number of data blocks
|
||||
sb_rblocks dq ? ; number of realtime blocks (not supported yet!)
|
||||
sb_rextents dq ? ; number of realtime extents (not supported yet!)
|
||||
sb_uuid rb 16 ; file system unique identifier
|
||||
sb_logstart dq ? ; starting block of log (for internal journal; journals on separate devices are not supported!)
|
||||
sb_rootino dq ? ; root inode number
|
||||
sb_rbmino dq ? ; bitmap inode for realtime extents (ignored)
|
||||
sb_rsumino dq ? ; summary inode for rt bitmap (ignored)
|
||||
sb_rextsize dd ? ; realtime extent size, blocks
|
||||
sb_agblocks dd ? ; size of an allocation group (the last one may be smaller!)
|
||||
sb_agcount dd ? ; number of allocation groups
|
||||
sb_rbmblocks dd ? ; number of rt bitmap blocks
|
||||
sb_logblocks dd ? ; number of log blocks
|
||||
sb_versionnum dw ? ; header version == XFS_SB_VERSION
|
||||
sb_sectsize dw ? ; volume sector size in bytes (only 512B sectors are supported)
|
||||
sb_inodesize dw ? ; inode size, bytes
|
||||
sb_inopblock dw ? ; inodes per block
|
||||
sb_fname rb 12 ; inodes per block (aka label)
|
||||
sb_blocklog db ? ; log2 of sb_blocksize
|
||||
sb_sectlog db ? ; log2 of sb_blocksize
|
||||
sb_inodelog db ? ; log2 of sb_inodesize
|
||||
sb_inopblog db ? ; log2 of sb_inopblock
|
||||
sb_agblklog db ? ; log2 of sb_agblocks (rounded up!)
|
||||
sb_rextslog db ? ; log2 of sb_rextents
|
||||
sb_inprogress db ? ; mkfs is in progress, don't mount
|
||||
sb_imax_pct db ? ; max % of fs for inode space
|
||||
; statistics
|
||||
sb_icount dq ? ; allocated inodes
|
||||
sb_ifree dq ? ; free inodes
|
||||
sb_fdblocks dq ? ; free data blocks
|
||||
sb_frextents dq ? ; free realtime extents
|
||||
|
||||
sb_uquotino dq ? ; user quota inode
|
||||
sb_gquotino dq ? ; group quota inode
|
||||
sb_qflags dw ? ; quota flags
|
||||
sb_flags db ? ; misc. flags
|
||||
sb_shared_vn db ? ; shared version number
|
||||
sb_inoalignmt dd ? ; inode chunk alignment, fsblocks
|
||||
sb_unit dd ? ; stripe or raid unit
|
||||
sb_width dd ? ; stripe or raid width
|
||||
sb_dirblklog db ? ; log2 of dir block size (fsbs)
|
||||
sb_logsectlog db ? ; log2 of the log sector size
|
||||
sb_logsectsize dw ? ; sector size for the log, bytes
|
||||
sb_logsunit dd ? ; stripe unit size for the log
|
||||
sb_features2 dd ? ; additional feature bits
|
||||
ends
|
||||
|
||||
|
||||
; allocation group inode (xfs_ag.h)
|
||||
struct xfs_agi
|
||||
agi_magicnum dd ? ; magic number == XFS_AGI_MAGIC
|
||||
agi_versionnum dd ? ; header version == XFS_AGI_VERSION
|
||||
agi_seqno dd ? ; sequence number starting from 0
|
||||
agi_length dd ? ; size in blocks of a.g.
|
||||
agi_count dd ? ; count of allocated inodes
|
||||
agi_root dd ? ; root of inode btree
|
||||
agi_level dd ? ; levels in inode btree
|
||||
agi_freecount dd ? ; number of free inodes
|
||||
agi_newino dd ? ; new inode just allocated
|
||||
agi_dirino dd ? ; last directory inode chunk
|
||||
agi_unlinked rd XFS_AGI_UNLINKED_BUCKETS ; Hash table of inodes which have been unlinked but are still being referenced
|
||||
ends
|
||||
|
||||
|
||||
; superblock structure of b+tree node/leaf (same structure, bb_level matters)
|
||||
struct xfs_btree_sblock
|
||||
bb_magic dd ?
|
||||
bb_level dw ? ; distinguishes nodeds and leaves
|
||||
bb_numrecs dw ?
|
||||
bb_leftsib dd ?
|
||||
bb_rightsib dd ?
|
||||
ends
|
||||
|
||||
|
||||
; record of b+tree inode
|
||||
struct xfs_inobt_rec
|
||||
ir_startino dd ?
|
||||
ir_freecount dd ?
|
||||
ir_free dq ?
|
||||
ends
|
||||
|
||||
|
||||
; structure to store create, access and modification time in inode core
|
||||
struct xfs_timestamp
|
||||
t_sec dd ?
|
||||
t_nsec dd ? ; nanoseconds
|
||||
ends
|
||||
|
||||
|
||||
; inode core structure: basic information about file
|
||||
struct xfs_dinode_core
|
||||
di_magic dw ? ; inode magic = XFS_DINODE_MAGIC
|
||||
di_mode dw ? ; mode and type of file
|
||||
di_version db ? ; inode version
|
||||
di_format db ? ; format of di_c data
|
||||
di_onlink dw ? ; old number of links to file
|
||||
di_uid dd ? ; owner's user id
|
||||
di_gid dd ? ; owner's group id
|
||||
di_nlink dd ? ; number of links to file
|
||||
di_projid dw ? ; owner's project id
|
||||
di_pad rb 8 ; unused, zeroed space
|
||||
di_flushiter dw ? ; incremented on flush
|
||||
di_atime xfs_timestamp ; time last accessed
|
||||
di_mtime xfs_timestamp ; time last modified
|
||||
di_ctime xfs_timestamp ; time created/inode modified
|
||||
di_size dq ? ; number of bytes in file
|
||||
di_nblocks dq ? ; number of direct & btree blocks used
|
||||
di_extsize dd ? ; basic/minimum extent size for file
|
||||
di_nextents dd ? ; number of extents in data fork
|
||||
di_anextents dw ? ; number of extents in attribute fork
|
||||
di_forkoff db ? ; attr fork offs, <<3 for 64b align
|
||||
di_aformat db ? ; format of attr fork's data
|
||||
di_dmevmask dd ? ; DMIG event mask
|
||||
di_dmstate dw ? ; DMIG state info
|
||||
di_flags dw ? ; random flags, XFS_DIFLAG_...
|
||||
di_gen dd ? ; generation number
|
||||
ends
|
||||
|
||||
|
||||
; shortform dir header
|
||||
struct xfs_dir2_sf_hdr
|
||||
count db ? ; the number of directory entries, used only if each inode number fits 4 bytes; zero otherwise
|
||||
i8count db ? ; the number of directory entries, used only when count is zero
|
||||
parent dq ? ; parent inode number: xfs_dir2_inou_t (4 or 8 bytes)
|
||||
ends
|
||||
|
||||
|
||||
; shortform dir entry
|
||||
struct xfs_dir2_sf_entry
|
||||
namelen db ? ; actual name length (ASCII)
|
||||
offset rb 2 ; saved offset
|
||||
name db ? ; name, variable size
|
||||
; inumber dq ? ; xfs_dir2_inou_t
|
||||
ends
|
||||
|
||||
|
||||
; active entry in a data block
|
||||
; aligned to 8 bytes
|
||||
; tag appears as the last 2 bytes
|
||||
struct xfs_dir2_data_entry
|
||||
inumber dq ? ; inode number
|
||||
namelen db ? ; name length
|
||||
name db ? ; name bytes, no null
|
||||
; tag dw ? ; starting offset of us
|
||||
ends
|
||||
|
||||
|
||||
; unused entry in a data block
|
||||
; aligned to 8 bytes
|
||||
; tag appears as the last 2 bytes
|
||||
struct xfs_dir2_data_unused
|
||||
freetag dw ? ; XFS_DIR2_DATA_FREE_TAG
|
||||
length dw ? ; total free length
|
||||
; tag dw ? ; starting offset of us
|
||||
ends
|
||||
|
||||
|
||||
; generic data entry
|
||||
struct xfs_dir2_data_union
|
||||
union
|
||||
xentry xfs_dir2_data_entry
|
||||
unused xfs_dir2_data_unused
|
||||
ends
|
||||
ends
|
||||
|
||||
|
||||
; describe a free area in the data block
|
||||
; the freespace will be formatted as a xfs_dir2_data_unused_t
|
||||
struct xfs_dir2_data_free
|
||||
offset dw ? ; start of freespace
|
||||
length dw ? ; length of freespace
|
||||
ends
|
||||
|
||||
|
||||
; header for the data blocks
|
||||
; always at the beginning of a directory-sized block
|
||||
; the code knows that XFS_DIR2_DATA_FD_COUNT is 3
|
||||
struct xfs_dir2_data_hdr
|
||||
magic dd ? ; XFS_DIR2_DATA_MAGIC or XFS_DIR2_BLOCK_MAGIC
|
||||
bestfree xfs_dir2_data_free
|
||||
bestfree2 xfs_dir2_data_free
|
||||
bestfree3 xfs_dir2_data_free
|
||||
ends
|
||||
|
||||
|
||||
; leaf block entry
|
||||
struct xfs_dir2_leaf_entry
|
||||
hashval dd ? ; hash value of name
|
||||
address dd ? ; address of data entry
|
||||
ends
|
||||
|
||||
|
||||
; the tail of directory block
|
||||
struct xfs_dir2_block_tail
|
||||
count dd ? ; count of leaf entries
|
||||
stale dd ? ; count of stale leaf entries
|
||||
ends
|
||||
|
||||
|
||||
; generic single-block structure, for xfs_db
|
||||
struct xfs_dir2_block
|
||||
hdr xfs_dir2_data_hdr
|
||||
u xfs_dir2_data_union
|
||||
; leaf xfs_dir2_leaf_entry
|
||||
; tail xfs_dir2_block_tail
|
||||
ends
|
||||
|
||||
|
||||
;
|
||||
struct xfs_dir2_data
|
||||
hdr xfs_dir2_data_hdr ; magic XFS_DIR2_DATA_MAGIC
|
||||
u xfs_dir2_data_union
|
||||
ends
|
||||
|
||||
|
||||
;
|
||||
struct xfs_da_blkinfo
|
||||
forw dd ? ; previous block in list
|
||||
back dd ? ; following block in list
|
||||
magic dw ? ; validity check on block
|
||||
pad dw ? ; unused
|
||||
ends
|
||||
|
||||
|
||||
; leaf block header
|
||||
struct xfs_dir2_leaf_hdr
|
||||
info xfs_da_blkinfo ; header for da routines
|
||||
count dw ? ; count of entries
|
||||
stale dw ? ; count of stale entries
|
||||
ends
|
||||
|
||||
|
||||
; leaf block tail
|
||||
struct xfs_dir2_leaf_tail
|
||||
bestcount dd ?
|
||||
ends
|
||||
|
||||
|
||||
; leaf block
|
||||
; bests and tail are at the end of the block for single-leaf only
|
||||
; (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC)
|
||||
struct xfs_dir2_leaf
|
||||
hdr xfs_dir2_leaf_hdr ; leaf header
|
||||
ents xfs_dir2_leaf_entry ; entries
|
||||
; bests dw ? ; best free counts
|
||||
; tail xfs_dir2_leaf_tail ; leaf tail
|
||||
ends
|
||||
|
||||
|
||||
; header of 'free' block part
|
||||
struct xfs_dir2_free_hdr
|
||||
magic dd ? ; XFS_DIR2_FREE_MAGIC
|
||||
firstdb dd ? ; db of first entry
|
||||
nvalid dd ? ; count of valid entries
|
||||
nused dd ? ; count of used entries
|
||||
ends
|
||||
|
||||
|
||||
; 'free' part of directiry block
|
||||
struct xfs_dir2_free
|
||||
hdr xfs_dir2_free_hdr ; block header
|
||||
bests dw ? ; best free counts
|
||||
; unused entries are -1 (XFS_NULL)
|
||||
ends
|
||||
|
||||
|
||||
; b+tree node header
|
||||
struct xfs_da_node_hdr
|
||||
info xfs_da_blkinfo
|
||||
count dw ?
|
||||
level dw ?
|
||||
ends
|
||||
|
||||
|
||||
; b+tree node
|
||||
struct xfs_da_node_entry
|
||||
hashval dd ? ; hash value for this descendant
|
||||
before dd ? ; Btree block before this key
|
||||
ends
|
||||
|
||||
|
||||
;
|
||||
struct xfs_da_intnode
|
||||
hdr xfs_da_node_hdr
|
||||
btree xfs_da_node_entry
|
||||
ends
|
||||
|
||||
|
||||
; packet extent
|
||||
struct xfs_bmbt_rec
|
||||
l0 dq ?
|
||||
l1 dq ?
|
||||
ends
|
||||
|
||||
|
||||
; unpacked extent
|
||||
struct xfs_bmbt_irec
|
||||
br_startoff dq ? ; starting file offset
|
||||
br_startblock dq ? ; starting block number
|
||||
br_blockcount dd ? ; number of blocks
|
||||
br_state dd ? ; extent state
|
||||
ends
|
||||
|
||||
|
||||
; bmap root header, on-disk form only
|
||||
struct xfs_bmdr_block
|
||||
bb_level dw ? ; 0 is a leaf
|
||||
bb_numrecs dw ? ; current number of data records
|
||||
ends
|
||||
|
||||
|
||||
; key structure for non-leaf levels of the tree
|
||||
struct xfs_bmbt_key
|
||||
br_startoff dq ? ; starting file offset
|
||||
ends
|
||||
|
||||
|
||||
sizeof.xfs_bmbt_ptr = 8 ; workaround
|
||||
sizeof.xfs_bmdr_ptr = 8 ; workaround
|
||||
|
||||
|
||||
; long form header: bmap btrees
|
||||
; xfs_btree_lblock is xfs_bmbt_block (xfs_btree.h)
|
||||
struct xfs_bmbt_block
|
||||
bb_magic dd ? ; magic number for block type
|
||||
bb_level dw ? ; 0 is a leaf
|
||||
bb_numrecs dw ? ; current number of data records
|
||||
bb_leftsib dq ? ; left sibling block or NULLDFSBNO
|
||||
bb_rightsib dq ? ; right sibling block or NULLDFSBNO
|
||||
ends
|
||||
|
||||
|
||||
; high level inode structure
|
||||
struct xfs_inode
|
||||
di_core xfs_dinode_core ; main info, aka core
|
||||
di_next_unlinked dd ? ; unlinked but still used inode (if any, XFS_NULL otherwise)
|
||||
di_u db ? ; data fork inode part
|
||||
; di_a db ? ; data attribute
|
||||
ends
|
||||
|
||||
|
||||
; internal data for every XFS partition
|
||||
; this _is_ XFS partition structure
|
||||
; most fields are unpacked or bswap'ed values from the superblock, so see xfs_sb structure above
|
||||
struct XFS PARTITION
|
||||
Lock MUTEX ? ; access mutex
|
||||
blocksize dd ?
|
||||
sectsize dd ?
|
||||
dirblocksize dd ?
|
||||
rootino dq ?
|
||||
cur_block dd ?
|
||||
cur_inode dd ?
|
||||
cur_sect dd ?
|
||||
cur_dirblock dd ?
|
||||
tmp_inode dd ?
|
||||
versionnum dd ?
|
||||
features2 dd ?
|
||||
inodesize dd ?
|
||||
inopblock dd ?
|
||||
blocklog dd ?
|
||||
sectlog dd ?
|
||||
inodelog dd ?
|
||||
inopblog dd ?
|
||||
agblklog dd ?
|
||||
blockmsectlog dd ?
|
||||
inodetoblocklog dd ?
|
||||
dirblklog dd ?
|
||||
sectpblock dd ?
|
||||
agblocks dd ?
|
||||
; helpers, temporary vars, etc
|
||||
agblockmask dq ?
|
||||
extent xfs_bmbt_irec
|
||||
left_extents dd ?
|
||||
left_leaves dd ?
|
||||
bytes_to_read dd ?
|
||||
bytes_read dd ?
|
||||
entries_read dd ?
|
||||
file_offset dq ?
|
||||
max_dirblockaddr dd ?
|
||||
next_block_num dq ?
|
||||
dir2_leaf_offset_blocks dd ?
|
||||
dir2_free_offset_blocks dd ?
|
||||
cur_inode_save dd ?
|
||||
bytes_left_in_file dq ?
|
||||
ro_nextents dd ?
|
||||
bb_ptrs dd ?
|
||||
maxnumrecs dd ?
|
||||
buffer_pos dd ?
|
||||
eof dd ?
|
||||
ends
|
@ -233,6 +233,8 @@ align 4
|
||||
FONT_I:
|
||||
if lang eq sp
|
||||
file 'char_sp.mt'
|
||||
else if lang eq et
|
||||
file 'char_et.mt'
|
||||
else
|
||||
file 'char.mt'
|
||||
end if
|
||||
@ -241,6 +243,8 @@ align 4
|
||||
FONT_II:
|
||||
if lang eq sp
|
||||
file 'char2_sp.mt'
|
||||
else if lang eq et
|
||||
file 'char2_et.mt'
|
||||
else
|
||||
file 'char2.mt'
|
||||
end if
|
||||
|
@ -144,6 +144,8 @@ use16
|
||||
|
||||
if lang eq sp
|
||||
include "kernelsp.inc" ; spanish kernel messages
|
||||
else if lang eq et
|
||||
version db 'Kolibri OS versioon 0.7.7.0+ ',13,10,13,10,0
|
||||
else
|
||||
version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0
|
||||
end if
|
||||
@ -696,6 +698,19 @@ no_mode_0x12:
|
||||
mov [mem_BACKGROUND], 4
|
||||
mov [img_background], static_background_data
|
||||
|
||||
; set clipboard
|
||||
|
||||
xor eax, eax
|
||||
mov [clipboard_slots], eax
|
||||
mov [clipboard_write_lock], eax
|
||||
stdcall kernel_alloc, 4096
|
||||
test eax, eax
|
||||
jnz @f
|
||||
|
||||
dec eax
|
||||
@@:
|
||||
mov [clipboard_main_list], eax
|
||||
|
||||
; SET UP OS TASK
|
||||
|
||||
mov esi, boot_setostask
|
||||
@ -1093,6 +1108,8 @@ end if
|
||||
@@:
|
||||
DEBUGF 1, "K : %d CPU detected\n", eax
|
||||
|
||||
include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
|
||||
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
|
||||
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
|
||||
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
|
||||
@ -1100,6 +1117,7 @@ end if
|
||||
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
|
||||
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
|
||||
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
|
||||
|
||||
; START MULTITASKING
|
||||
|
||||
; A 'All set - press ESC to start' messages if need
|
||||
@ -3248,6 +3266,10 @@ sys_cpuusage:
|
||||
mov EAX, dword [ECX+CURRENT_TASK+TASKDATA.event_mask]
|
||||
stosd
|
||||
|
||||
; Keyboard mode (+75)
|
||||
mov al, byte [ecx*8 + SLOT_BASE + APPDATA.keyboard_mode]
|
||||
stosb
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
@ -3790,10 +3812,6 @@ newdw2:
|
||||
|
||||
mov eax, [edi + WDATA.box.left]
|
||||
mov ebx, [edi + WDATA.box.top]
|
||||
mov ecx, [edi + WDATA.box.width]
|
||||
mov edx, [edi + WDATA.box.height]
|
||||
add ecx, eax
|
||||
add edx, ebx
|
||||
|
||||
mov ecx, [draw_limits.bottom] ; ecx = area y end ebx = window y start
|
||||
cmp ecx, ebx
|
||||
@ -3892,6 +3910,64 @@ align 4
|
||||
align 4
|
||||
newdw8:
|
||||
nobgrd:
|
||||
;--------------------------------------
|
||||
push eax edi ebp
|
||||
mov edi, [esp+12]
|
||||
cmp edi, 1
|
||||
je .found
|
||||
|
||||
mov eax, [draw_limits.left]
|
||||
mov ebx, [draw_limits.top]
|
||||
mov ecx, [draw_limits.right]
|
||||
sub ecx, eax
|
||||
test ecx, ecx
|
||||
jz .not_found
|
||||
|
||||
mov edx, [draw_limits.bottom]
|
||||
sub edx, ebx
|
||||
test edx, edx
|
||||
jz .not_found
|
||||
|
||||
; eax - x, ebx - y
|
||||
; ecx - size x, edx - size y
|
||||
add ebx, edx
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.start_y:
|
||||
push ecx
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.start_x:
|
||||
add eax, ecx
|
||||
mov ebp, [d_width_calc_area + ebx*4]
|
||||
add ebp, [_WinMapAddress]
|
||||
movzx ebp, byte[eax+ebp] ; get value for current point
|
||||
cmp ebp, edi
|
||||
jne @f
|
||||
|
||||
pop ecx
|
||||
jmp .found
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
sub eax, ecx
|
||||
|
||||
dec ecx
|
||||
jnz .start_x
|
||||
|
||||
pop ecx
|
||||
dec ebx
|
||||
dec edx
|
||||
jnz .start_y
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.not_found:
|
||||
pop ebp edi eax
|
||||
jmp ricino
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.found:
|
||||
pop ebp edi eax
|
||||
|
||||
mov [eax + WDATA.fl_redraw], byte 1 ; mark as redraw
|
||||
;--------------------------------------
|
||||
@ -5511,13 +5587,13 @@ syscall_reserveportarea: ; ReservePortArea and FreePortArea
|
||||
|
||||
align 4
|
||||
syscall_threads: ; CreateThreads
|
||||
; eax=1 create thread
|
||||
;
|
||||
; ebx=thread start
|
||||
; ecx=thread stack value
|
||||
; ecx=thread entry point
|
||||
; edx=thread stack pointer
|
||||
;
|
||||
; on return : eax = pid
|
||||
|
||||
xor ebx, ebx
|
||||
call new_sys_threads
|
||||
|
||||
mov [esp+32], eax
|
||||
|
@ -171,6 +171,7 @@ include "core/v86.inc" ; virtual-8086 manager
|
||||
include "core/irq.inc" ; irq handling functions
|
||||
include "core/apic.inc" ; Interrupt Controller functions
|
||||
include "core/timers.inc"
|
||||
include "core/clipboard.inc" ; custom clipboard
|
||||
|
||||
; GUI stuff
|
||||
include "gui/window.inc"
|
||||
@ -191,7 +192,8 @@ include "fs/fat12.inc" ; read / write for fat12 filesystem
|
||||
include "blkdev/rd.inc" ; ramdisk read /write
|
||||
include "fs/fs_lfn.inc" ; syscall, version 2
|
||||
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
|
||||
include "fs/ext2.inc" ; read / write for ext2 filesystem
|
||||
include "fs/ext2/ext2.asm" ; read / write for ext2 filesystem
|
||||
include "fs/xfs.asm" ; read / write for xfs filesystem
|
||||
|
||||
; sound
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; Éste archivo debe ser editado con codificación CP866
|
||||
|
||||
version: cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0
|
||||
version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0
|
||||
diff16 "fin del código del kernel",0,$
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
$Revision: 3515 $
|
||||
|
||||
MAX_FRAGMENTS = 64
|
||||
IPv4_MAX_FRAGMENTS = 64
|
||||
|
||||
struct IPv4_header
|
||||
|
||||
@ -35,7 +35,7 @@ struct IPv4_header
|
||||
|
||||
ends
|
||||
|
||||
struct FRAGMENT_slot
|
||||
struct IPv4_FRAGMENT_slot
|
||||
|
||||
ttl dw ? ; Time to live for this entry, 0 for empty slot's
|
||||
id dw ? ; Identification field from IP header
|
||||
@ -45,7 +45,7 @@ struct FRAGMENT_slot
|
||||
|
||||
ends
|
||||
|
||||
struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
|
||||
struct IPv4_FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
|
||||
|
||||
PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
|
||||
NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
|
||||
@ -64,11 +64,11 @@ align 4
|
||||
GATEWAY_LIST rd NET_DEVICES_MAX
|
||||
BROADCAST_LIST rd NET_DEVICES_MAX
|
||||
|
||||
IP_packets_tx rd NET_DEVICES_MAX
|
||||
IP_packets_rx rd NET_DEVICES_MAX
|
||||
IP_packets_dumped rd NET_DEVICES_MAX
|
||||
IPv4_packets_tx rd NET_DEVICES_MAX
|
||||
IPv4_packets_rx rd NET_DEVICES_MAX
|
||||
IPv4_packets_dumped rd NET_DEVICES_MAX
|
||||
|
||||
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
|
||||
IPv4_FRAGMENT_LIST rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot
|
||||
|
||||
endg
|
||||
|
||||
@ -84,7 +84,7 @@ macro IPv4_init {
|
||||
|
||||
xor eax, eax
|
||||
mov edi, IP_LIST
|
||||
mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4
|
||||
mov ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4
|
||||
rep stosd
|
||||
|
||||
}
|
||||
@ -99,15 +99,15 @@ macro IPv4_decrease_fragment_ttls {
|
||||
|
||||
local .loop, .next
|
||||
|
||||
mov esi, FRAGMENT_LIST
|
||||
mov ecx, MAX_FRAGMENTS
|
||||
mov esi, IPv4_FRAGMENT_LIST
|
||||
mov ecx, IPv4_MAX_FRAGMENTS
|
||||
.loop:
|
||||
cmp [esi + FRAGMENT_slot.ttl], 0
|
||||
cmp [esi + IPv4_FRAGMENT_slot.ttl], 0
|
||||
je .next
|
||||
dec [esi + FRAGMENT_slot.ttl]
|
||||
dec [esi + IPv4_FRAGMENT_slot.ttl]
|
||||
jz .died
|
||||
.next:
|
||||
add esi, sizeof.FRAGMENT_slot
|
||||
add esi, sizeof.IPv4_FRAGMENT_slot
|
||||
dec ecx
|
||||
jnz .loop
|
||||
jmp .done
|
||||
@ -263,7 +263,7 @@ IPv4_input: ; TODO: add IPv4
|
||||
; Now we can update stats
|
||||
|
||||
.ip_ok:
|
||||
inc [IP_packets_rx + edi]
|
||||
inc [IPv4_packets_rx + edi]
|
||||
|
||||
;----------------------------------
|
||||
; Check if the packet is fragmented
|
||||
@ -304,7 +304,7 @@ IPv4_input: ; TODO: add IPv4
|
||||
|
||||
.dump:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
|
||||
inc [IP_packets_dumped] ; FIXME: use correct interface
|
||||
inc [IPv4_packets_dumped] ; FIXME: use correct interface
|
||||
call NET_packet_free
|
||||
add esp, 4 ; pop (balance stack)
|
||||
ret
|
||||
@ -319,7 +319,7 @@ IPv4_input: ; TODO: add IPv4
|
||||
xchg al, ah
|
||||
shl ax, 3
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x\n", ax, [edx + IPv4_header.Identification]:4
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x ptr=0x%x\n", ax, [edx + IPv4_header.Identification]:4, edx
|
||||
|
||||
test ax, ax ; Is this the first packet of the fragment?
|
||||
jz .is_first_fragment
|
||||
@ -334,24 +334,24 @@ IPv4_input: ; TODO: add IPv4
|
||||
cmp esi, -1
|
||||
je .dump
|
||||
|
||||
mov [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl
|
||||
mov esi, [esi + FRAGMENT_slot.ptr]
|
||||
mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl
|
||||
mov esi, [esi + IPv4_FRAGMENT_slot.ptr]
|
||||
or edi, -1
|
||||
.find_last_entry: ; The following routine will try to find the last entry
|
||||
cmp edi, [esi + FRAGMENT_entry.PrevPtr]
|
||||
cmp edi, [esi + IPv4_FRAGMENT_entry.PrevPtr]
|
||||
jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
|
||||
mov edi, esi
|
||||
mov esi, [esi + FRAGMENT_entry.NextPtr]
|
||||
mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
|
||||
cmp esi, -1
|
||||
jne .find_last_entry
|
||||
; We found the last entry (pointer is now in edi)
|
||||
; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
|
||||
|
||||
pop eax ; pointer to packet
|
||||
mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
|
||||
mov [eax + FRAGMENT_entry.NextPtr], -1
|
||||
mov [eax + FRAGMENT_entry.PrevPtr], edi
|
||||
mov [eax + FRAGMENT_entry.Owner], ebx
|
||||
mov [edi + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
|
||||
mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
|
||||
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
|
||||
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
|
||||
|
||||
add esp, 4
|
||||
ret
|
||||
@ -363,29 +363,29 @@ IPv4_input: ; TODO: add IPv4
|
||||
.is_first_fragment:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
|
||||
; try to locate a free slot..
|
||||
mov ecx, MAX_FRAGMENTS
|
||||
mov esi, FRAGMENT_LIST
|
||||
mov ecx, IPv4_MAX_FRAGMENTS
|
||||
mov esi, IPv4_FRAGMENT_LIST
|
||||
.find_free_slot:
|
||||
cmp word [esi + FRAGMENT_slot.ttl], 0
|
||||
cmp word [esi + IPv4_FRAGMENT_slot.ttl], 0
|
||||
je .found_free_slot
|
||||
add esi, sizeof.FRAGMENT_slot
|
||||
add esi, sizeof.IPv4_FRAGMENT_slot
|
||||
loop .find_free_slot
|
||||
jmp .dump ; If no free slot was found, dump the packet
|
||||
|
||||
.found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure
|
||||
mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
|
||||
mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
|
||||
mov ax, [edx + IPv4_header.Identification]
|
||||
mov [esi + FRAGMENT_slot.id], ax
|
||||
mov [esi + IPv4_FRAGMENT_slot.id], ax
|
||||
mov eax, [edx + IPv4_header.SourceAddress]
|
||||
mov [esi + FRAGMENT_slot.SrcIP], eax
|
||||
mov [esi + IPv4_FRAGMENT_slot.SrcIP], eax
|
||||
mov eax, [edx + IPv4_header.DestinationAddress]
|
||||
mov [esi + FRAGMENT_slot.DstIP], eax
|
||||
mov [esi + IPv4_FRAGMENT_slot.DstIP], eax
|
||||
pop eax
|
||||
mov [esi + FRAGMENT_slot.ptr], eax
|
||||
mov [esi + IPv4_FRAGMENT_slot.ptr], eax
|
||||
; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
|
||||
mov [eax + FRAGMENT_entry.NextPtr], -1
|
||||
mov [eax + FRAGMENT_entry.PrevPtr], -1
|
||||
mov [eax + FRAGMENT_entry.Owner], ebx
|
||||
mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
|
||||
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1
|
||||
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
|
||||
|
||||
add esp, 4 ; balance stack and exit
|
||||
ret
|
||||
@ -401,33 +401,33 @@ IPv4_input: ; TODO: add IPv4
|
||||
cmp esi, -1
|
||||
je .dump
|
||||
|
||||
mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
|
||||
mov esi, [esi + IPv4_FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
|
||||
push esi
|
||||
xor eax, eax
|
||||
or edi, -1
|
||||
|
||||
.count_bytes:
|
||||
cmp [esi + FRAGMENT_entry.PrevPtr], edi
|
||||
cmp [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
|
||||
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
|
||||
mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
|
||||
mov cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
|
||||
xchg cl, ch
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
|
||||
add ax, cx
|
||||
movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
|
||||
movzx cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
|
||||
and cx, 0x000F
|
||||
shl cx, 2
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
|
||||
sub ax, cx
|
||||
mov edi, esi
|
||||
mov esi, [esi + FRAGMENT_entry.NextPtr]
|
||||
mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
|
||||
cmp esi, -1
|
||||
jne .count_bytes
|
||||
|
||||
mov esi, [esp+4]
|
||||
mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
|
||||
mov [esi + FRAGMENT_entry.NextPtr], -1
|
||||
mov [esi + FRAGMENT_entry.PrevPtr], edi
|
||||
mov [esi + FRAGMENT_entry.Owner], ebx
|
||||
mov [edi + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
|
||||
mov [esi + IPv4_FRAGMENT_entry.NextPtr], -1
|
||||
mov [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
|
||||
mov [esi + IPv4_FRAGMENT_entry.Owner], ebx
|
||||
|
||||
mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length
|
||||
xchg cl, ch
|
||||
@ -454,18 +454,18 @@ IPv4_input: ; TODO: add IPv4
|
||||
mov edx, [esp+4] ; Get pointer to first fragment entry back in edx
|
||||
|
||||
.rebuild_packet_loop:
|
||||
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
|
||||
movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
|
||||
xchg cl, ch ; intel byte order
|
||||
shl cx, 3 ; multiply by 8 and clear first 3 bits
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
|
||||
|
||||
lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment
|
||||
movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
|
||||
movzx ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
|
||||
and bx, 0x000F ;
|
||||
shl bx, 2 ;
|
||||
|
||||
lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment
|
||||
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
|
||||
lea esi, [edx + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment
|
||||
movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
|
||||
xchg cl, ch ; intel byte order
|
||||
|
||||
cmp edi, eax ; Is this packet the first fragment ?
|
||||
@ -474,6 +474,8 @@ IPv4_input: ; TODO: add IPv4
|
||||
add esi, ebx ;
|
||||
.first_fragment:
|
||||
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Copying %u bytes from 0x%x to 0x%x\n", ecx, esi, edi
|
||||
push cx ; First copy dword-wise, then byte-wise
|
||||
shr cx, 2 ;
|
||||
rep movsd ;
|
||||
@ -482,11 +484,12 @@ IPv4_input: ; TODO: add IPv4
|
||||
rep movsb ;
|
||||
|
||||
push eax
|
||||
push [edx + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
|
||||
push [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
|
||||
push edx ; Push pointer to fragment onto stack
|
||||
mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
|
||||
mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx
|
||||
call NET_packet_free ; free the previous fragment buffer (this uses the value from stack)
|
||||
pop eax
|
||||
pop edx ebx eax
|
||||
cmp edx, -1 ; Check if it is last fragment in chain
|
||||
jne .rebuild_packet_loop
|
||||
|
||||
@ -494,11 +497,9 @@ IPv4_input: ; TODO: add IPv4
|
||||
xchg cl, ch
|
||||
mov edx, eax
|
||||
mov [edx + IPv4_header.TotalLength], cx
|
||||
add esp, 8
|
||||
add esp, 12
|
||||
xchg cl, ch
|
||||
push ecx
|
||||
|
||||
push eax
|
||||
push ecx edx ; size and pointer
|
||||
jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr
|
||||
|
||||
.destroy_slot_pop:
|
||||
@ -527,19 +528,19 @@ IPv4_find_fragment_slot:
|
||||
|
||||
push eax ebx ecx edx
|
||||
mov ax, [edx + IPv4_header.Identification]
|
||||
mov ecx, MAX_FRAGMENTS
|
||||
mov esi, FRAGMENT_LIST
|
||||
mov ecx, IPv4_MAX_FRAGMENTS
|
||||
mov esi, IPv4_FRAGMENT_LIST
|
||||
mov ebx, [edx + IPv4_header.SourceAddress]
|
||||
mov edx, [edx + IPv4_header.DestinationAddress]
|
||||
.find_slot:
|
||||
cmp [esi + FRAGMENT_slot.id], ax
|
||||
cmp [esi + IPv4_FRAGMENT_slot.id], ax
|
||||
jne .try_next
|
||||
cmp [esi + FRAGMENT_slot.SrcIP], ebx
|
||||
cmp [esi + IPv4_FRAGMENT_slot.SrcIP], ebx
|
||||
jne .try_next
|
||||
cmp [esi + FRAGMENT_slot.DstIP], edx
|
||||
cmp [esi + IPv4_FRAGMENT_slot.DstIP], edx
|
||||
je .found_slot
|
||||
.try_next:
|
||||
add esi, sizeof.FRAGMENT_slot
|
||||
add esi, sizeof.IPv4_FRAGMENT_slot
|
||||
loop .find_slot
|
||||
|
||||
or esi, -1
|
||||
@ -552,10 +553,9 @@ IPv4_find_fragment_slot:
|
||||
;
|
||||
; IPv4_output
|
||||
;
|
||||
; IN: eax = dest ip
|
||||
; ebx = output device ptr/0 for automatic choice
|
||||
; IN: eax = Destination IP
|
||||
; ecx = data length
|
||||
; edx = source ip
|
||||
; edx = Source IP
|
||||
; di = TTL shl 8 + protocol
|
||||
;
|
||||
; OUT: eax = pointer to buffer start
|
||||
@ -573,9 +573,9 @@ IPv4_output:
|
||||
cmp ecx, 65500 ; Max IPv4 packet size
|
||||
ja .too_large
|
||||
|
||||
push ecx eax edx di
|
||||
|
||||
call IPv4_route ; outputs device number in edi, dest ip in eax
|
||||
push ecx di eax
|
||||
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
|
||||
push edx
|
||||
|
||||
test edi, edi
|
||||
jz .loopback
|
||||
@ -586,12 +586,12 @@ IPv4_output:
|
||||
push ebx ; push the mac onto the stack
|
||||
push ax
|
||||
|
||||
inc [IP_packets_tx + edi] ; update stats
|
||||
inc [IPv4_packets_tx + edi] ; update stats
|
||||
|
||||
mov ebx, [NET_DRV_LIST + edi]
|
||||
lea eax, [ebx + ETH_DEVICE.mac]
|
||||
mov edx, esp
|
||||
mov ecx, [esp + 10 + 6]
|
||||
mov ecx, [esp + 6 + 8 + 2]
|
||||
add ecx, sizeof.IPv4_header
|
||||
mov di, ETHER_PROTO_IPv4
|
||||
call ETH_output
|
||||
@ -605,12 +605,14 @@ IPv4_output:
|
||||
mov [edi + IPv4_header.TotalLength], cx
|
||||
mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME
|
||||
mov [edi + IPv4_header.FlagsAndFragmentOffset], 0
|
||||
pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
|
||||
; [edi + IPv4_header.Protocol]
|
||||
|
||||
mov [edi + IPv4_header.HeaderChecksum], 0
|
||||
popd [edi + IPv4_header.SourceAddress]
|
||||
popd [edi + IPv4_header.DestinationAddress]
|
||||
|
||||
pop word[edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
|
||||
; [edi + IPv4_header.Protocol]
|
||||
|
||||
pop ecx
|
||||
|
||||
IPv4_checksum edi
|
||||
@ -677,7 +679,7 @@ IPv4_output_raw:
|
||||
push ebx ; push the mac
|
||||
push ax
|
||||
|
||||
inc [IP_packets_tx + 4*edi]
|
||||
inc [IPv4_packets_tx + 4*edi]
|
||||
mov ebx, [NET_DRV_LIST + 4*edi]
|
||||
lea eax, [ebx + ETH_DEVICE.mac]
|
||||
mov edx, esp
|
||||
@ -857,40 +859,44 @@ IPv4_fragment:
|
||||
; IPv4_route
|
||||
;
|
||||
; IN: eax = Destination IP
|
||||
; OUT: edi = device number*4
|
||||
; eax = ip of gateway if nescessary, unchanged otherwise
|
||||
; edx = Source IP
|
||||
; OUT: eax = Destination IP (or gateway IP)
|
||||
; edx = Source IP
|
||||
; edi = device number*4
|
||||
; DESTROYED:
|
||||
; ecx
|
||||
;
|
||||
;---------------------------------------------------------------------------
|
||||
align 4
|
||||
IPv4_route:
|
||||
IPv4_route: ; TODO: return error if no valid route found
|
||||
|
||||
cmp eax, 0xffffffff
|
||||
je .broadcast
|
||||
|
||||
xor edi, edi
|
||||
mov ecx, NET_DEVICES_MAX
|
||||
.loop:
|
||||
mov ebx, [IP_LIST + edi]
|
||||
and ebx, [SUBNET_LIST + edi]
|
||||
jz .next
|
||||
mov edx, eax
|
||||
and edx, [SUBNET_LIST+edi]
|
||||
|
||||
cmp ebx, edx
|
||||
jne .next
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
|
||||
ret
|
||||
|
||||
mov ecx, eax
|
||||
and ecx, [SUBNET_LIST + edi]
|
||||
cmp ebx, ecx
|
||||
je .got_it
|
||||
.next:
|
||||
add edi, 4
|
||||
dec ecx
|
||||
jnz .loop
|
||||
cmp edi, 4*NET_DEVICES_MAX
|
||||
jb .loop
|
||||
|
||||
.invalid:
|
||||
mov eax, [GATEWAY_LIST+4] ;;; FIXME
|
||||
mov eax, [GATEWAY_LIST + 4] ; TODO: let user (or a user space daemon) configure default route
|
||||
.broadcast:
|
||||
mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME
|
||||
mov edi, 4 ; TODO: same as above
|
||||
.got_it:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
|
||||
test edx, edx
|
||||
jnz @f
|
||||
mov edx, [IP_LIST + edi]
|
||||
@@:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -910,6 +916,45 @@ IPv4_get_frgmnt_num:
|
||||
ret
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; IPv4_connect
|
||||
;
|
||||
; IN: eax = socket pointer
|
||||
; OUT: eax = 0 ok / -1 error
|
||||
; ebx = error code
|
||||
;
|
||||
;-------------------------
|
||||
align 4
|
||||
IPv4_connect:
|
||||
|
||||
push eax edx
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
pop edx eax
|
||||
|
||||
; Fill in local IP
|
||||
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||
jne @f
|
||||
push [IP_LIST + 4] ; FIXME: use correct local IP
|
||||
pop [eax + IP_SOCKET.LocalIP]
|
||||
|
||||
; Fill in remote IP
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
; Set up data receiving queue
|
||||
push eax
|
||||
init_queue (eax + SOCKET_QUEUE_LOCATION)
|
||||
pop eax
|
||||
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;
|
||||
; IPv4_API
|
||||
@ -952,11 +997,11 @@ IPv4_api:
|
||||
ret
|
||||
|
||||
.packets_tx:
|
||||
mov eax, [IP_packets_tx + eax]
|
||||
mov eax, [IPv4_packets_tx + eax]
|
||||
ret
|
||||
|
||||
.packets_rx:
|
||||
mov eax, [IP_packets_rx + eax]
|
||||
mov eax, [IPv4_packets_rx + eax]
|
||||
ret
|
||||
|
||||
.read_ip:
|
||||
|
@ -17,6 +17,7 @@
|
||||
$Revision: 3346 $
|
||||
|
||||
ETH_FRAME_MINIMUM = 60
|
||||
ETH_QUEUE_SIZE = 255
|
||||
|
||||
struct ETH_header
|
||||
|
||||
@ -32,12 +33,40 @@ struct ETH_DEVICE NET_DEVICE
|
||||
|
||||
ends
|
||||
|
||||
struct ETH_queue_entry
|
||||
|
||||
device dd ?
|
||||
packet dd ?
|
||||
size dd ?
|
||||
|
||||
ends
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
|
||||
ETH_BROADCAST dp 0xffffffffffff
|
||||
endg
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
ETH_input_event dd ?
|
||||
ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4
|
||||
endg
|
||||
|
||||
macro ETH_init {
|
||||
|
||||
init_queue ETH_queue
|
||||
|
||||
movi ebx, 1
|
||||
mov ecx, ETH_process_input
|
||||
call new_sys_threads
|
||||
test eax, eax
|
||||
jns @f
|
||||
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
|
||||
@@:
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; ETH_input
|
||||
@ -53,8 +82,60 @@ endg
|
||||
;-----------------------------------------------------------------
|
||||
align 4
|
||||
ETH_input:
|
||||
mov eax, [esp]
|
||||
mov ecx, [esp+4]
|
||||
|
||||
push ebx
|
||||
mov esi, esp
|
||||
|
||||
pushf
|
||||
cli
|
||||
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
|
||||
popf
|
||||
|
||||
add esp, sizeof.ETH_queue_entry
|
||||
|
||||
xor edx, edx
|
||||
mov eax, [ETH_input_event]
|
||||
mov ebx, [eax + EVENT.id]
|
||||
xor esi, esi
|
||||
call raise_event
|
||||
|
||||
ret
|
||||
|
||||
.fail:
|
||||
popf
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
|
||||
|
||||
add esp, sizeof.ETH_queue_entry - 8
|
||||
call NET_packet_free
|
||||
add esp, 4
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
ETH_process_input:
|
||||
|
||||
xor esi, esi
|
||||
mov ecx, MANUAL_DESTROY
|
||||
call create_event
|
||||
mov [ETH_input_event], eax
|
||||
|
||||
.wait:
|
||||
mov eax, [ETH_input_event]
|
||||
mov ebx, [eax + EVENT.id]
|
||||
call wait_event
|
||||
|
||||
.loop:
|
||||
get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait
|
||||
|
||||
mov eax, [esi + ETH_queue_entry.packet]
|
||||
mov ecx, [esi + ETH_queue_entry.size]
|
||||
mov ebx, [esi + ETH_queue_entry.device]
|
||||
|
||||
pushd .loop ; return address
|
||||
push ecx eax
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
|
||||
sub ecx, sizeof.ETH_header
|
||||
@ -78,7 +159,7 @@ ETH_input:
|
||||
cmp ax, ETHER_PROTO_PPP_SESSION
|
||||
je PPPoE_session_input
|
||||
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH_input: Unknown packet type=%x\n", ax
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
|
||||
|
||||
.dump:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
|
||||
|
@ -310,15 +310,16 @@ ICMP_input:
|
||||
ret
|
||||
|
||||
|
||||
if 0
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; ICMP_output
|
||||
;
|
||||
; IN: eax = dest ip
|
||||
; ebx = source ip
|
||||
; bh = type
|
||||
; bl = code
|
||||
; ecx = data length
|
||||
; dh = type
|
||||
; dl = code
|
||||
; edx = source ip
|
||||
; esi = data offset
|
||||
; edi = identifier shl 16 + sequence number
|
||||
;
|
||||
@ -328,10 +329,7 @@ ICMP_output:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
|
||||
|
||||
push esi edi dx
|
||||
|
||||
mov edx, [eax + IP_SOCKET.LocalIP]
|
||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||
push esi edi bx
|
||||
add ecx, sizeof.ICMP_header
|
||||
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
||||
call IPv4_output
|
||||
@ -374,13 +372,14 @@ ICMP_output:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
|
||||
add esp, 2*4 + 2
|
||||
ret
|
||||
end if
|
||||
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; ICMP_output
|
||||
; ICMP_output_raw
|
||||
;
|
||||
; IN: eax = socket ptr
|
||||
; ecx = data length
|
||||
|
@ -39,6 +39,7 @@ struct SOCKET
|
||||
|
||||
snd_proc dd ?
|
||||
rcv_proc dd ?
|
||||
connect_proc dd ?
|
||||
|
||||
ends
|
||||
|
||||
@ -131,6 +132,7 @@ struct TCP_SOCKET IP_SOCKET
|
||||
timer_persist dd ?
|
||||
timer_keepalive dd ? ; keepalive/syn timeout
|
||||
timer_timed_wait dd ? ; also used as 2msl timer
|
||||
timer_connect dd ?
|
||||
|
||||
; extra
|
||||
|
||||
@ -142,13 +144,13 @@ struct TCP_SOCKET IP_SOCKET
|
||||
temp_bits db ?
|
||||
rb 3 ; align
|
||||
|
||||
|
||||
ends
|
||||
|
||||
struct UDP_SOCKET IP_SOCKET
|
||||
|
||||
LocalPort dw ? ; network byte order
|
||||
RemotePort dw ? ; network byte order
|
||||
firstpacket db ?
|
||||
|
||||
ends
|
||||
|
||||
@ -309,6 +311,7 @@ SOCKET_open:
|
||||
mov [eax + SOCKET.Domain], ecx
|
||||
mov [eax + SOCKET.Type], edx
|
||||
mov [eax + SOCKET.Protocol], esi
|
||||
mov [eax + SOCKET.connect_proc], connect_notsupp
|
||||
|
||||
cmp ecx, AF_INET4
|
||||
jne .no_inet4
|
||||
@ -357,6 +360,7 @@ align 4
|
||||
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
|
||||
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
|
||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||
mov [eax + SOCKET.connect_proc], UDP_connect
|
||||
ret
|
||||
|
||||
align 4
|
||||
@ -364,6 +368,7 @@ align 4
|
||||
mov [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||
mov [eax + SOCKET.snd_proc], SOCKET_send_tcp
|
||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream
|
||||
mov [eax + SOCKET.connect_proc], TCP_connect
|
||||
|
||||
TCP_init_socket eax
|
||||
ret
|
||||
@ -373,6 +378,7 @@ align 4
|
||||
.raw_ip:
|
||||
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
|
||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||
mov [eax + SOCKET.connect_proc], IPv4_connect
|
||||
ret
|
||||
|
||||
|
||||
@ -380,6 +386,7 @@ align 4
|
||||
.raw_icmp:
|
||||
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
|
||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||
mov [eax + SOCKET.connect_proc], IPv4_connect
|
||||
ret
|
||||
|
||||
align 4
|
||||
@ -414,6 +421,9 @@ SOCKET_bind:
|
||||
cmp esi, 2
|
||||
jb .invalid
|
||||
|
||||
cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once
|
||||
jnz .invalid
|
||||
|
||||
cmp word [edx], AF_INET4
|
||||
je .af_inet4
|
||||
|
||||
@ -449,17 +459,21 @@ SOCKET_bind:
|
||||
|
||||
.tcp:
|
||||
.udp:
|
||||
mov ebx, [edx + 4] ; First, fill in the IP
|
||||
test ebx, ebx ; If IP is 0, use default
|
||||
jnz @f
|
||||
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i
|
||||
@@:
|
||||
mov [eax + IP_SOCKET.LocalIP], ebx
|
||||
|
||||
mov bx, [edx + 2] ; Now fill in the local port if it's still available
|
||||
call SOCKET_check_port
|
||||
jz .addrinuse ; ZF is set by socket_check_port, on error
|
||||
pushd [edx + 4] ; First, fill in the IP
|
||||
popd [eax + IP_SOCKET.LocalIP]
|
||||
|
||||
mov bx, [edx + 2] ; Did caller specify a local port?
|
||||
test bx, bx
|
||||
jnz .just_check
|
||||
call SOCKET_find_port ; Nope, find an ephemeral one
|
||||
jmp .done
|
||||
|
||||
.just_check:
|
||||
call SOCKET_check_port ; Yes, check if it's still available
|
||||
jz .addrinuse ; ZF is set by socket_check_port on error
|
||||
|
||||
.done:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
|
||||
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
|
||||
[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
|
||||
@ -496,8 +510,18 @@ SOCKET_connect:
|
||||
cmp esi, 8
|
||||
jb .invalid
|
||||
|
||||
cmp word [edx], AF_INET4
|
||||
je .af_inet4
|
||||
cmp [eax + SOCKET.state], SS_ISCONNECTING
|
||||
je .already
|
||||
|
||||
test [eax + SOCKET.options], SO_ACCEPTCON
|
||||
jnz .notsupp
|
||||
|
||||
call [eax + SOCKET.connect_proc]
|
||||
|
||||
mov dword[esp+20], ebx
|
||||
mov dword[esp+32], eax
|
||||
ret
|
||||
|
||||
|
||||
.notsupp:
|
||||
mov dword[esp+20], EOPNOTSUPP
|
||||
@ -509,150 +533,16 @@ SOCKET_connect:
|
||||
mov dword[esp+32], -1
|
||||
ret
|
||||
|
||||
.af_inet4:
|
||||
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||
jne @f
|
||||
push [IP_LIST + 4] ; FIXME !i!i!i!
|
||||
pop [eax + IP_SOCKET.LocalIP]
|
||||
@@:
|
||||
|
||||
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
|
||||
je .udp
|
||||
|
||||
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||
je .tcp
|
||||
|
||||
cmp [eax + SOCKET.Protocol], IP_PROTO_IP
|
||||
je .ip
|
||||
|
||||
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
|
||||
je .ip
|
||||
|
||||
jmp .notsupp
|
||||
|
||||
align 4
|
||||
.udp:
|
||||
pusha
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
popa
|
||||
|
||||
pushw [edx + 2]
|
||||
pop [eax + UDP_SOCKET.RemotePort]
|
||||
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
cmp [eax + UDP_SOCKET.LocalPort], 0
|
||||
jne @f
|
||||
call SOCKET_find_port
|
||||
@@:
|
||||
|
||||
mov [eax + UDP_SOCKET.firstpacket], 0
|
||||
|
||||
push eax
|
||||
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
|
||||
pop eax
|
||||
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
|
||||
mov dword[esp+32], 0
|
||||
ret
|
||||
|
||||
align 4
|
||||
.tcp:
|
||||
pusha
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
popa
|
||||
|
||||
pushw [edx + 2]
|
||||
pop [eax + TCP_SOCKET.RemotePort]
|
||||
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
cmp [eax + TCP_SOCKET.LocalPort], 0
|
||||
jne @f
|
||||
call SOCKET_find_port
|
||||
@@:
|
||||
|
||||
mov [eax + TCP_SOCKET.timer_persist], 0
|
||||
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
|
||||
|
||||
push [TCP_sequence_num]
|
||||
add [TCP_sequence_num], 6400
|
||||
pop [eax + TCP_SOCKET.ISS]
|
||||
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
|
||||
|
||||
TCP_sendseqinit eax
|
||||
; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
|
||||
|
||||
mov ebx, eax
|
||||
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||
call SOCKET_ring_create ; TODO: check if memory was available or not
|
||||
|
||||
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||
call SOCKET_ring_create ; TODO: same here
|
||||
|
||||
pusha
|
||||
lea ecx, [ebx + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
popa
|
||||
|
||||
push ebx
|
||||
mov eax, ebx
|
||||
call TCP_output
|
||||
pop eax
|
||||
|
||||
.block:
|
||||
test [eax + SOCKET.options], SO_NONBLOCK
|
||||
jz .loop
|
||||
|
||||
mov dword[esp+20], EWOULDBLOCK
|
||||
.already:
|
||||
mov dword[esp+20], EALREADY
|
||||
mov dword[esp+32], -1
|
||||
ret
|
||||
|
||||
.loop:
|
||||
cmp [eax + TCP_SOCKET.t_state], TCPS_CLOSED
|
||||
je .fail
|
||||
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
|
||||
je .established
|
||||
ja .fail
|
||||
|
||||
call SOCKET_block
|
||||
jmp .loop
|
||||
|
||||
.fail:
|
||||
mov eax, [eax + SOCKET.errorcode]
|
||||
mov [esp+20], eax
|
||||
mov dword[esp+32], -1
|
||||
ret
|
||||
|
||||
.established:
|
||||
mov dword[esp+32], 0
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
.ip:
|
||||
pusha
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
popa
|
||||
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
push eax
|
||||
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
|
||||
pop eax
|
||||
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
|
||||
mov dword[esp+32], 0
|
||||
connect_notsupp:
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, EOPNOTSUPP
|
||||
ret
|
||||
|
||||
|
||||
@ -865,15 +755,15 @@ SOCKET_receive:
|
||||
call [eax + SOCKET.rcv_proc]
|
||||
pop edi
|
||||
|
||||
test [eax + SOCKET.state], SS_CANTRCVMORE
|
||||
jnz .return
|
||||
|
||||
cmp ebx, EWOULDBLOCK
|
||||
jne .return
|
||||
|
||||
test edi, MSG_DONTWAIT
|
||||
jnz .return_err
|
||||
|
||||
test [eax + SOCKET.state], SS_CANTRCVMORE
|
||||
jnz .return_err
|
||||
|
||||
; test [eax + SOCKET.options], SO_NONBLOCK
|
||||
; jnz .return_err
|
||||
|
||||
@ -885,10 +775,10 @@ SOCKET_receive:
|
||||
push EINVAL
|
||||
pop ebx
|
||||
.return_err:
|
||||
mov eax, -1
|
||||
mov ecx, -1
|
||||
.return:
|
||||
mov [esp+20], ebx
|
||||
mov [esp+32], eax
|
||||
mov [esp+32], ecx
|
||||
ret
|
||||
|
||||
|
||||
@ -909,7 +799,7 @@ SOCKET_receive_dgram:
|
||||
cmp ecx, ebx ; If data segment does not fit in applications buffer, abort
|
||||
ja .too_small
|
||||
|
||||
push ecx
|
||||
push eax ecx
|
||||
push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later
|
||||
mov esi, [esi + socket_queue_entry.data_ptr]
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
|
||||
@ -930,12 +820,12 @@ SOCKET_receive_dgram:
|
||||
.nd:
|
||||
|
||||
call NET_packet_free
|
||||
pop eax ; return number of bytes copied to application
|
||||
pop ecx eax ; return number of bytes copied to application
|
||||
xor ebx, ebx
|
||||
ret
|
||||
|
||||
.too_small:
|
||||
mov eax, -1
|
||||
mov ecx, -1
|
||||
push EMSGSIZE
|
||||
pop ebx
|
||||
ret
|
||||
@ -980,21 +870,23 @@ SOCKET_receive_stream:
|
||||
mov edi, edx
|
||||
xor edx, edx
|
||||
|
||||
push eax
|
||||
add eax, STREAM_SOCKET.rcv
|
||||
call SOCKET_ring_read ; copy data from kernel buffer to application buffer
|
||||
call SOCKET_ring_free ; free read memory
|
||||
pop eax
|
||||
|
||||
mov eax, ecx ; return number of bytes copied
|
||||
xor ebx, ebx ; errorcode = 0 (no error)
|
||||
ret
|
||||
|
||||
.wouldblock:
|
||||
push EWOULDBLOCK
|
||||
pop ebx
|
||||
xor ecx, ecx
|
||||
ret
|
||||
|
||||
.peek:
|
||||
mov eax, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
|
||||
mov ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
|
||||
xor ebx, ebx
|
||||
ret
|
||||
|
||||
@ -2193,6 +2085,7 @@ SOCKET_num_to_ptr:
|
||||
mov eax, [eax + SOCKET.NextPtr]
|
||||
or eax, eax
|
||||
jz .error
|
||||
diff16 "tetten", 0, $
|
||||
cmp [eax + SOCKET.Number], ecx
|
||||
jne .next_socket
|
||||
|
||||
@ -2321,6 +2214,11 @@ SOCKET_check_owner:
|
||||
align 4
|
||||
SOCKET_process_end:
|
||||
|
||||
cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all?
|
||||
je .quickret ; nope, exit immediately
|
||||
|
||||
; TODO: run the following code in another thread, to avoid deadlock
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
|
||||
|
||||
pusha
|
||||
@ -2371,6 +2269,7 @@ SOCKET_process_end:
|
||||
call mutex_unlock
|
||||
popa
|
||||
|
||||
.quickret:
|
||||
ret
|
||||
|
||||
|
||||
@ -2390,10 +2289,10 @@ SOCKET_is_connecting:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax
|
||||
|
||||
and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
|
||||
or [eax + SOCKET.options], SS_ISCONNECTING
|
||||
and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
|
||||
or [eax + SOCKET.state], SS_ISCONNECTING
|
||||
|
||||
jmp SOCKET_notify
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
@ -115,6 +115,7 @@ MAX_backlog = 20 ; maximum backlog for stream sockets
|
||||
|
||||
; Error Codes
|
||||
ENOBUFS = 1
|
||||
EINPROGRESS = 2
|
||||
EOPNOTSUPP = 4
|
||||
EWOULDBLOCK = 6
|
||||
ENOTCONN = 9
|
||||
@ -125,6 +126,7 @@ ENOMEM = 18
|
||||
EADDRINUSE = 20
|
||||
ECONNREFUSED = 61
|
||||
ECONNRESET = 52
|
||||
EISCONN = 56
|
||||
ETIMEDOUT = 60
|
||||
ECONNABORTED = 53
|
||||
|
||||
@ -248,6 +250,8 @@ stack_init:
|
||||
mov ecx, (NET_DEVICES_MAX + 2)
|
||||
rep stosd
|
||||
|
||||
ETH_init
|
||||
|
||||
PPPoE_init
|
||||
|
||||
IPv4_init
|
||||
|
@ -71,6 +71,8 @@ TCP_time_rtt_default = 5 ; default Round Trip Time (3,2s)
|
||||
TCP_time_srtt_default = 0 ;
|
||||
TCP_time_max_idle = 8*TCP_time_keep_interval ; FIXME
|
||||
|
||||
TCP_time_connect = 300 ; in 1/100s (default=3s)
|
||||
|
||||
; timer constants
|
||||
TCP_max_rxtshift = 12 ; max retransmissions waiting for ACK
|
||||
TCP_max_keepcnt = 8 ; max keepalive probes
|
||||
|
@ -437,8 +437,6 @@ TCP_send:
|
||||
; Create the IP packet
|
||||
|
||||
mov ecx, esi
|
||||
|
||||
mov ebx, [eax + SOCKET.device]
|
||||
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
|
||||
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
|
||||
mov di, IP_PROTO_TCP shl 8 + 128
|
||||
|
@ -74,6 +74,137 @@ TCP_usrclosed:
|
||||
ret
|
||||
|
||||
|
||||
;-------------------------
|
||||
;
|
||||
; TCP_connect
|
||||
;
|
||||
; IN: eax = socket ptr
|
||||
; OUT: eax = 0 ok / -1 error
|
||||
; ebx = error code
|
||||
;
|
||||
;-------------------------
|
||||
align 4
|
||||
TCP_connect:
|
||||
|
||||
test [eax + SOCKET.state], SS_ISCONNECTED
|
||||
jnz .eisconn
|
||||
|
||||
push eax edx
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
pop edx eax
|
||||
|
||||
; Fill in local IP
|
||||
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||
jne @f
|
||||
push [IP_LIST + 4] ; FIXME: use correct local IP
|
||||
pop [eax + IP_SOCKET.LocalIP]
|
||||
|
||||
; Fill in remote port and IP
|
||||
pushw [edx + 2]
|
||||
pop [eax + TCP_SOCKET.RemotePort]
|
||||
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
; Find a local port, if user didnt define one
|
||||
cmp [eax + TCP_SOCKET.LocalPort], 0
|
||||
jne @f
|
||||
call SOCKET_find_port
|
||||
@@:
|
||||
|
||||
; Start the TCP sequence
|
||||
mov [eax + TCP_SOCKET.timer_persist], 0
|
||||
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
|
||||
|
||||
push [TCP_sequence_num]
|
||||
add [TCP_sequence_num], 6400
|
||||
pop [eax + TCP_SOCKET.ISS]
|
||||
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
|
||||
|
||||
TCP_sendseqinit eax
|
||||
|
||||
mov ebx, eax
|
||||
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||
call SOCKET_ring_create
|
||||
test eax, eax
|
||||
jz .nomem
|
||||
|
||||
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||
call SOCKET_ring_create
|
||||
test eax, eax
|
||||
jz .nomem
|
||||
|
||||
push ebx
|
||||
lea ecx, [ebx + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
pop eax
|
||||
|
||||
call SOCKET_is_connecting
|
||||
|
||||
; Now send the SYN packet to remote end
|
||||
push eax
|
||||
call TCP_output
|
||||
pop eax
|
||||
|
||||
.block:
|
||||
test [eax + SOCKET.options], SO_NONBLOCK
|
||||
jz .waitforit
|
||||
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, EINPROGRESS
|
||||
ret
|
||||
|
||||
.nomem:
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, ENOMEM
|
||||
ret
|
||||
|
||||
.eisconn:
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, EISCONN
|
||||
ret
|
||||
|
||||
.waitforit:
|
||||
push eax
|
||||
stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
|
||||
pop ebx
|
||||
mov [ebx + TCP_SOCKET.timer_connect], eax
|
||||
mov eax, ebx
|
||||
|
||||
.loop:
|
||||
cmp [eax + SOCKET.errorcode], 0
|
||||
jne .fail
|
||||
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
|
||||
je .established
|
||||
|
||||
call SOCKET_block
|
||||
jmp .loop
|
||||
|
||||
.timeout:
|
||||
mov eax, [esp+4]
|
||||
mov [eax + SOCKET.errorcode], ETIMEDOUT
|
||||
and [eax + SOCKET.state], not SS_ISCONNECTING
|
||||
call SOCKET_notify.unblock
|
||||
ret 4
|
||||
|
||||
.fail:
|
||||
mov ebx, [eax + SOCKET.errorcode]
|
||||
mov [eax + SOCKET.errorcode], 0 ; Clear the error, we only need to send it to the caller once
|
||||
xor eax, eax
|
||||
dec eax
|
||||
ret
|
||||
|
||||
.established:
|
||||
stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
;-------------------------
|
||||
|
@ -182,7 +182,7 @@ UDP_input:
|
||||
;
|
||||
; FIXME: UDP should check remote IP, but not under all circumstances!
|
||||
|
||||
cmp [eax + UDP_SOCKET.firstpacket], 0
|
||||
cmp [eax + UDP_SOCKET.RemotePort], 0
|
||||
je .updateport
|
||||
|
||||
cmp [eax + UDP_SOCKET.RemotePort], cx
|
||||
@ -211,8 +211,6 @@ UDP_input:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
|
||||
mov [eax + UDP_SOCKET.RemotePort], cx
|
||||
inc [eax + UDP_SOCKET.firstpacket]
|
||||
|
||||
jmp .updatesock
|
||||
|
||||
.dump_:
|
||||
@ -262,7 +260,6 @@ UDP_output:
|
||||
|
||||
sub esp, 8 ; Data ptr and data size will be placed here
|
||||
push edx esi
|
||||
mov ebx, [eax + SOCKET.device]
|
||||
mov edx, [eax + IP_SOCKET.LocalIP]
|
||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||
mov di, IP_PROTO_UDP shl 8 + 128
|
||||
@ -311,6 +308,84 @@ UDP_output:
|
||||
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; UDP_connect
|
||||
;
|
||||
; IN: eax = socket pointer
|
||||
; OUT: eax = 0 ok / -1 error
|
||||
; ebx = error code
|
||||
;
|
||||
;-------------------------
|
||||
align 4
|
||||
UDP_connect:
|
||||
|
||||
test [eax + SOCKET.state], SS_ISCONNECTED
|
||||
jz @f
|
||||
call UDP_disconnect
|
||||
@@:
|
||||
|
||||
push eax edx
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_lock
|
||||
pop edx eax
|
||||
|
||||
; Fill in local IP
|
||||
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||
jne @f
|
||||
push [IP_LIST + 4] ; FIXME: use correct local IP
|
||||
pop [eax + IP_SOCKET.LocalIP]
|
||||
|
||||
; Fill in remote port and IP, overwriting eventually previous values
|
||||
pushw [edx + 2]
|
||||
pop [eax + UDP_SOCKET.RemotePort]
|
||||
|
||||
pushd [edx + 4]
|
||||
pop [eax + IP_SOCKET.RemoteIP]
|
||||
|
||||
; Find a local port, if user didnt define one
|
||||
cmp [eax + UDP_SOCKET.LocalPort], 0
|
||||
jne @f
|
||||
call SOCKET_find_port
|
||||
@@:
|
||||
|
||||
push eax
|
||||
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
|
||||
pop eax
|
||||
|
||||
push eax
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
pop eax
|
||||
|
||||
call SOCKET_is_connected
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; UDP_disconnect
|
||||
;
|
||||
; IN: eax = socket pointer
|
||||
; OUT: eax = socket pointer
|
||||
;
|
||||
;-------------------------
|
||||
align 4
|
||||
UDP_disconnect:
|
||||
|
||||
; TODO: remove the pending received data
|
||||
|
||||
call SOCKET_is_disconnected
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;
|
||||
; UDP_API
|
||||
|
Loading…
Reference in New Issue
Block a user