Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6235 → Rev 6240

/kernel/branches/Kolibri-acpi/boot/shutdown.inc
15,7 → 15,14
 
use32
become_real:
xor ebx, ebx
xor edx, edx
xor ecx, ecx
xor esi, esi
xor edi, edi
xor ebp, ebp
cli
ltr bx
lgdt [realmode_gdt-OS_BASE]
jmp 8:@f
use16
34,9 → 41,10
pr_mode_exit:
 
; setup stack
mov ax, 0x3000
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
mov ss, ax
mov esp, 0x0EC00
mov esp, TMP_STACK_TOP and 0xFFFF
 
; setup ds
push cs
pop ds
173,31 → 181,41
 
mov ax, 0x0003 ; set text mode for screen
int 0x10
jmp 0x4000:0000
jmp 0x5000:0000
 
restart_kernel_4000:
restart_kernel_5001:
cli
 
push ds
pop es
mov cx, 0x8000
push cx
xor si, si
xor di, di
 
push 0x7100
pop ds
xor si, si
xor di, di
rep movsw
pop cx
mov ds, cx
mov cx, 0x4000
rep movsd
 
push 0x8100
pop ds
push 0x2000
pop es
rep movsw
push 0x9000
mov cx, 0x4000
rep movsd
 
push 0x9100
pop ds
push 0x3000
pop es
mov cx, 0xE000/2
rep movsw
mov cx, 0x4000
rep movsd
xchg bx, bx
push 0xA100
pop ds
push 0x4000
pop es
mov cx, 0x800
rep movsd
 
wbinvd ; write and invalidate cache
 
/kernel/branches/Kolibri-acpi/const.inc
358,6 → 358,10
STDOUT_FILENO equ 1
STDERR_FILENO equ 2
 
SYSTEM_SHUTDOWN equ 2
SYSTEM_REBOOT equ 3
SYSTEM_RESTART equ 4
 
struct SYSCALL_STACK
_eip dd ?
_edi dd ? ; +4
/kernel/branches/Kolibri-acpi/core/sync.inc
132,10 → 132,10
jnz .futex_wait_timeout
mov ecx, [ebp+FUTEX.pointer]
mov eax, edx
lock cmpxchg [ecx], edx ;wait until old_value == new_value
jz .wait_slow
lock cmpxchg [ecx], edx
je .wait_slow
 
mov [esp+SYSCALL_STACK._eax], 0
mov [esp+SYSCALL_STACK._eax], -2
ret
 
.wait_slow:
148,13 → 148,13
lea esi, [ebp+FUTEX.wait_list]
 
list_add_tail esp, esi ;esp= new waiter, esi= list head
 
mov eax, edx
.again:
mov [ebx+TASKDATA.state], 1
call change_task
 
lock cmpxchg [ecx], edx
jz .again
je .again
 
list_del esp
add esp, sizeof.MUTEX_WAITER
174,9 → 174,9
mov ecx, [ebp+FUTEX.pointer]
mov eax, edx
lock cmpxchg [ecx], edx ;wait until old_value == new_value
jz .wait_slow_timeout
je .wait_slow_timeout
 
mov [esp+SYSCALL_STACK._eax], 0
mov [esp+SYSCALL_STACK._eax], -2
ret
 
align 4
210,6 → 210,7
test eax, eax
jz .timeout
 
mov eax, edx
lock cmpxchg [ecx], edx
jz .again_timeout
@@:
231,7 → 232,7
 
align 4
;ecx futex handle
;edx numder of threads
;edx number of threads
;edi current process
;ebp futex object
.futex_wake:
/kernel/branches/Kolibri-acpi/core/taskman.inc
940,13 → 940,7
mov ecx, 11
rep movsb ;copy process name
 
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
 
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
 
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
959,6 → 953,13
@@:
mov [edx+APPDATA.tls_base], eax
 
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
 
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
 
lea eax, [app_cmdline]
stdcall set_app_params , [slot], eax, dword 0, \
dword 0, [flags]
/kernel/branches/Kolibri-acpi/data32.inc
173,11 → 173,12
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file_load:
; load kernel.mnt to 0x7000:0
 
