Ok (sorry by evering starting replies with Ok, anyway...), i did adjusted the code into a your tips, and each time a adjust it i get an different error.
This code is and simple kernel to backup data form a area of disk to another area on this same disk, encoding contents.
At this time, as the most of the times before, the code boots, displays the "[ ]" in the begginning of screen, and then freezes, ctrl+alt+del don't take any effect, what means that the interrupt flags still off (what was supposed to be like that).
This time, i'll put both the boot and kernel codes, so now everything of this program will be here.
1: Can i use 32-bit code without entering protected mode (acessing only base memory), like in the thread "Showstat"?.
3: There's any problem about entering and exiting protected mode without setting segment registers that are not in use, like SS, FS or GS?
4: are the segment registers 16 or 32-bits? if they're 16-bits, how do i can move eax to they? and if they're 32-bit, do i need to move eax to they instead ax, after entering protected mode?
Code: Select all
[BITS 16]
[ORG 0x0500]
;clear interrupt falg
CLI
;Set up flags, segment register and stack pointers:
Xor ax,ax
Push ax
Popf
Mov ds,ax
Mov ss,ax
Mov ax,0B800h
Mov es,ax
Mov bp,STACK
Mov sp,STACK+0200h
;disable text blinking cursor (sometimes the bios enables it before booting)
Mov ah,01h
Mov cx,02B0Bh
Int 010h
;This loop clears the screen, without using Rep Stosw
;but using a block of Stosw's and then a Loop instruction that
;returns to the beggining of this block, this turns the operation
;much faster than a "Rep Stosw"
Xor ax,ax
Xor di,di
Mov cx,03Eh
LOOPCLEAR:
TIMES 020h db 0ABh ;(020h * Stosw)
Loop LOOPCLEAR
TIMES 010h db 0ABh ;(010h * Stosw)
;Once the system booted by floppy, the disk must be reseted before
;being acessed, if the reseting don't work the rest of the code is useless,
;because this means the disk is damaged,
;so the code only proceeds when the disk has been sucessfully reseted.
;In all disk errors therefore, the code will beep three times, reset the disk,
;beep three times again and try again, and, if there's more than five errors,
;the code will skip the current sector
;those beeps are used to warn me about the errors, and to create a type of
;delay beteween reseting and acessing.
RESET:
Xor ax,ax
Mov dx,080h
Int 013h
Jnc START
Pusha
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Popa
Jmp RESET
;this simply display "[ ]" on the screen.
;that will be used to display the progress
START:
Mov word [es:00h],00F5Bh
Mov word [es:016h],00F5Dh
;this is the first thread: read the sectors from the source of the backup, executing 63 loops
;Of 16 sectors each, that fills the memory from 010000h to 08E000h (63*16*512 = 07E000h bytes)
;and each time the memory gets filled up, it calls a routine that enters protected
;mode, copies the 07E000h bytes from 010000h to 0200000h, and Adds the address
; to put the data by 07E000h, so each time it happens the data is stored in a different place.
;after that routine return to real-mode and returns to the code, the code reset the buffer to 010000h
;again and continue copying sectors from disk, this part of copying memory is a second loop, that happens 250 times,
;in a total of 129Mb of bytes copyied (63*16*250*512).
READISK:
Call RESETEXT
Mov cx,03Fh
Mov byte [COUNTER],0FAh
Mov si,DRD
READLOOP:
Mov ax,04200h
Int 013h
Jc DORESET
Loop CDRD
Call WRITEEXT
Mov word [OFFBUFF1],00000h
Mov word [SEGBUFF1],01000h
Mov cx,03Fh
Call SHOWSTAT
Sub byte [COUNTER],01h
Jnz READLOOP
Jmp DISCHARGE
DORESET:
Cmp di,05h
Je CDRD
Pusha
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Xor ax,ax
Mov dx,080h
Int 013h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Popa
Inc di
Jmp READLOOP
CDRD:
Xor di,di
Add word [OFFBUFF1],02000h
Jnc CONTDRD
Add word [SEGBUFF1],01000h
CONTDRD:
Add word [SECTOR11],010h
Jnc READLOOP
Inc word [SECTOR21]
Jmp READLOOP
;This is the second thread
;firstly, it encripts the data on buffer of extended memory, calling ENCODE routine
;Then it reset the source and destin variables of the protected mode routines
;So next acesses will acess the begging of this buffer
;the rest of this thread is almost equal to the first one, but:
;the loops read the extended memory to base memory, then writes the data on
;base memory to disk.
;the disk area to be acessed is different.
;when this loop ends, there is another counter, called MAINCOUNTER,
;this counter is decreased, and if this is nonzero, the code returns to the first thread.
;If zero, this will Halt the processor, and if the HLT fails by some reason, will enter
;a infinite Loop, by jumping in the self Jmp instruction (Jmp $).
DISCHARGE:
Call ENCODE
Call RESETEXT
Mov byte [COUNTER],0FAh
Mov si,DWD
WRITELOOP:
Call READEXT
Mov word [OFFBUFF2],00000h
Mov word [SEGBUFF2],01000h
Mov cx,03Fh
Call SHOWSTAT
INLOOP:
Mov ax,04300h
Int 013h
Jc DOSET
Loop CDWD
Sub byte [COUNTER],01h
Jnz WRITELOOP
Sub byte [MAINCOUNTER],01h
Jnz READISK
HLT
Jmp $
DOSET:
Cmp di,05h
Je CDWD
Pusha
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Xor ax,ax
Mov dx,080h
Int 013h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Mov ax,0E07h
Int 010h
Popa
Inc di
Jmp INLOOP
CDWD:
Xor di,di
Add word [OFFBUFF2],02000h
Jnc CONTDWD
Add word [SEGBUFF2],01000h
CONTDWD:
Add word [SECTOR12],010h
Jnc INLOOP
Inc word [SECTOR22]
Jmp INLOOP
;this routine Push falgs, genreal registers, DS e ES registers, enter
;protecte mode, move data from base memory to extended memory, get back in real-mode,
;pop everything that has been pushed and returns.
;note the this and the next routines won't use the stack, so SS, EBP and ESP don't matter.
WRITEEXT:
Pushf
Pusha
Push ds
Push es
Xor ax,ax
Mov ds,ax
Mov es,ax
lgdt [GDTP]
Mov eax,CR0
Or eax,01h
Mov CR0,eax
Jmp 08h:CLEARA
[BITS 32]
CLEARA:
Mov ax,010h
Mov ds,ax
Mov es,ax
Mov esi,010000h
Mov edi,[LASTDESTIN]
Mov ecx,01F800h
Rep Movsd
Mov [LASTDESTIN],edi
Jmp 018h:REALA
[BITS 16]
REALA:
Mov ax,020h
Mov ds,ax
Mov es,ax
Mov eax,CR0
Xor eax,01h
Mov CR0,eax
Jmp 0000h:REALB
REALB:
Pop es
Pop ds
Popa
Popf
Ret
;this is routine is the same and WRITEEXT, but do de inverse operation about the direction
; of data moving (EX to BASE).
READEXT:
Pushf
Pusha
Push ds
Push es
Xor ax,ax
Mov ds,ax
Mov es,ax
lgdt [GDTP]
Mov eax,CR0
Or eax,01h
Mov CR0,eax
Jmp 08h:CLEARB
[BITS 32]
CLEARB:
Mov ax,010h
Mov ds,ax
Mov es,ax
Mov edi,010000h
Mov esi,[LASTSOURCE]
Mov ecx,01F800h
Rep Movsd
Mov [LASTSOURCE],esi
Jmp 018h:REALC
[BITS 16]
REALC:
Mov ax,020h
Mov ds,ax
Mov es,ax
Mov eax,CR0
Xor eax,01h
Mov CR0,eax
Jmp 0000h:REALD
REALD:
Pop es
Pop ds
Popa
Popf
Ret
;this routine do the same about pushing, entering proteced mode, getting back to real-mde
;and poping everything, but this don't move nothing, just encript the data in extended memory
;by Adding the First dword by the Second and Adding offset by 4, until reach the dword before
;the last, the last dword is leave intact.
ENCODE:
Pushf
Pusha
Push ds
Push es
Xor ax,ax
Mov ds,ax
Mov es,ax
lgdt [GDTP]
Mov eax,CR0
Or eax,01h
Mov CR0,eax
Jmp 08h:CLEARC
[BITS 32]
CLEARC:
Mov ax,010h
Mov ds,ax
Mov es,ax
Mov ebx,0200000h
LOOPENCODE:
Mov eax,[ebx+04h]
Add [ebx],eax
Add ebx,04h
Cmp ebx,07D0C000h
Jb LOOPENCODE
Jmp 018h:REALE
[BITS 16]
REALE:
Mov ax,020h
Mov ds,ax
Mov es,ax
Mov eax,CR0
Xor eax,01h
Mov CR0,eax
Jmp 0000h:REALF
REALF:
Pop es
Pop ds
Popa
Popf
Ret
;this routine simply reset values of LASTSOURCE and LASTDESTIN
;and it don't need to enter protected mode, just need to be 32-bit code.
[BITS 32]
RESETEXT:
Pushf
Push eax
Mov eax,0200000h
Mov [LASTDESTIN],eax
Mov [LASTSOURCE],eax
Pop eax
Popf
Ret
;this routine simply increase the dword of progress, turn it on decimal code
;and display it inside the "[ ]" that has been displayed on screen.
;As the routine before, only need to be 32-bit, not protected mode.
SHOWSTAT:
Pushf
Pusha
Mov edi,02h
Inc dword [PRGCOUNTER]
Mov eax,[PRGCOUNTER]
Mov ebx,03B9ACA00h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,05F5E100h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,0989680h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,0F4240h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,0186A0h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,02710h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,03E8h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,064h
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov eax,edx
Mov ebx,0Ah
Xor edx,edx
Div ebx
Add ax,0F30h
Stosw
Mov ax,dx
Add ax,0F30h
Stosw
Popa
Popf
Ret
;this is the DAP of the backup source disk area (note that both source and destin are in the same disk)
DRD:
dd 00100010h
OFFBUFF1 dw 00000h
SEGBUFF1 dw 01000h
SECTOR11 dw 0000h
SECTOR21 dw 0000h
dd 00000000h
;this is the DAP of the backup destin disk area
DWD:
dd 00100010h
OFFBUFF2 dw 00000h
SEGBUFF2 dw 01000h
SECTOR12 dw 04E4Ch
SECTOR22 dw 063Eh
dd 00000000h
;this are the variables used during code
MAINCOUNTER db 0A6h
PRGCOUNTER dd 00000000h
COUNTER db 0FAh
LASTDESTIN dd 00200000h
LASTSOURCE dd 00200000h
;this is the GDT, there's the description of it:
;the first two entries after null entrie are 32-bit code and data segment,
;the take the whole addressable space, are unconforming, readable/writeable
;system ring, and the two entries next are the same, but 16-bit.
GDT:
dq 00000000000000000h
dw 0FFFFh
dw 00000h
db 00h
db 010011010b
db 011001111b
db 00h
dw 0FFFFh
dw 00000h
db 00h
db 010010010b
db 011001111b
db 00h
dw 0FFFFh
dw 00000h
db 00h
db 010011010b
db 000001111b
db 00h
dw 0FFFFh
dw 00000h
db 00h
db 010010010b
db 000001111b
db 00h
;GDT pointer
GDTP:
dw GDTP-GDT-1
dd GDT
;1024 bytes stack
STACK:
TIMES 0100h dd 00000000h