flash
Joined: 11 Mar 2006
Posts: 55
Location: Cuba
|
Hi!
I am using qemu. But since i must make some work on ubuntu i decided to install a dual boot with W7 and Ubuntu 11.10.
Then i choose to work mostly in W7 and use VMware to access ubuntu partition throw a virtual machine. It work fine all the time.
So i write my test codes over ubuntu virtual machine that runs qemu eventualy. From this virtual machine, the following code works great at qemu. But some how strange happens if i boot ubuntu real partition, in this case the same code (even the compiled binary) throws General protection fault . And it is indicating code 123h: irq source and fault because machine check exception(12h). I am completely stucked to find the cause of this behavior. Some body have encountered similar effects?? I am doing something wrong?
This is the code, just set pm, load some sectors via pio and lba48 and executes it at 0x80000 and the interrupts "used" are 0,1,13,32,33 and 40.
note: when i call ints separately (via software and avoiding sti) there are no problems. An other interesting thing is that replacing hlt by iret at int 13 isr makes all work fine except for the general protection fault string on screen. What happens here?
format binary as 'img'
org 7C00h
cli
mov ah,0x02 ; Leer
mov al,0x8 ; 8 sectores
mov ch,0x00 ; desde la pista cero
mov cl,0x02 ; comenzando por el segundo sector
mov dh,0x00 ; y en la cabeza cero
mov dl,0x80 ; Utilizar el primer disco duro
mov bx,0x8000 ; copiar en 8000:0
mov es,bx
mov bx,0x0000
@@: int 0x13 ; listo!
jc @b
@@: mov ax,0x2401 ; activar la línea A20
int 0x15
jc @b
cli
lgdt fword [gdtr] ; Inicializar el registro de descriptores globales
mov eax,cr0
or al,1 ; activar el modo protegido
mov cr0,eax
jmp 8:protectedMode ; activar los selectores del modo protegido
use32
protectedMode: jmp 80000h ; Ejecutar el código que se cargó desde disco
align 4
gdt:
dq 0000000000000000h ; descriptor nulo
dq 00cf9a000000ffffh ; código con máximos privilegios
dq 00cf92000000ffffh ; datos con máximos privilegios
.end:
gdtr: dw (gdt.end-gdt)-1
dd gdt
times 510-($-$$) db 0
dw 0aa55h
org 80000h
mov ax,16 ; Update ds and ss
mov ds,ax
mov ss,ax
;
; IRQ remap
;__________________________________________________
mov al,0x11
out 0x20,al
out 0xA0,al
mov al,0x20
out 0x21,al
mov al,0x28
out 0xA1,al
mov al,0x4
out 0x21,al
mov al,0x2
out 0xA1,al
mov al,1
out 0x21,al
out 0xA1,al
xor al,al
out 0x21,al
out 0xA1,al
lidt fword [idtr]
mov al,36h ; "change" timer base
out 43h,al
mov al,00h
out 40h,al
mov al,0ffh
out 40h,al
;
; Código con excepciones
;___________________________________________
mov edi,0b806fh ; Ugly way to prepare date area
mov ecx,25
@@: mov [edi],byte 01001110b
add edi,2
loop @b
mov al,0ah ; Set RTC interrupt frequency
out 70h,al
in al,71h
or al,0fh ; divisor
mov ah,al
mov al,0ah
out 70h,al
mov al,ah
out 71h,al
mov al,0bh ; Activate RTC interrupt
out 70h,al
in al,71h
or al,64 ; set bit 6
mov ah,al
mov al,0bh
out 70h,al
mov al,ah
out 71h,al
sti
jmp $
;
; Interrupt service routines
;_________________________________________________
div_cero: cli
mov esi,divz
mov edi,0b8000h
mov ah,74h
call Print
hlt
trap: cli
mov esi,flt_msg
mov edi,0b8000h
mov ah,74h
call Print
hlt
general_protection:
cli
mov esi,gp_msg
mov edi,0b8000h
mov ah,74h
call Print
pop eax
mov ch,74h
call PrintHex
hlt
timer: cli
inc [syscount]
mov edi,0b8130h
mov eax,[syscount]
mov ch,4eh
call PrintHex
mov al,20h ; end of interruption
out 20h,al
sti
iret
keyboard: cli ; simple keymap use
in al,60h
test al,128
jnz done
mov ah,9
mov edi,[screenpos]
mov esi,keymap
xor ebx,ebx
mov bl,al
mov al,[esi+ebx ]
mov [edi],ax
add edi,2
mov [screenpos],edi
done: mov al,20h
out 20h,al
iret
rtc: cli ; just print time and date
mov al,0ch
out 70h,al
in al,71h
mov edi,0b806eh
mov al,4 ; hours
out 70h,al
in al,71h
call show_bcd
mov [edi], byte ':'
add edi,2
mov al,2 ; minutes
out 70h,al
in al,71h
call show_bcd
mov [edi], byte ':'
add edi,2
mov al,0 ; seconds
out 70h,al
in al,71h
call show_bcd
add edi,2
mov al,6 ; day of the week
out 70h,al
in al,71h
call show_week_day
mov [edi], dword 4e204e2ch
add edi,4
mov al,8 ; month
out 70h,al
in al,71h
call show_month
add edi,2
mov al,7 ; day of the mont
out 70h,al
in al,71h
call show_bcd
add edi,2
mov al,50 ; cantury value
out 70h,al
in al,71h
call show_bcd
mov al,9 ; year value
out 70h,al
in al,71h
call show_bcd
mov al,20h ; end of interrupt to slave and primary pics
out 0A0h,al
out 20h,al
sti
iret
Print:
@@: mov al,[esi]
cmp al,0
je @f
mov [edi],ax
add edi,2
inc esi
jmp @b
@@: ret
PrintHex: xor edx,edx
mov ebx,0f0000000h
push eax
mov cl,28
again: pop eax
push eax
and eax,ebx
shr eax,cl
cmp al,10
jb @f
add al,7 ;'A'-'9'-1
@@: add al,'0'
mov ah,ch
mov [edi],ax
add edi,2
shr ebx,4
sub cl,4
inc edx
cmp edx,8
jne again
pop eax
ret
show_bcd: mov ah,al
shr al,4
add al,'0'
mov [edi],al
add edi,2
mov al,ah
and al,0fh
add al,'0'
mov [edi],al
add edi,2
ret
show_week_day: push ecx
xor ah,ah
mov ecx,3
mov ebx,dias
dec eax
mov esi,eax
shl esi,1
add esi,eax
@@: mov al,[ebx+esi]
mov [edi],al
add edi,2
inc esi
loop @b
pop ecx
ret
show_month: push ecx
push ebx
test al,00010000b
jz @f
and al,0fh
add al,10
@@: xor ah,ah
dec eax
mov esi,eax
shl esi,1
add esi,eax
mov ecx,3
mov ebx,meses
@@: mov al,[ebx+esi]
mov [edi],al
add edi,2
inc esi
loop @b
pop ebx
pop ecx
ret
dias db 'DomLunMarMieJueVieSab'
meses db 'EneFebMarAbrMayJunJulAgoSepOctNovDic'
divz db 'Divisi',162,'n por cero',0
flt_msg db 'Trampa del sistema',0
gp_msg db 'Error de protecci',162,'n general. C',162,'digo: ',0
syscount dd 0
screenpos dd 0b8000h + 320
keymap: DB 0
DB 27,'1234567890-=',8
DB 9,'qwertyuiop[]',10
DB 0,'asdfghjkl;',39,96,0,'\'
DB 'zxcvbnm,./',0,'*',0,' '
DB 0,'2345678901',0,'3789-456+1230.'
;
; Interrupt descriptor table
;___________________________________________________________________
align 4
idt:
dw div_cero and 0ffffh ; int 0
dw 8
db 0
db 8eh
dw div_cero shr 16
dw trap and 0ffffh ; int 1
dw 8
db 0
db 8eh
dw trap shr 16
dq 11 dup(0) ; ints 2 - 12
dw general_protection and 0ffffh ; int 13
dw 8
db 0
db 8eh
dw general_protection shr 16
dq 18 dup(0) ; ints 14 - 31
dw timer and 0ffffh ; int 32(irq0)
dw 8
db 0
db 8eh
dw timer shr 16
dw keyboard and 0ffffh ; int 33(irq1)
dw 8
db 0
db 8eh
dw keyboard shr 16
dq 6 dup(0) ; ints 34 - 39(irqs2-7)
dw rtc and 0ffffh ; int 40(irq8)
dw 8
db 0
db 8eh
dw rtc shr 16
dq 215 dup(0) ; ints 41 - 255
.end:
idtr: dw(idt.end-idt)-1
dd idt
times (8*512)-($-$$) db 0 ; Fill sectors, just in case
_________________ i don't hate goto
|