; load kernel.mnt to _CLEAN_ZONE
dd 0 ; subfunction
dq 0 ; offset in file
dd 0x30000 ; number of bytes to read
dd OS_BASE + 0x71000 ; buffer for data
dd 0x31000 ; number of bytes to read
dd _CLEAN_ZONE ; buffer for data
db '/RD/1/KERNEL.MNT',0
 
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
25,11 → 25,11
* ecx = [координата по оси y]*65536 + [размер по оси y]
* edx = 0xXYRRGGBB, где:
* Y = стиль окна:
* Y=0 - тип I - окно фиксированных размеров
* Y=1 - только определить область окна, ничего не рисовать
* Y=2 - тип II - окно изменяемых размеров
* Y=3 - окно со скином
* Y=4 - окно со скином фиксированных размеров
* Y=0,2 эти стили являются устаревшими и не должны более использоваться,
они оставлены для совместимости со старыми приложениями
* остальные возможные значения (от 5 до 15) зарезервированы,
вызов функции с такими Y игнорируется
* RR, GG, BB = соответственно красная, зеленая, синяя
36,9 → 36,7
составляющие цвета рабочей области окна
(игнорируется для стиля Y=1)
* X = DCBA (биты)
* A = 1 - у окна есть заголовок; для стилей Y=3,4 адрес строки
заголовка задаётся в edi, для прочих стилей
используется подфункция 1 функции 71
* A = 1 - у окна есть заголовок
* B = 1 - координаты всех графических примитивов задаются
относительно клиентской области окна
* C = 1 - не закрашивать рабочую область при отрисовке окна
52,7 → 50,7
X=8 - обычный градиент,
для окон типа II X=4 - негативный градиент
* прочие значения X и Y зарезервированы
* edi = 0x00RRGGBB - цвет рамки
* edi = адрес строки заголовка для стилей Y=3,4 (также см. функцию 71.1)
Возвращаемое значение:
* функция не возвращает значения
Замечания:
82,35 → 80,9
* Размеры окна понимаются в смысле координат правого нижнего угла.
Это же относится и ко всем остальным функциям.
Это означает, что реальные размеры на 1 пиксель больше.
* Вид окна типа I:
* рисуется внешняя рамка цвета, указанного в edi,
шириной 1 пиксель
* рисуется заголовок - прямоугольник с левым верхним углом (1,1)
и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
(с учетом градиента)
* если ysize>21, то закрашивается рабочая область окна -
прямоугольник с левым верхним углом (1,21) и правым нижним
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
указанным в edx (с учетом градиента)
* если A=1 и строка заголовка установлена подфункцией 1
функции 71, то она выводится в соответствующем месте заголовка
* Вид окна стиля Y=1:
* полностью определяется приложением
* Вид окна типа II:
* рисуется внешняя рамка шириной 1 пиксель "затенённого" цвета
edi (все составляющие цвета уменьшаются в два раза)
* рисуется промежуточная рамка шириной 3 пикселя цвета edi
* рисуется внутренняя рамка шириной 1 пиксель
"затенённого" цвета edi
* рисуется заголовок - прямоугольник с левым верхним углом (4,4)
и правым нижним (xsize-4,min(20,ysize)) цвета, указанного в esi
(с учетом градиента)
* если ysize>=26, то закрашивается рабочая область окна -
прямоугольник с левым верхним углом (5,20) и правым нижним
(xsize-5,ysize-5) - цветом, указанным в edx (с учетом градиента)
* если A=1 и строка заголовка установлена подфункцией 1
функции 71, то она выводится в соответствующем месте заголовка
* Вид окна со скином:
* Вид окна со скином Y=3,4:
* рисуется внешняя рамка шириной 1 пиксель
цвета 'outer' из скина
* рисуется промежуточная рамка шириной 3 пикселя
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
25,19 → 25,17
* ecx = [coordinate on axis y]*65536 + [size on axis y]
* edx = 0xXYRRGGBB, where:
* Y = style of the window:
* Y=0 - type I - fixed-size window
* Y=1 - only define window area, draw nothing
* Y=2 - type II - variable-size window
* Y=3 - skinned window
* Y=4 - skinned fixed-size window
* other possible values (from 5 up to 15) are reserved,
* Y=0,2 window types are outdated and should not be used anymore,
they are retained for compatibility with old programs.
* other possible values (from 5 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=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
subfunction 1 of function 71
* A = 1 - window has caption
* B = 1 - coordinates of all graphics primitives are relative to
window client area
* C = 1 - don't fill working area on window draw
47,11 → 45,8
* esi = 0xXYRRGGBB - color of the header
* RR, GG, BB define color
* 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
* other values of X and Y are reserved
* edi = 0x00RRGGBB - color of the frame
* X not used, other values of Y are reserved
* edi = caption string for styles Y=3,4 (also can be set by func 71.1)
Returned value:
* function does not return value
Remarks:
79,34 → 74,9
* The sizes of the window are understood in sence of coordinates
of the right lower corner. This concerns all other functions too.
It means, that the real sizes are on 1 pixel more.
* The window of type I looks as follows:
* draw external frame of color indicated in edi, 1 pixel in width
* draw header - rectangle with the left upper corner (1,1) and
right lower (xsize-1,min(20,ysize-1)) color indicated in esi
(taking a gradient into account)
* if ysize>21, fill the working area of the window -
rectangle with the left upper corner (1,21) and right lower
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
indicated in edx (taking a gradient into account)
* if A=1 and caption has been already set by subfunction 1
of function 71, it is drawn in the corresponding place of header
* The window of style Y=1 looks as follows:
* completely defined by the application
* The window of type II looks as follows:
* draw external frame of width 1 pixel with the "shaded" color
edi (all components of the color decrease twice)
* draw intermediate frame of width 3 pixels with color edi
* draw internal frame of width 1 pixel with the "shaded" color edi
* draw header - rectangle with the left upper corner (4,4)
and right lower (xsize-4,min(20,ysize)) color, indicated in esi
(taking a gradient into account)
* if ysize>=26, fill the working area of the window -
rectangle with the left upper corner (5,20) and right lower
(xsize-5,ysize-5) with color indicated in edx
(taking a gradient into account)
* if A=1 and caption has been already set by subfunction 1
of function 71, it is drawn in the corresponding place of header
* The skinned window looks as follows:
* The skinned window Y=3,4 looks as follows:
* draw external frame of width 1 pixel
with color 'outer' from the skin
* draw intermediate frame of width 3 pixel
4794,15 → 4764,32
* edx = control value
* esi = timeout in system ticks or 0 for infinity
Returned value:
* eax = 0 - successfull, -1 on timeout
 
* eax = 0 - successfull
-1 - timeout
-2 - futex dword does not have the same value as edx
Remarks:
* This operation tests that the value at the futex dword still
* This functionn tests that the value at the futex dword still
contains the expected control value, and if so, then sleeps
waiting for a wake operation on the futex.
* The futex handle must have been created by subfunction 0
 
======================================================================
=============== Function 77, Subfunction 3, Futex wake ===============
======================================================================
Parameters:
* eax = 77 - function number
* ebx = 3 - subfunction number
* ecx = futex handle
* edx = number of waiters to wake
Returned value:
* eax = number of waiters that were woken up
 
Remarks:
* This function wakes at most edx of the waiters that are
waiting (e.g., inside futex wait) on the futex dword
* The futex handle must have been created by subfunction 0
 
======================================================================
=============== Function -1 - terminate thread/process ===============
======================================================================
Parameters:
/kernel/branches/Kolibri-acpi/fs/ntfs.inc
48,9 → 48,12
nameOffset = 10
attributeFlags = 12
attributeID = 14
sizeWithoutHeader = 16
; resident attribute header
sizeWithoutHeader = 10h
; attributeOffset = 14h
indexedFlag = 16h
; non resident attribute header
firstVCN = 10h
lastVCN = 18h
dataRunsOffset = 20h
attributeAllocatedSize = 28h
439,6 → 442,9
mov eax, [ebp+NTFS.ntfs_cur_read]
cmp eax, 4
jc .failFreeBitmapMFT
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz .failFreeBitmapMFT
mov [ebp+NTFS.mftBitmapSize], eax
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.mftBitmapLocation], eax
657,18 → 663,19
jc .errret
; 2. Find required attribute.
mov eax, [ebp+NTFS.frs_buffer]
; a) For auxiliary records, read base record
; N.B. If base record is present,
; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
; a) For auxiliary records, read base record.
; If base record is present, base iRecord may be 0 (for $Mft),
; but SequenceNumber is nonzero.
cmp dword [eax+24h], 0
jz @f
mov eax, [eax+20h]
; test eax, eax
; jz @f
.beginfindattr:
mov [ebp+NTFS.ntfs_attr_iRecord], eax
call ntfs_read_file_record
jc .errret
jmp @f
.newAttribute:
pushad
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ebp+NTFS.frs_buffer]
1070,7 → 1077,7
 
ntfs_read_file_record:
; in: eax = iRecord
; out: [ebp+NTFS.frs_buffer] = record data
; out: [ebp+NTFS.frs_buffer] -> file record
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
push ecx edx
1135,6 → 1142,9
ntfs_restore_usa_frs:
mov eax, [ebp+NTFS.frs_size]
ntfs_restore_usa:
; in:
; ebx -> record
; eax = size in bytes
pushad
shr eax, 9
mov ecx, eax
1163,13 → 1173,13
 
ntfs_decode_mcb_entry:
; in:
; esi -> mcb entry
; esi -> MCB entry
; esp -> buffer (16 bytes)
; out:
; esi -> next mcb entry
; esi -> next MCB entry
; esp -> data run size
; esp+8 -> cluster (delta)
; CF=0 -> mcb end
; CF=0 -> MCB end
push eax ecx edi
lea edi, [esp+16]
xor eax, eax
1999,59 → 2009,79
@@: ; 1. Search file
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jnc .found
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
test eax, eax
jz ntfsFail
jmp .notFound
 
.found: ; rewrite
jc .notFound
; found, rewrite
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.ntfsFolder], 1
jz ntfsDenied
jz .folder
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
cmp dword [edi], 'INDX'
jz @f
mov esi, [ebp+NTFS.frs_buffer]
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
add eax, esi
@@:
mov edx, [ebx+12]
mov [eax+fileRealSize], edx
mov dword [eax+fileRealSize+4], 0
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jc ntfsDenied
mov eax, [ebp+NTFS.frs_buffer]
cmp word [eax+baseRecordReuse], 0
jc ntfsFail
mov ecx, [ebp+NTFS.frs_buffer]
mov eax, edx
xor edx, edx
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
cmp byte [eax+hardLinkCounter], 1
jnz ntfsUnsupported ; file copying required
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz ntfsUnsupported ; resident $DATA
mov eax, [ebx+4]
mov edx, [ebx+8]
add eax, [ebx+12]
adc edx, 0
cmp edx, [ecx+attributeRealSize+4]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
cmp byte [ecx+nonResidentFlag], 0
jz @f
cmp [ecx+attributeRealSize+4], edx
jnz @f
cmp [ecx+attributeRealSize], eax
jnz ntfsUnsupported
jmp ntfs_WriteFile.write
jz ntfs_WriteFile.writeNode
@@:
jmp ntfs_WriteFile.resizeAttribute
 
.notFound: ; create; check path folders
cmp dword [esp+4], 0
jnz ntfsNotFound
cmp byte [esi], 0
jz ntfsNotFound
.folder:
bt dword [eax+fileFlags], 28
jnc ntfsDenied
push 0
jmp ntfsOut
 
.notFound: ; create
test eax, eax
jz ntfsFail
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; 2. Prepare directory record
mov ecx, esi
@@: ; count characters
inc ecx
cmp byte [ecx], '/'
jz ntfsNotFound
jz ntfsNotFound ; path folder not found
cmp byte [ecx], 0
jnz @b
sub ecx, esi
push ecx
lea ecx, [ecx*2+52h] ; precalculate index length
add ecx, 7 ; align 8
and ecx, not 7
lea ecx, [ecx*2+52h+7] ; precalculate index length
and ecx, not 7 ; align 8
mov edi, [ebp+NTFS.cur_index_buf]
push esi
push ecx
2111,11 → 2141,12
rep stosd
cld
add edi, 4
pop eax
pop ecx
pop esi
mov [edi+indexAllocatedSize], ax ; fill index with data
mov [edi+indexAllocatedSize], cx ; fill index with data
mov eax, [esp]
lea eax, [eax*2+42h]
shl eax, 1
add eax, 42h
mov [edi+indexRawSize], ax
mov eax, [ebp+NTFS.ntfs_attr_iRecord]
mov [edi+directoryRecordReference], eax
2123,8 → 2154,16
mov eax, [eax+reuseCounter]
mov [edi+directoryReferenceReuse], ax
mov eax, [ebx+12]
add ecx, 30h+48h+8+18h+8
add ecx, eax
mov [ebp+NTFS.fileRealSize], eax
mov [edi+fileRealSize], eax
cmp [ebp+NTFS.frs_size], ecx
jc @f
mov eax, [ebx+16]
mov [ebp+NTFS.fileDataStart], eax
xor eax, eax
@@:
mov ecx, [ebp+NTFS.sectors_per_cluster]
shl ecx, 9
add eax, ecx
2149,161 → 2188,15
cmp [ebp+NTFS.ntfsFolder], 0
jz @f
mov edi, [ebp+NTFS.indexOffset]
mov byte [edi+fileFlags+3], 16
bts dword [edi+fileFlags], 28
jmp .mftBitmap
 
@@: ; 3. File data
cmp [ebp+NTFS.fileRealSize], 0
cmp [ebp+NTFS.fileDataSize], 0
jz .mftBitmap
; One piece free space bitmap search engine
mov edi, [ebp+NTFS.BitmapBuffer]
add edi, [ebp+NTFS.BitmapStart]
mov eax, [ebp+NTFS.fileDataSize]
shr eax, 5
jz .small
push eax ; bitmap dwords
add edi, 4
.start:
mov ecx, [ebp+NTFS.BitmapSize]
add ecx, [ebp+NTFS.BitmapBuffer]
sub ecx, edi
shr ecx, 2
@@:
xor eax, eax
repnz scasd ; search for empty dword
jz @f
call bitmapBuffering
jmp @b
@@:
cmp ecx, [esp]
jnc @f
call bitmapBuffering
jmp @b
@@:
sub edi, 4
mov ecx, [esp]
mov esi, edi
xor eax, eax
repz scasd ; check following dwords
jnz .start
sub esi, 4
mov eax, [esi]
xor edx, edx
bsr edx, eax
inc edx
push edx ; starting bit
push esi ; starting dword
add esi, 4
neg edx
add edx, 32
mov eax, [ebp+NTFS.fileDataSize]
sub eax, edx
mov edx, eax
shr eax, 5
shl eax, 2
add esi, eax
mov eax, [esi]
bsf ecx, eax ; last dword
jz .done
and edx, 31
cmp ecx, edx
jnc .done
add esp, 8
jmp .start
 
.small: ; less than 32 clusters
mov ecx, [ebp+NTFS.BitmapSize]
sub ecx, [ebp+NTFS.BitmapStart]
shr ecx, 2
.smStart:
mov eax, -1
repz scasd ; search for zero bits
push ecx
test ecx, ecx
jnz @f
call bitmapBuffering
pop eax
jmp .smStart
@@:
sub edi, 4
mov eax, [edi]
not eax
@@:
bsf ecx, eax ; first 0
jz .again
not eax
shr eax, cl
shl eax, cl
bsf edx, eax ; next 1
jz @f
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; fits inside
bsf ecx, eax
not eax
shr eax, cl
shl eax, cl
jmp @b
@@: ; next dword
mov eax, [edi+4]
bsf edx, eax
jz .got ; empty
add edx, 32
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; share between dwords
.again:
add edi, 4
pop ecx
jmp .smStart
 
.got:
push ecx ; starting bit
push edi ; starting dword
.done: ; mark space
mov ecx, [esp+4]
cmp ecx, 32
jc @f
xor ecx, ecx
add dword [esp], 4
mov [esp+4], ecx
@@:
mov edi, [esp]
xor eax, eax
dec eax
shr eax, cl
shl eax, cl
neg ecx
add ecx, 32
sub ecx, [ebp+NTFS.fileDataSize]
jc @f
shl eax, cl ; fits inside dword
shr eax, cl
or [edi], eax
jmp .writeData
 
@@:
or [edi], eax
neg ecx
push ecx
shr ecx, 5
add edi, 4
xor eax, eax
dec eax
rep stosd
pop ecx
and ecx, 31
shr eax, cl
shl eax, cl
not eax
or [edi], eax
.writeData:
pop edx
sub edx, [ebp+NTFS.BitmapBuffer]
shl edx, 3
pop eax
add eax, edx
pop edx
mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc
jc ntfsDiskFull
mov [ebp+NTFS.fileDataStart], eax
mul [ebp+NTFS.sectors_per_cluster]
mov ecx, [ebp+NTFS.fileRealSize]
2325,7 → 2218,7
movzx eax, byte [edi]
not al
bsf ecx, eax
jz ntfsUnsupported ; no free records
jz .extendBitmapMFT ; no free records
bts [edi], ecx
; get record location
sub edi, [ebp+NTFS.mftBitmapBuffer]
2343,89 → 2236,58
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
cmp [ebp+NTFS.ntfs_cur_read], 0
jnz .mftRecord
; extend MFT $DATA
jz .extendMFT
jmp .mftRecord
 
.extendBitmapMFT:
mov eax, [ebp+NTFS.sectors_per_cluster]
shl eax, 9
cmp [ebp+NTFS.mftBitmapSize], eax
jnc ntfsUnsupported
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfsLastRead]
jnz ntfsUnsupported ; auxiliary record
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov ebx, [ebp+NTFS.sectors_per_cluster]
shl ebx, 9+3
add dword [edi+lastVCN], 8
add [edi+attributeAllocatedSize], ebx
adc byte [edi+attributeAllocatedSize+4], 0
add [edi+attributeRealSize], ebx
adc byte [edi+attributeRealSize+4], 0
add [edi+initialDataSize], ebx
adc byte [edi+initialDataSize+4], 0
movzx eax, byte [edi+dataRunsOffset]
add edi, eax
mov al, [edi]
inc edi
shl eax, 4
shr al, 4
mov cl, 4
sub cl, al
shl cl, 3
add ah, al
shr eax, 8
cmp byte [edi+eax], 0
jnz ntfsUnsupported ; $MFT fragmented
mov al, 8
mov edx, [edi]
rol eax, cl
rol edx, cl
add eax, edx
jc ntfsUnsupported
ror eax, cl
shr edx, cl
mov [edi], eax
add edx, [ebp+NTFS.mft_cluster]
mov esi, edx
mov ecx, edx
and ecx, 7
shr edx, 3
add edx, [ebp+NTFS.BitmapBuffer]
mov ax, [edx]
shr ax, cl
test al, al
jnz ntfsUnsupported
dec al
xchg [edx], al
mov [edx+1], al
stdcall kernel_alloc, ebx
test eax, eax
jz ntfsNoMemory
mov ecx, ebx
shr ecx, 2
mov edi, eax
push ebx
mov ebx, eax
xor eax, eax
rep stosd
mov eax, esi
mov edi, [ebp+NTFS.mftBitmapBuffer]
mov ecx, [ebp+NTFS.mftBitmapSize]
add edi, ecx
mov eax, ecx
mov edx, [ebp+NTFS.ntfs_attr_offs]
add ecx, 8
mov [edx+attributeRealSize], ecx
mov [edx+initialDataSize], ecx
shl eax, 3
mov [ebp+NTFS.newMftRecord], eax
mov dword [edi], 1
mov dword [edi+4], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80
call ntfs_read_attr.newAttribute
jc ntfsFail
mov [ebp+NTFS.mftBitmapSize], ecx
.extendMFT:
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
pop ecx
shr ecx, 9
call fs_write64_sys ; clear new records
stdcall kernel_free, ebx
mov eax, esi
shr eax, 3+9
mov ebx, eax
shl ebx, 9
add ebx, [ebp+NTFS.BitmapBuffer]
add eax, [ebp+NTFS.BitmapLocation]
mov ecx, 1
xor edx, edx
call fs_write64_app ; partition bitmap
test eax, eax
jnz ntfsDevice
cmp eax, [ebp+NTFS.ntfsLastRead]
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
xor ax, ax
add eax, 10000h
adc edx, 0
push [ebp+NTFS.fileDataStart]
push [ebp+NTFS.fileDataSize]
call resizeAttribute
jc ntfsErrorPop2
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; $MFT
test eax, eax
jnz ntfsDevice
mov eax, [ebp+NTFS.mftmirr_cluster]
mul [ebp+NTFS.sectors_per_cluster]
mov ebx, [ebp+NTFS.frs_buffer]
2432,28 → 2294,26
movzx ecx, word [ebx+updateSequenceSize]
dec ecx
call fs_write64_sys ; $MFTMirr
test eax, eax
jnz ntfsDevice
mov eax, [ebp+NTFS.ntfs_cur_offs]
add [ebp+NTFS.ntfsLastRead], eax
call ntfsSpaceClean
pop [ebp+NTFS.fileDataSize]
pop [ebp+NTFS.fileDataStart]
.mftRecord:
mov esi, [ebp+NTFS.indexOffset]
mov ecx, [ebp+NTFS.frs_size]
shr ecx, 2
mov edi, [ebp+NTFS.frs_buffer]
xor eax, eax
movzx ecx, word [esi+indexAllocatedSize]
add ecx, 8+30h+48h+50h+8
push ecx
shr ecx, 2
rep stosd
mov edi, [ebp+NTFS.frs_buffer]
; record header
mov eax, [ebp+NTFS.frs_size]
mov [edi+recordAllocatedSize], eax
shr eax, 9
inc eax
mov [edi+updateSequenceSize], al
mov dword[edi], 'FILE'
mov byte [edi+updateSequenceOffset], 2ah
mov byte [edi+updateSequenceSize], 3
mov byte [edi+hardLinkCounter], 1
mov byte [edi+attributeOffset], 30h
pop dword[edi+recordRealSize]
mov word [edi+recordAllocatedSize], 1024
mov byte [edi+newAttributeID], 3
rdtsc
mov [edi+2ah], ax
2465,27 → 2325,33
mov byte [edi+attributeOffset], 18h
add edi, 48h
; $FileName
mov esi, [ebp+NTFS.indexOffset]
mov byte [edi+attributeType], 30h
mov byte [edi+attributeID], 1
mov byte [edi+attributeOffset], 18h
mov byte [edi+indexedFlag], 1
mov cx, [esi+indexRawSize]
mov [edi+sizeWithoutHeader], ecx
mov cx, [esi+indexAllocatedSize]
add ecx, 8
mov [edi+sizeWithHeader], ecx
mov byte [edi+attributeOffset], 18h
mov byte [edi+indexedFlag], 1
add edi, 18h
add esi, 16
sub ecx, 18h
shr ecx, 2
rep movsd
cmp [ebp+NTFS.ntfsFolder], 0
jnz @f
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+attributeID], 2
cmp [ebp+NTFS.ntfsFolder], 1
jz .indexRoot
; $Data
mov byte [edi+attributeType], 80h
cmp [ebp+NTFS.fileRealSize], 0
jz .zeroSize
mov eax, [ebp+NTFS.fileDataSize]
test eax, eax
jz .resident
mov esi, [ebp+NTFS.indexOffset]
dec eax
mov [edi+lastVCN], eax
mov byte [edi+nonResidentFlag], 1
mov byte [edi+dataRunsOffset], 40h
mov eax, [esi+fileAllocatedSize]
2493,22 → 2359,33
mov eax, [esi+fileRealSize]
mov [edi+attributeRealSize], eax
mov [edi+initialDataSize], eax
mov byte [edi+40h], 44h
mov eax, [ebp+NTFS.fileDataSize]
mov [edi+41h], eax
dec eax
mov [edi+lastVCN], eax
mov eax, [ebp+NTFS.fileDataStart]
mov [edi+45h], eax
mov al, 1
jmp .writeMftRecord
push edi
mov esi, edi
add edi, 40h
call createMcbEntry
inc edi
jmp @f
 
.zeroSize:
.resident:
mov ecx, [ebp+NTFS.fileRealSize]
mov [edi+sizeWithoutHeader], ecx
mov byte [edi+attributeOffset], 18h
push edi
mov esi, [ebp+NTFS.fileDataStart]
add edi, 18h
rep movsb
@@:
mov eax, edi
pop edi
sub eax, edi
add eax, 7
and eax, not 7
mov [edi+sizeWithHeader], eax
add edi, eax
mov al, 1
jmp .writeMftRecord
jmp @f
 
@@: ; $IndexRoot
.indexRoot:
mov byte [edi+attributeType], 90h
mov byte [edi+nameLength], 4
mov byte [edi+nameOffset], 18h
2527,19 → 2404,20
mov byte [edi+30h+nodeAllocatedSize], 32
mov byte [edi+40h+indexAllocatedSize], 16
mov byte [edi+40h+indexFlags], 2
add edi, 50h
mov al, 3
.writeMftRecord:
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+attributeID], 2
mov dword[edi+50h], -1 ; $End
mov edi, [ebp+NTFS.frs_buffer]
mov [edi+recordFlags], al
mov [ebp+NTFS.ntfs_cur_buf], edi
@@:
mov esi, [ebp+NTFS.frs_buffer]
mov dword [edi], -1
mov dword [edi+4], 0
add edi, 8
sub edi, esi
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [esi+recordFlags], al
mov [esi+recordRealSize], edi
call writeRecord
test eax, eax
jnz ntfsDevice
mov esi, [ebp+PARTITION.Disk]
call disk_sync
; write MFT bitmap
mov eax, [ebp+NTFS.newMftRecord]
shr eax, 3+9
2553,13 → 2431,13
test eax, eax
jnz ntfsDevice
; 5. Write partition bitmap
cmp [ebp+NTFS.ntfsFolder], 0
jnz @f
cmp [ebp+NTFS.fileRealSize], 0
cmp [ebp+NTFS.ntfsFolder], 1
jz @f
mov ecx, [ebp+NTFS.fileDataStart]
mov eax, ecx
add ecx, [ebp+NTFS.fileDataSize]
mov eax, [ebp+NTFS.fileDataStart]
mov ecx, [ebp+NTFS.fileDataSize]
test ecx, ecx
jz @f
add ecx, eax
add ecx, 4095
shr ecx, 3+9
shr eax, 3+9
2573,8 → 2451,6
test eax, eax
jnz ntfsDevice
@@:
mov esi, [ebp+PARTITION.Disk]
call disk_sync
mov edi, [ebp+NTFS.indexOffset]
mov eax, [ebp+NTFS.newMftRecord]
mov [edi+fileRecordReference], eax
2584,8 → 2460,6
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord
test eax, eax
jnz ntfsDevice
mov ebx, [ebp+NTFS.fileRealSize]
ntfsDone:
mov esi, [ebp+PARTITION.Disk]
2595,16 → 2469,17
ret
 
writeRecord:
; make updateSequence and write to disk
; in:
; [ebp+NTFS.ntfs_cur_buf] = record
; [ebp+NTFS.ntfs_cur_buf] -> record
; [ebp+NTFS.ntfsLastRead] = partition sector
; making updateSequence
mov esi, [ebp+NTFS.ntfs_cur_buf]
mov edi, esi
movzx ecx, word [esi+updateSequenceOffset]
add edi, ecx
mov ax, [edi]
add edi, 2
inc ax
stosw
mov cx, [esi+updateSequenceSize]
dec ecx
push ecx
2614,7 → 2489,6
mov [esi-2], ax
dec ecx
jnz @b
; writing to disk
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
pop ecx
2621,11 → 2495,667
xor edx, edx
jmp fs_write64_sys
 
createMcbEntry:
; in:
; [ebp+NTFS.fileDataStart] = position value
; [ebp+NTFS.fileDataSize] = size value
; edi -> destination
; esi -> attribute header
mov eax, [ebp+NTFS.fileDataStart]
xor edx, edx
shl eax, 1
jnc @f
not eax
@@:
inc edx
shr eax, 8
jnz @b
mov eax, [ebp+NTFS.fileDataSize]
shl eax, 1
xor ecx, ecx
@@:
inc ecx
shr eax, 8
jnz @b
lea eax, [edi+edx+1]
add eax, ecx
sub eax, esi
sub eax, [esi+sizeWithHeader]
jc @f
add word [esi+sizeWithHeader], 8 ; extend attribute
mov esi, [ebp+NTFS.frs_buffer]
mov eax, [esi+recordRealSize]
add eax, 8
cmp [esi+recordAllocatedSize], eax
jc .end ; no space in the record
mov [esi+recordRealSize], eax
push ecx edi
add esi, eax
mov ecx, esi
sub ecx, edi
sub ecx, 8
shr ecx, 2
mov edi, esi
sub edi, 4
sub esi, 12
std
rep movsd
cld
pop edi ecx
@@:
mov eax, edx
shl eax, 4
add eax, ecx
stosb
lea esi, [ebp+NTFS.fileDataSize]
rep movsb
lea esi, [ebp+NTFS.fileDataStart]
mov ecx, edx
rep movsb
mov [edi], cl
.end:
ret
 
resizeAttribute:
; in:
; [ebp+NTFS.frs_buffer] -> file record
; [ebp+NTFS.ntfs_attr_offs] -> attribute
; edx:eax = new size
; out:
; [ebp+NTFS.fileDataSize] = clusters added (positive)
; [ebp+NTFS.fileDataStart] = added block
; CF=1 -> eax = error code
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
cmp byte [esi+nonResidentFlag], 0
jz .resident
mov ecx, [ebp+NTFS.sectors_per_cluster]
shl ecx, 9
mov [esi+attributeRealSize], eax
mov [esi+attributeRealSize+4], edx
mov [esi+initialDataSize], eax
mov [esi+initialDataSize+4], edx
sub eax, 1
sbb edx, 0
jc .makeResident
div ecx
mov edi, eax
inc eax
mul ecx
mov [esi+attributeAllocatedSize], eax
mov [esi+attributeAllocatedSize+4], edx
mov ecx, [esi+lastVCN]
mov [esi+lastVCN], edi
movzx eax, byte [esi+dataRunsOffset]
sub edi, ecx
mov [ebp+NTFS.fileDataSize], edi
jz .done
jc .shrinkAttribute
; extend attribute
xor edi, edi
add esi, eax
push edi edi edi edi
@@:
mov edx, eax
mov eax, esi
add edi, [esp+8]
call ntfs_decode_mcb_entry
jc @b
mov [esp+4], edx
mov [esp+12], edi
add edi, [esp]
push edi
shr edi, 5
shl edi, 2
push eax
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jz @f
cmp edi, [ebp+NTFS.BitmapStart]
jc .err1
@@:
call ntfsSpaceAlloc
jc .err1
pop edi
pop edx
cmp edx, eax
jnz .newEntry
pop edx
pop edi
pop [ebp+NTFS.fileDataStart]
mov [esp], eax
push [ebp+NTFS.fileDataSize]
add [ebp+NTFS.fileDataSize], edx
jmp @f
 
.newEntry:
add esp, 12
pop edx
push eax
push [ebp+NTFS.fileDataSize]
sub eax, edx
mov [ebp+NTFS.fileDataStart], eax
@@:
mov esi, [ebp+NTFS.ntfs_attr_offs]
call createMcbEntry
pop ecx
pop eax
jc .err2
mov [ebp+NTFS.fileDataSize], ecx
mov [ebp+NTFS.fileDataStart], eax
.writeBitmap:
add ecx, eax
add ecx, 4095
shr ecx, 3+9
shr eax, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
call fs_write64_app
test eax, eax
jnz @f
.done:
ret
 
.err4:
pop eax
@@:
movi eax, ERROR_DEVICE
stc
ret
 
.err1:
add esp, 24
stc
.err10:
movi eax, ERROR_DISK_FULL
ret
 
.err2:
movi eax, ERROR_UNSUPPORTED_FS
ret
 
.shrinkAttribute:
add ecx, edi
inc ecx
add esi, eax
xor edi, edi
sub esp, 20
@@:
mov [esp+16], esi
call ntfs_decode_mcb_entry
jnc .err3
add edi, [esp+8]
sub ecx, [esp]
jnc @b
mov ebx, ecx
add ecx, [esp]
mov eax, [esp+8]
mov [ebp+NTFS.fileDataSize], ecx
mov [ebp+NTFS.fileDataStart], eax
push edi
add edi, ecx
neg ebx
call ntfsSpaceFree
pop edi
jc .end
@@:
call ntfs_decode_mcb_entry
jnc .end
cmp dword[esp+8], 0
jz @b
add edi, [esp+8]
mov ebx, [esp]
call ntfsSpaceFree
jnc @b
.end:
add esp, 16
pop edi
cmp [ebp+NTFS.fileDataSize], 0
jz @f
mov esi, [ebp+NTFS.ntfs_attr_offs]
call createMcbEntry
mov [ebp+NTFS.fileDataSize], 0
@@:
ret
 
.err3:
movi eax, ERROR_FS_FAIL
add esp, 20
stc
ret
 
.resident:
test edx, edx
jnz .nonResident
cmp eax, 8000h
jnc .nonResident
add ax, [esi+attributeOffset]
sub eax, [esi+sizeWithHeader]
jc @f
mov edi, [ebp+NTFS.frs_buffer]
mov ecx, eax
add ecx, [edi+recordRealSize]
cmp [edi+recordAllocatedSize], ecx
jc .nonResident
add eax, 7
and eax, not 7
add [edi+recordRealSize], eax
add edi, [edi+recordRealSize]
add [esi+sizeWithHeader], eax
add esi, [esi+sizeWithHeader]
mov ecx, edi
sub ecx, esi
shr ecx, 2
sub edi, 4
mov esi, edi
sub esi, eax
std
rep movsd
mov ecx, eax
shr ecx, 2
xor eax, eax
rep stosd
cld
mov esi, [ebp+NTFS.ntfs_attr_offs]
@@:
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov [esi+sizeWithoutHeader], eax
mov [ebp+NTFS.fileDataSize], 0
clc
ret
 
.nonResident: ; convert resident to non-resident
mov eax, dword [ebp+NTFS.ntfs_attr_size]
sub eax, 1
sbb edx, 0
mov ecx, [ebp+NTFS.sectors_per_cluster]
shl ecx, 9
div ecx
inc eax
mov [ebp+NTFS.fileDataSize], eax
mov edi, [ebp+NTFS.BitmapStart]
push ecx
call ntfsSpaceAlloc
pop ecx
jc .err10
mov [ebp+NTFS.fileDataStart], eax
mov esi, [ebp+NTFS.ntfs_attr_offs]
xor eax, eax
xor edx, edx
@@:
add eax, ecx
inc edx
cmp eax, [esi+sizeWithoutHeader]
jc @b
push edx
push eax
stdcall kernel_alloc, eax
mov ecx, [esp]
shr ecx, 2
mov edi, eax
mov ebx, eax
xor eax, eax
rep stosd
mov al, [esi+attributeOffset]
mov ecx, [esi+sizeWithoutHeader]
add esi, eax
mov edi, ebx
rep movsb
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
pop ecx
shr ecx, 9
call fs_write64_app
push ebx
mov ebx, eax
call kernel_free
test ebx, ebx
jnz .err4
mov esi, [ebp+NTFS.ntfs_attr_offs]
add esi, [esi+sizeWithHeader]
mov ecx, [ebp+NTFS.frs_buffer]
add ecx, [ecx+recordRealSize]
sub ecx, esi
shr ecx, 2
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
push ecx
rep movsd
mov edi, [ebp+NTFS.ntfs_attr_offs]
add edi, 16
mov cl, 6
xor eax, eax
rep stosd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
inc eax
mov ecx, [ebp+NTFS.sectors_per_cluster]
shl ecx, 9
mul ecx
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+nonResidentFlag], 1
mov byte [edi+dataRunsOffset], 40h
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeAllocatedSize+4], edx
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov [edi+attributeRealSize], eax
mov [edi+attributeRealSize+4], edx
mov [edi+initialDataSize], eax
mov [edi+initialDataSize+4], edx
mov esi, edi
add edi, 40h
call createMcbEntry
mov eax, edi
mov edi, [ebp+NTFS.ntfs_attr_offs]
sub eax, edi
add eax, 8
and eax, not 7
mov [edi+sizeWithHeader], eax
pop ecx
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
add edi, eax
rep movsd
mov esi, [ebp+NTFS.frs_buffer]
sub edi, esi
mov [esi+recordRealSize], edi
pop edx
mov ecx, [ebp+NTFS.fileDataSize]
sub [ebp+NTFS.fileDataSize], edx
mov eax, [ebp+NTFS.fileDataStart]
add [ebp+NTFS.fileDataStart], edx
jmp .writeBitmap
 
.makeResident: ; convert non-resident to empty resident
movzx eax, byte [esi+dataRunsOffset]
mov byte [esi+nonResidentFlag], 0
mov dword [esi+sizeWithoutHeader], 0
mov dword [esi+attributeOffset], 18h
add esi, eax
xor edi, edi
sub esp, 16
@@:
call ntfs_decode_mcb_entry
jnc @f
cmp dword[esp+8], 0
jz @b
add edi, [esp+8]
mov ebx, [esp]
call ntfsSpaceFree
jnc @b
@@:
add esp, 16
mov [ebp+NTFS.fileDataSize], 0
ret
 
ntfsSpaceClean:
; clean up to 16 Mb of disk space
; in:
; [ebp+NTFS.fileDataStart] = block to clean
; [ebp+NTFS.fileDataSize] = block size
mov eax, [ebp+NTFS.fileDataSize]
test eax, eax
jz @f
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, 8001h
jnc @f
push eax
shl eax, 9
stdcall kernel_alloc, eax
pop ecx
test eax, eax
jz @f
push ecx
shl ecx, 7
mov edi, eax
mov ebx, eax
xor eax, eax
rep stosd
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfsLastRead], eax
pop ecx
call fs_write64_app
stdcall kernel_free, ebx
@@:
ret
 
ntfsSpaceAlloc:
; find and mark block of free space in bitmap buffer
; in:
; edi = offset in bitmap to start search from
; [ebp+NTFS.fileDataSize] = block size in clusters
; out:
; eax = allocated block starting cluster
; CF=1 -> disk full
mov ecx, [ebp+NTFS.BitmapBuffer]
add edi, ecx
add ecx, [ebp+NTFS.BitmapSize]
sub ecx, edi
jnc @f
call bitmapBuffering
shl ecx, 2
@@:
shr ecx, 2
mov eax, [ebp+NTFS.fileDataSize]
shr eax, 5
jz .small
push eax ; bitmap dwords
.start:
mov ecx, [ebp+NTFS.BitmapBuffer]
add ecx, [ebp+NTFS.BitmapSize]
sub ecx, edi
shr ecx, 2
@@:
xor eax, eax
repnz scasd ; search for empty dword
jz @f
call bitmapBuffering
jmp @b
@@:
cmp ecx, [esp]
jnc @f
call bitmapBuffering
jmp @b
@@:
sub edi, 4
mov ecx, [esp]
mov esi, edi
xor eax, eax
repz scasd ; check following dwords
jnz .start
sub esi, 4
mov eax, [esi]
xor edx, edx
bsr edx, eax
inc edx
push edx ; starting bit
push esi ; starting dword
add esi, 4
neg edx
add edx, 32
mov eax, [ebp+NTFS.fileDataSize]
sub eax, edx
mov edx, eax
shr eax, 5
shl eax, 2
add esi, eax
mov eax, [esi]
bsf ecx, eax ; check last dword
jz .done
and edx, 31
cmp ecx, edx
jnc .done
add esp, 8
jmp .start
 
.small: ; less than 32 clusters
mov eax, -1
repz scasd ; search for zero bits
push ecx
test ecx, ecx
jnz @f
call bitmapBuffering
pop eax
jmp .small
@@:
sub edi, 4
mov eax, [edi]
not eax
@@:
bsf ecx, eax ; first 0
jz .again
not eax
shr eax, cl
shl eax, cl
bsf edx, eax ; next 1
jz @f
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; fits inside
bsf ecx, eax
not eax
shr eax, cl
shl eax, cl
jmp @b
@@: ; next dword
mov eax, [edi+4]
bsf edx, eax
jz .got ; empty
add edx, 32
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; share between dwords
.again:
add edi, 4
pop ecx
jmp .small
 
.got:
push ecx ; starting bit
push edi ; starting dword
.done: ; mark space
mov ecx, [esp+4]
cmp ecx, 32
jc @f
xor ecx, ecx
add dword [esp], 4
mov [esp+4], ecx
@@:
mov edi, [esp]
xor eax, eax
dec eax
shr eax, cl
shl eax, cl
neg ecx
add ecx, 32
sub ecx, [ebp+NTFS.fileDataSize]
jc @f
shl eax, cl ; fits inside dword
shr eax, cl
or [edi], eax
jmp .end
 
@@:
or [edi], eax
neg ecx
push ecx
shr ecx, 5
add edi, 4
xor eax, eax
dec eax
rep stosd
pop ecx
and ecx, 31
shr eax, cl
shl eax, cl
not eax
or [edi], eax
.end:
pop eax
sub eax, [ebp+NTFS.BitmapBuffer]
shl eax, 3
pop edx
add eax, edx
pop edx
ret
 
ntfsSpaceFree:
; free disk space
; in:
; edi = starting cluster
; ebx = size in clusters
mov eax, edi
add eax, ebx
shr eax, 3
inc eax
cmp eax, [ebp+NTFS.BitmapSize]
jc @f
add eax, [ebp+NTFS.BitmapBuffer]
push edi
mov edi, eax
call bitmapBuffering
pop edi
@@:
push edi
mov ecx, edi
shr edi, 5
shl edi, 2
add edi, [ebp+NTFS.BitmapBuffer]
and ecx, 31
xor eax, eax
dec eax
shr eax, cl
shl eax, cl
neg ecx
add ecx, 32
sub ecx, ebx
jc @f
shl eax, cl ; fits inside dword
shr eax, cl
not eax
and [edi], eax
jmp .writeBitmap
 
@@:
not eax
and [edi], eax
neg ecx
push ecx
shr ecx, 5
add edi, 4
xor eax, eax
rep stosd
pop ecx
and ecx, 31
dec eax
shr eax, cl
shl eax, cl
and [edi], eax
.writeBitmap:
pop eax
mov edi, eax
lea ecx, [eax+ebx+4095]
shr eax, 3+9
shr ecx, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
jmp fs_write64_app
 
bitmapBuffering:
; Extend BitmapBuffer and read next 32kb of bitmap
; Warning: $Bitmap fragmentation is not foreseen
; if edi -> position in bitmap buffer,
; then ecx = number of buffered dwords left
; in: edi -> position in bitmap buffer
; out: ecx = number of buffered dwords left
push ebx
mov eax, [ebp+NTFS.BitmapTotalSize]
cmp eax, [ebp+NTFS.BitmapSize]
2654,11 → 3184,12
jnc @f
mov [ebp+NTFS.BitmapSize], eax
@@:
mov ecx, [ebp+NTFS.BitmapSize]
add ecx, [ebp+NTFS.BitmapBuffer]
pop ebx
mov ecx, [ebp+NTFS.BitmapBuffer]
add ecx, [ebp+NTFS.BitmapSize]
sub ecx, edi
jc bitmapBuffering
shr ecx, 2
pop ebx
ret
 
.err:
2667,9 → 3198,11
mov ecx, 8
call release_pages
.end:
add esp, 12 ; double ret
push ERROR_DISK_FULL
jmp ntfsOut
pop ebx
pop eax ; ret
pop eax
stc
ret
 
;----------------------------------------------------------------
ntfs_WriteFile:
2684,34 → 3217,86
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
cmp dword [edi], 'INDX'
jz @f
mov esi, [ebp+NTFS.frs_buffer]
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
add eax, esi
@@:
mov ecx, [ebx+4]
mov edx, [ebx+8]
add ecx, [ebx+12]
adc edx, 0
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jc ntfsDenied
mov eax, [ebp+NTFS.frs_buffer]
cmp word [eax+baseRecordReuse], 0
jc ntfsFail
mov eax, ecx
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
cmp byte [eax+hardLinkCounter], 1
jnz ntfsUnsupported ; file copying required
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz ntfsUnsupported ; resident $DATA
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
mov eax, [ebx+4]
mov edx, [ebx+8]
add eax, [ebx+12]
adc edx, 0
push ebx
cmp byte [ecx+nonResidentFlag], 0
jz .resizeAttribute
cmp edx, [ecx+attributeRealSize+4]
jc .write
jnz ntfsUnsupported ; end of file
jc .writeNode
jnz .resizeAttribute
cmp [ecx+attributeRealSize], eax
jc ntfsUnsupported
.write:
jnc .writeNode
.resizeAttribute:
call resizeAttribute
jc ntfsErrorPop
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jz @f
mov ebx, [esp]
movzx edi, byte [ecx+attributeOffset]
add edi, ecx
add edi, [ebx+4]
mov ecx, [ebx+12]
mov esi, [ebx+16]
rep movsb
@@:
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; file
mov ebx, [ebp+NTFS.frs_buffer]
call ntfs_restore_usa_frs
.writeNode:
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; directory
pop ebx
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 0
jz .done
mov ecx, [ebx+12]
test ecx, ecx
jz .done
mov eax, [ebx+4]
mov edx, [ebx+8]
mov ecx, [ebx+12]
mov esi, [ebx+16]
shrd eax, edx, 9
test dword[ebx+4], 1FFh
2742,10 → 3327,8
call fs_write64_app
pop ebx
pop ecx
test eax, eax
jnz ntfsDevice
test ecx, ecx
jz @f
jz .done
mov eax, [ebx+4]
mov edx, [ebx+8]
shrd eax, edx, 9
2765,7 → 3348,7
pop ecx
jc ntfsDevice
and ecx, 1FFh
jz @f
jz .done
add esi, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_size], 1
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
2780,9 → 3363,7
xor edx, edx
call fs_write64_app
pop ebx
test eax, eax
jnz ntfsDevice
@@:
.done:
mov ebx, [ebx+12]
jmp ntfsDone
 
2809,6 → 3390,11
jnc ntfsUnsupported
; delete index from the node
movzx edx, word [eax+indexAllocatedSize]
mov ecx, [eax+fileRecordReference]
cmp [eax+edx+fileRecordReference], ecx
jnz @f
add dx, [eax+edx+indexAllocatedSize]
@@:
mov edi, [ebp+NTFS.cur_index_buf]
cmp dword [edi], 'INDX'
jz .indexRecord
2855,8 → 3441,6
mov esi, [ebp+NTFS.frs_buffer]
cmp word [esi+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
cmp byte [esi+hardLinkCounter], 2
jnc .writeFileRecord ; delete hard link
mov esi, [ebp+NTFS.ntfs_attr_offs]
cmp byte [esi+nonResidentFlag], 0
jz .writeBitmapMFT
2864,83 → 3448,16
add esi, eax
xor edi, edi
sub esp, 16
.clearBitmap: ; "delete" file data
@@: ; "delete" file data
call ntfs_decode_mcb_entry
jnc .mcbEnd
jnc @f
cmp dword[esp+8], 0
jz .clearBitmap
jz @b
add edi, [esp+8]
mov ebx, [esp]
mov eax, edi
add eax, ebx
shr eax, 3
inc eax
cmp eax, [ebp+NTFS.BitmapSize]
jc .buffered
add eax, [ebp+NTFS.BitmapBuffer]
add esp, 16
push edi
mov edi, eax
call ntfsSpaceFree
jnc @b
@@:
call bitmapBuffering
shl ecx, 2
js @b
pop edi
sub esp, 16
.buffered:
push edi
mov ecx, edi
shr edi, 5
shl edi, 2
add edi, [ebp+NTFS.BitmapBuffer]
and ecx, 31
xor eax, eax
dec eax
shr eax, cl
shl eax, cl
neg ecx
add ecx, 32
sub ecx, ebx
jc @f
shl eax, cl ; fits inside dword
shr eax, cl
not eax
and [edi], eax
jmp .writeBitmap
 
@@:
not eax
and [edi], eax
neg ecx
push ecx
shr ecx, 5
add edi, 4
xor eax, eax
rep stosd
pop ecx
and ecx, 31
dec eax
shr eax, cl
shl eax, cl
and [edi], eax
.writeBitmap:
pop edi
mov ecx, edi
add ecx, ebx
add ecx, 4095
shr ecx, 3+9
mov eax, edi
shr eax, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
call fs_write64_app
jmp .clearBitmap
 
.mcbEnd:
add esp, 16
jmp .writeBitmapMFT
 
2971,10 → 3488,8
xor edx, edx
call fs_write64_sys
mov esi, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], esi
mov byte [esi+recordFlags], 0
.writeFileRecord:
dec byte [esi+hardLinkCounter]
mov [ebp+NTFS.ntfs_cur_buf], esi
call writeRecord
; write directory node
mov eax, [ebp+NTFS.nodeLastRead]
2982,12 → 3497,113
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord
test eax, eax
jz ntfsDone
jmp ntfsDevice
jmp ntfsDone
 
;----------------------------------------------------------------
ntfs_SetFileEnd:
cmp byte [esi], 0
jnz @f
xor ebx, ebx
movi eax, ERROR_ACCESS_DENIED
ret
@@:
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
cmp dword [edi], 'INDX'
jz @f
mov esi, [ebp+NTFS.frs_buffer]
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
add eax, esi
@@:
mov ecx, [ebx+4]
mov edx, [ebx+8]
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, ecx
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
cmp byte [ecx+nonResidentFlag], 0
jz .resizeAttribute
cmp [ecx+attributeRealSize+4], edx
jnz .resizeAttribute
cmp [ecx+attributeRealSize], eax
jnc .resizeAttribute
mov eax, [ecx+attributeRealSize]
mov ecx, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_size], ecx
shl ecx, 9
div ecx
test edx, edx
jz .aligned
push edx
push ecx
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_offs], eax
stdcall kernel_alloc, ecx
pop ecx
pop edi
sub ecx, edi
add edi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfsLastRead]
call ntfs_read_attr.continue
jc @f
xor eax, eax
rep stosb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ecx, [ebp+NTFS.sectors_per_cluster]
xor edx, edx
call fs_write64_app
pop ebx
@@:
pop [ebp+NTFS.ntfsLastRead]
stdcall kernel_free, [ebp+NTFS.ntfs_cur_buf]
.aligned:
mov eax, [ebx+4]
mov edx, [ebx+8]
.resizeAttribute:
call resizeAttribute
jc ntfsError
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; file
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; directory
call ntfsSpaceClean
jmp ntfsDone
 
;----------------------------------------------------------------
ntfs_SetFileInfo:
movi eax, ERROR_UNSUPPORTED_FS
ret
3018,11 → 3634,7
 
ntfsUnsupported:
push ERROR_UNSUPPORTED_FS
ntfsOut:
call ntfs_unlock
xor ebx, ebx
pop eax
ret
jmp ntfsOut
ntfsDevice:
push ERROR_DEVICE
jmp ntfsOut
3035,6 → 3647,17
ntfsFail:
push ERROR_FS_FAIL
jmp ntfsOut
ntfsNoMemory:
push ERROR_OUT_OF_MEMORY
ntfsDiskFull:
push ERROR_DISK_FULL
jmp ntfsOut
ntfsErrorPop2:
pop ebx
ntfsErrorPop:
pop ebx
ntfsError:
push eax
ntfsOut:
call ntfs_unlock
xor ebx, ebx
pop eax
ret
/kernel/branches/Kolibri-acpi/init.inc
455,7 → 455,25
 
acpi_locate:
push ebx
push edi
 
movzx ebx, word [0x40E]
shl ebx, 4
lea ecx, [ebx+1024]
call .check
 
test ebx, ebx
jnz .done
 
mov ebx, ACPI_HI_RSDP_WINDOW_START
mov edi, ACPI_HI_RSDP_WINDOW_END
call .check
.done:
mov eax, ebx
pop edi
pop ebx
ret
 
.check:
cmp [ebx], dword 0x20445352
jne .next
472,17 → 490,12
 
test al, al
jnz .next
 
mov eax, ebx
pop ebx
ret
.next:
add ebx, 16
cmp ebx, ACPI_HI_RSDP_WINDOW_END
cmp ebx, edi
jb .check
 
pop ebx
xor eax, eax
xor ebx, ebx
ret
 
align 4
/kernel/branches/Kolibri-acpi/kernel.asm
253,7 → 253,7
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x006CC00 ; Set stack
mov esp, TMP_STACK_TOP ; Set stack
 
; CLEAR 0x280000 - HEAP_BASE
 
2177,7 → 2177,7
@@:
 
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], 3; terminate this program
mov [eax+TASKDATA.state], TSTATE_ZOMBIE
call wakeup_osloop
 
.waitterm: ; wait here for termination
3746,7 → 3746,7
align 4
markz:
push ecx edx
cmp [edx+TASKDATA.state], 9
cmp [edx+TASKDATA.state], TSTATE_FREE
jz .nokill
lea edx, [(edx-(CURRENT_TASK and 1FFFFFFFh))*8+SLOT_BASE]
cmp [edx+APPDATA.process], sys_proc
3760,7 → 3760,7
pop edx ecx
test eax, eax
jz @f
mov [edx+TASKDATA.state], byte 3
mov [edx+TASKDATA.state], TSTATE_ZOMBIE
@@:
add edx, 0x20
loop markz
5766,103 → 5766,64
.no_shutdown_cpus:
 
cli
call IRQ_mask_all
 
if ~ defined extended_primary_loader
; load kernel.mnt to 0x7000:0
mov eax, [OS_BASE + 0x9030]
cmp al, SYSTEM_RESTART
jne @F
 
; load kernel.mnt to _CLEAN_ZONE
mov ebx, kernel_file_load
pushad
call file_system_lfn
popad
 
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
mov edi, OS_BASE+0x40000
mov ecx, 1000
rep movsb
end if
mov esi, OS_BASE+restart_kernel_5000 ; move kernel re-starter to 0x5000:0
mov edi, OS_BASE+0x50000
mov ecx, (restart_code_end - restart_kernel_5000)/4
rep movsd
 
; mov esi, BOOT_VAR ; restore 0x0 - 0xffff
; mov edi, OS_BASE
; mov ecx, 0x10000/4
; cld
; rep movsd
@@:
;disable paging
 
call IRQ_mask_all
call create_trampoline_pgmap
mov cr3, eax
jmp @F
org $-OS_BASE
@@:
mov eax, cr0
and eax, 0x7FFFFFFF
mov cr0, eax
mov eax, cr3
mov cr3, eax
 
cmp byte [OS_BASE + 0x9030], 2
jnz no_acpi_power_off
cmp byte [0x9030], SYSTEM_SHUTDOWN
jne no_acpi_power_off
 
; scan for RSDP
; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA).
movzx eax, word [OS_BASE + 0x40E]
shl eax, 4
jz @f
mov ecx, 1024/16
call scan_rsdp
jnc .rsdp_found
@@:
; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh.
mov eax, 0xE0000
mov ecx, 0x2000
call scan_rsdp
jc no_acpi_power_off
.rsdp_found:
mov esi, [eax+16] ; esi contains physical address of the RSDT
mov ebp, [ipc_tmp]
stdcall map_page, ebp, esi, PG_READ
lea eax, [esi+1000h]
lea edx, [ebp+1000h]
stdcall map_page, edx, eax, PG_READ
and esi, 0xFFF
add esi, ebp
cmp dword [esi], 'RSDT'
jnz no_acpi_power_off
mov ecx, [esi+4]
sub ecx, 24h
jbe no_acpi_power_off
shr ecx, 2
add esi, 24h
.scan_fadt:
lodsd
mov ebx, eax
lea eax, [ebp+2000h]
stdcall map_page, eax, ebx, PG_READ
lea eax, [ebp+3000h]
add ebx, 0x1000
stdcall map_page, eax, ebx, PG_READ
and ebx, 0xFFF
lea ebx, [ebx+ebp+2000h]
; system_power_off
 
mov ebx, [acpi_fadt_base-OS_BASE]
cmp dword [ebx], 'FACP'
jz .fadt_found
loop .scan_fadt
jmp no_acpi_power_off
.fadt_found:
; ebx is linear address of FADT
mov edi, [ebx+40] ; physical address of the DSDT
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_READ
lea eax, [ebp+5000h]
lea esi, [edi+0x1000]
stdcall map_page, eax, esi, PG_READ
and esi, 0xFFF
sub edi, esi
cmp dword [esi+ebp+4000h], 'DSDT'
jnz no_acpi_power_off
mov eax, [esi+ebp+4004h] ; DSDT length
jne no_acpi_power_off
mov esi, [acpi_dsdt_base-OS_BASE]
cmp dword [esi], 'DSDT'
jne no_acpi_power_off
mov eax, [esi+4] ; DSDT length
sub eax, 36+4
jbe no_acpi_power_off
add esi, 36
.scan_dsdt:
cmp dword [esi+ebp+4000h], '_S5_'
cmp dword [esi], '_S5_'
jnz .scan_dsdt_cont
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
cmp byte [esi+4], 12h ; DefPackage opcode
jnz .scan_dsdt_cont
mov dl, [esi+ebp+4000h+6]
mov dl, [esi+6]
cmp dl, 4 ; _S5_ package must contain 4 bytes
; ...in theory; in practice, VirtualBox has 2 bytes
ja .scan_dsdt_cont
cmp dl, 1
jb .scan_dsdt_cont
lea esi, [esi+ebp+4000h+7]
lea esi, [esi+7]
xor ecx, ecx
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
jz @f
5884,21 → 5845,6
jmp do_acpi_power_off
.scan_dsdt_cont:
inc esi
cmp esi, 0x1000
jb @f
sub esi, 0x1000
add edi, 0x1000
push eax
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_READ
push PG_READ
lea eax, [edi+1000h]
push eax
lea eax, [ebp+5000h]
push eax
stdcall map_page
pop eax
@@:
dec eax
jnz .scan_dsdt
jmp no_acpi_power_off
5932,34 → 5878,143
@@:
jmp $
 
no_acpi_power_off:
 
scan_rsdp:
add eax, OS_BASE
.s:
cmp dword [eax], 'RSD '
jnz .n
cmp dword [eax+4], 'PTR '
jnz .n
jmp 0x50000
 
align 4
restart_kernel_5000:
org 0x50000
 
cmp byte [0x9030], SYSTEM_RESTART
jne @F
 
xchg bx, bx
 
mov esi, _CLEAN_ZONE-OS_BASE
mov edi, 0x10000
mov ecx, 0x31000/4
cld
rep movsd
@@:
 
xor ebx, ebx
xor edx, edx
xor ecx, ecx
xor esi, esi
xor edi, edi
xor ebp, ebp
lidt [.idt]
lgdt [.gdt]
jmp 8:@f
align 8
.gdt:
; selector 0 - not used
dw 23
dd .gdt
dw 0
; selector 8 - code from 5000:0000 to 1000:FFFF
dw 0FFFFh
dw 0
db 5
db 10011011b
db 00000000b
db 0
; selector 10h - data from 1000:0000 to 1000:FFFF
dw 0FFFFh
dw 0
db 1
db 10010011b
db 00000000b
db 0
.idt:
dw 256*4
dd 0
org $ - 0x50000
use16
@@:
add dl, [eax+esi]
inc esi
cmp esi, 20
jnz @b
test dl, dl
jz .ok
.n:
add eax, 10h
loop .s
stc
.ok:
ret
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
 
no_acpi_power_off:
call create_trampoline_pgmap
mov cr3, eax
jmp become_real+0x10000
mov eax, cr0
and eax, not 80000001h
mov cr0, eax
jmp 0x5000:.real_mode
 
align 4
.real_mode:
 
; setup stack
 
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
mov ss, ax
mov esp, TMP_STACK_TOP and 0xFFFF
 
;remap IRQs
mov al, 0x11
out 0x20, al
out 0xA0, al
 
mov al, 0x08
out 0x21, al
mov al, 0x70
out 0xA1, al
 
mov al, 0x04
out 0x21, al
mov al, 0x02
out 0xA1, al
 
mov al, 0x01
out 0x21, al
out 0xA1, al
 
mov al, 0xB8
out 0x21, al
mov al, 0xBD
out 0xA1, al
 
mov al, 00110100b
out 43h, al
mov al, 0xFF
out 40h, al
out 40h, al
 
mov al, byte [es:0x9030]
cmp al, SYSTEM_RESTART
je .do_restart
 
jmp $
 
.do_restart:
 
mov ax, 0x0003 ; set text mode for screen
int 0x10
sti
 
; (hint by Black_mirror)
; We must read data from keyboard port,
; because there may be situation when previous keyboard interrupt is lost
; (due to return to real mode and IRQ reprogramming)
; and next interrupt will not be generated (as keyboard waits for handling)
in al, 0x60
 
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock
mov ax, 'KL'
jmp 0x1000:0000
 
 
align 4
org restart_kernel_5000 + $
restart_code_end:
 
iglobal
align 4
realmode_gdt:
5970,7 → 6025,7
; selector 8 - code from 1000:0000 to 1000:FFFF
dw 0FFFFh
dw 0
db 1
db 5
db 10011011b
db 00000000b
db 0
5983,6 → 6038,8
db 0
endg
 
org $+OS_BASE
 
if ~ lang eq sp
diff16 "end of .text segment",0,$
end if
/kernel/branches/Kolibri-acpi/network/IPv4.inc
634,6 → 634,8
push ecx ax edi
mov eax, edi
call ipv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
test eax, eax
jz .no_route
push edx
test edi, edi
jz .loopback
683,6 → 685,12
xor eax, eax
ret
 
.no_route:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: No route to host!\n"
add esp, 2*4+2
xor eax, eax
ret
 
.arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 4
917,7 → 925,7
; ebx = outgoing device / 0 ;
; edx = Source IP ;
; ;
; OUT: eax = Destination IP (or gateway IP) ;
; OUT: eax = Destination IP (may be gateway), 0 on error ;
; edx = Source IP ;
; edi = device number*4 ;
; ;
926,7 → 934,7
; ;
;-----------------------------------------------------------------;
align 4
ipv4_route: ; TODO: return error if no valid route found
ipv4_route:
 
test ebx, ebx
jnz .got_device
979,6 → 987,7
ret
 
.fail:
xor eax, eax
ret
 
 
/kernel/branches/Kolibri-acpi/video/cursors.inc
571,10 → 571,11
jnz @B
 
pop edi
pop esi
 
;--------------------------------------
align 4
.ret:
pop esi
pop ebx
ret
endp
605,10 → 606,11
jnz @B
 
pop edi
pop esi
 
;--------------------------------------
align 4
.ret:
pop esi
pop ebx
ret
endp