Created
December 13, 2011 21:56
-
-
Save leventov/1474068 to your computer and use it in GitHub Desktop.
lab4: protected mode with paging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.arch pentium4 | |
.code16 | |
.section .text | |
.org 0x100 | |
_gdt: .quad 0 | |
.byte 0xFF, 0xFF, 0, 0, 0xF, 0b10011010, 0b00001111, 0 # код | |
.byte 0xFF, 0xFF, 0, 0, 0xF, 0b10010000, 0b00001111, 0 # данные | |
.byte 0x00, 0x80, 0,0x80, 0xB, 0b10010010, 0b00000000, 0 # видео | |
.byte 0xFF, 0xFF, 0, 0, 9, 0b10010010, 0b00000000, 0 # стек, буфер | |
.byte 0x00, 0x10, 0, 0,0x12, 0b10010010, 0b00000000, 0 # каталог страниц | |
_gdt_size = . - _gdt | |
GDTR: .word _gdt_size - 1 | |
.long 0x10000 | |
_idt: .rept 0x20 | |
.quad 0 | |
.endr | |
.quad 0 | |
.word i09_handler, 8, 0b1000011000000000, 0 | |
.rept 0xF | |
.quad 0 | |
.endr | |
.word i16_handler, 8, 0b1000011000000000, 0 | |
_idt_size = . - _idt | |
IDTR: .word _idt_size - 1 | |
.long 0x11000 | |
start: | |
cli | |
lss %cs:STKPTR, %sp | |
sti | |
mov $0x0AA55, %di | |
mov $3, %bh | |
mov BEGSEG, %dx | |
lo: | |
mov %dx, %ds | |
cld | |
xor %si, %si | |
mov %ds:(%si), %ax | |
sub %di, %ax | |
jnz skipp | |
mov %ds:2, %ah | |
mov %ax, %cx | |
add %bh, %ah | |
not %bh | |
and %bh, %ah | |
not %bh | |
shr $3, %ax | |
add %ax, %dx | |
call scanbios | |
check: cmp $0xF000, %dx | |
jb lo | |
call init | |
call pm | |
call pg | |
sti | |
mov $0x18, %bx | |
mov %bx, %es | |
xor %ax, %ax | |
xor %di, %di | |
mov $2000, %cx # clear video memory of text mode | |
rep stosw | |
xor %di, %di | |
typing: | |
hlt | |
int $0x31 | |
jz typing | |
# push word ptr COUNT | |
# push 1 | |
# push dx | |
# push 1 | |
# int 60h | |
# add sp, 8 | |
# mov $0xE, %ah | |
# mov 1, %bx | |
# int $0x10 | |
mov $0xF, %ah | |
stosw | |
jmp typing | |
skipp: add $0x80, %dx | |
jmp check | |
STKPTR: .word 0xFFFE,0x9000 | |
BEGSEG: .word 0xC000 | |
COUNT: .word 0x9000 | |
PCO: .word 0x20 | |
com_l: .byte 0xAA, 0x64, 0xAB, 0x64, 0xFF, 0x60, 0x11 | |
ans_l: .byte 0x55, 0x11 ,0, 0x11, 0xFA, 0xAA, 0x11 | |
pm: | |
mov %cs, %ax | |
mov %ax, %ds | |
mov $_gdt, %si | |
mov $0x1000, %ax | |
mov %ax, %es | |
xor %di, %di | |
mov $_gdt_size/4, %cx | |
cld | |
rep movsl | |
mov $_idt, %si | |
mov $0x1100, %ax | |
mov %ax, %es | |
xor %di, %di | |
mov $_idt_size/4, %cx | |
rep movsl | |
lgdt GDTR | |
lidt IDTR | |
# we do not assign interrupts at all (IDT is empty) -> so disable interrupts at all | |
cli # disable int# | |
inb $0x70 | |
or $0x80, %al # disable NMI | |
outb $0x70 | |
# turn on 16bit i80286+ protected mode | |
mov %cr0, %eax | |
or $0x00000001, %eax | |
mov %eax, %cr0 | |
.byte 0xEA | |
.word next | |
.word 8 | |
# load other segment registers | |
next: mov $0x18, %ax | |
mov %ax, %es | |
mov $0x20, %ax | |
mov %ax, %ds | |
mov %ax, %ss | |
inb $0x70 | |
and $0x7F, %al # allow NMI | |
outb $0x70 | |
sti # allow int# | |
ret | |
_pde: .byte 0b010000111, 0, 0, 0 #PS=1, U/S=1, R/W=1, P=1, base=0 | |
pg: | |
mov $0x28, %ax | |
mov %ax, %es | |
mov %cs:_pde, %eax | |
xor %di, %di | |
stosl | |
mov $1023, %cx | |
xor %eax, %eax | |
rep stosl | |
mov $0x120000, %eax | |
mov %eax, %cr3 | |
mov $1, %eax | |
shl $4, %eax # PSE=1 // 4th in cr4 | |
mov %cr4, %ebx | |
or %eax, %ebx | |
mov %ebx, %cr4 | |
shl $27, %eax # PG=1 //last in cr0 | |
mov %cr0, %ebx | |
or %eax, %ebx | |
mov %ebx, %cr0 | |
ret | |
scanbios: | |
xor %bl, %bl | |
chcksm: | |
lodsw | |
addb %ah, %al | |
addb %al, %bl | |
decw %cx | |
jnz chcksm | |
or %bl, %bl | |
jnz skip | |
pusha | |
push %ds | |
push %es | |
push %fs | |
push %gs | |
push %cs | |
pushw $__ret | |
push %ds | |
pushw $3 | |
lret | |
__ret: | |
pop %gs | |
pop %fs | |
pop %es | |
pop %ds | |
popa | |
skip: | |
ret $0 | |
.set P0, 0x20 | |
.set P1, 0xA0 | |
init: | |
mov $0x20, %al | |
outb $P0 | |
outb $P1 | |
mov $0b00010000, %al | |
outb $P0 #icw1 pic0 | |
mov $0x20, %al | |
outb $P0 + 1 #icw2 pic0 | |
mov 0b100, %al | |
outb $P0 + 1 #icw3 pic0 | |
# mov al, 00010000b | |
# out 0A0h, al ;icw1 pic1 | |
# | |
# mov al, 70h | |
# out 0A1h, al ;icw2 pic1 | |
# | |
# mov al, 10b | |
# out 0A1h, al ;icw3 pic1 | |
mov $0b11111101, %al | |
outb $P0 + 1 #ocw1 pic0 | |
mov $com_l, %di | |
mov $ans_l, %si | |
w4: mov %cs:(%di), %bl | |
inc %di | |
cmp $0x11, %bl | |
jz kb_out | |
mov $0xFFF0, %cx | |
w40: inb $0x64 | |
test $2, %al | |
jz w41 | |
loop w40 | |
jmp error | |
w41: mov %bl, %al | |
xor %dx, %dx | |
mov %cs:(%di), %ah | |
inc %di | |
cmp $0x64, %ah | |
jnz o60 | |
outb $0x64 | |
jmp l5 | |
o60: outb $0x60 | |
# out dx, al | |
l5: mov %cs:(%si), %bl | |
inc %si | |
cmp $0x11, %bl | |
jz w4 | |
mov $0x2000, %cx | |
lo4: inb $0x64 | |
test $1, %al | |
jz w42 | |
inb $0x60 | |
cmp %al, %bl | |
jz l5 # ok | |
jmp error | |
w42: loop lo4 | |
jmp error | |
kb_out: | |
xor %ax, %ax | |
mov %ax, %es | |
cli | |
movw $i09_handler, %es:9*4 | |
movw %cs, %es:9*4+2 | |
movw $i16_handler, %es:0x16*4 | |
movw %cs, %es:0x16*4+2 | |
sti | |
mov %cs:COUNT, %ds # keyboard preparing | |
mov $1, %al | |
mov %al, %ds:0 | |
mov $2, %al | |
mov %al, %ds:1 | |
call timer_init | |
ret | |
error: | |
call wr | |
call stop | |
i09_handler: | |
push %ax | |
push %bx | |
push %cx | |
push %dx | |
push %si | |
push %ds | |
mov $0xAD, %al | |
outb $0x64 | |
xor %ax, %ax | |
inb $0x60 | |
test $0b10000000, %al | |
jnz rls | |
mov %cs:PCO, %ds | |
mov %ds:0, %dx | |
cmp %dl, %dh | |
jz rls | |
dec %ax | |
mov $alpha, %bx | |
add %ax, %bx | |
mov %cs:(%bx), %al | |
xor %cx, %cx | |
mov %al, %cl # shift randomizing | |
inb $0x42 | |
test $1, %al | |
jz sss | |
xor $32, %cl | |
sss: | |
xor %ax, %ax | |
mov %dh, %al | |
mov %ax, %si | |
mov %cl, %ds:(%si) | |
inc %al | |
and $0b00011111, %al | |
jnz nz | |
mov $2, %al | |
nz: mov %al, %ds:1 | |
rls: | |
mov $0x20, %al #eoi | |
outb $P0 | |
mov $0xAE, %al #scan allow | |
outb $0x64 | |
pop %ds | |
pop %si | |
pop %dx | |
pop %cx | |
pop %bx | |
pop %ax | |
iret | |
i16_handler: | |
lahf | |
push %dx | |
push %bx | |
push %si | |
push %ds | |
mov %ax, %bx | |
mov %cs:PCO, %ds | |
mov %ds:0, %dx | |
inc %dl | |
and $0b00011111, %dl | |
jnz norm | |
mov $2, %dl | |
norm: cmp %dl, %dh | |
jz sk4 | |
xor %ax, %ax | |
mov %dl, %al | |
mov %dl, %ds:0 | |
mov %ax, %si | |
mov %ds:(%si), %al | |
and $0b10111111, %bh | |
jmp sk5 | |
sk4: or $0b1000000, %bh | |
sk5: mov %bh, %ss:12(%esp) | |
pop %ds | |
pop %si | |
pop %bx | |
pop %dx | |
iret | |
timer_init: | |
push %ax | |
inb $0x61 | |
and $0b11111101, %al | |
or $0b00000001, %al | |
outb $0x61 | |
mov $0b10110100, %al | |
outb $0x43 | |
xor %al, %al | |
outb $0x42 | |
mov $5, %al | |
outb $0x42 | |
pop %ax | |
ret | |
wr: | |
push %cs | |
push $msg1 | |
push $0 | |
int $0x60 | |
add $6, %sp | |
ret | |
msg1: .asciz "Error!!1" | |
stop: | |
cli | |
hlt | |
jmp stop | |
alpha: .ascii " 1234567890-+ " | |
.ascii "qwertyuiop[] " | |
.ascii "asdfghjkl;\"` " | |
.ascii "\\zxcvbnm,./ " | |
.ascii " " | |
.byte 0 | |
# real startup entry begins at F000:FFF0 | |
.org 0xFFF0 | |
.byte 0xEA | |
.word start | |
.word 0xF000 | |
.org 0xFFFE | |
.word 0x99FC | |
.end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.arch pentium4 | |
.code16 | |
.section .text | |
.org 0x100 | |
_gdt: .quad 0 | |
.byte 0xFF, 0xFF, 0, 0, 0xF, 0b10011010, 0b00001111, 0 # код | |
.byte 0xFF, 0xFF, 0, 0, 0xF, 0b10010000, 0b00001111, 0 # данные | |
.byte 0x00, 0x80, 0,0x80, 0xB, 0b10010010, 0b00000000, 0 # видео | |
.byte 0xFF, 0xFF, 0, 0, 9, 0b10010010, 0b00000000, 0 # стек, буфер | |
.byte 0x00, 0x10, 0, 0,0x12, 0b10010010, 0b00000000, 0 # каталог страниц | |
_gdt_size = . - _gdt | |
GDTR: .word _gdt_size - 1 | |
.long 0x10000 | |
_idt: .rept 0x20 | |
.quad 0 | |
.endr | |
.quad 0 | |
.word i09_handler, 8, 0b1000011000000000, 0 | |
.rept 0xF | |
.quad 0 | |
.endr | |
.word i16_handler, 8, 0b1000011000000000, 0 | |
_idt_size = . - _idt | |
IDTR: .word _idt_size - 1 | |
.long 0x11000 | |
start: | |
cli | |
lss %cs:STKPTR, %sp | |
sti | |
mov $0x0AA55, %di | |
mov $3, %bh | |
mov BEGSEG, %dx | |
lo: | |
mov %dx, %ds | |
cld | |
xor %si, %si | |
mov %ds:(%si), %ax | |
sub %di, %ax | |
jnz skipp | |
mov %ds:2, %ah | |
mov %ax, %cx | |
add %bh, %ah | |
not %bh | |
and %bh, %ah | |
not %bh | |
shr $3, %ax | |
add %ax, %dx | |
call scanbios | |
check: cmp $0xF000, %dx | |
jb lo | |
call init | |
call pm | |
call pg | |
sti | |
mov $0x18, %ax | |
mov %ax, %es | |
xor %bx, %bx | |
mov $0x7FFF, %ax | |
nan: mov %ax, %di | |
mov %bx, %es:(%di) | |
dec %ax | |
jnz nan | |
typing: | |
hlt | |
int $0x31 | |
jz typing | |
# push word ptr COUNT | |
# push 1 | |
# push dx | |
# push 1 | |
# int 60h | |
# add sp, 8 | |
# mov $0xE, %ah | |
# mov 1, %bx | |
# int $0x10 | |
mov $0xF, %ah | |
mov %bx, %di | |
mov %ax, %es:(%di) | |
add $2, %bx | |
jmp typing | |
skipp: add $0x80, %dx | |
jmp check | |
STKPTR: .word 0xFFFE,0x9000 | |
BEGSEG: .word 0xC000 | |
COUNT: .word 0x9000 | |
PCO: .word 0x20 | |
com_l: .byte 0xAA, 0x64, 0xAB, 0x64, 0xFF, 0x60, 0x11 | |
ans_l: .byte 0x55, 0x11 ,0, 0x11, 0xFA, 0xAA, 0x11 | |
pm: | |
mov %cs, %ax | |
mov %ax, %ds | |
mov $_gdt, %si | |
mov $0x1000, %ax | |
mov %ax, %es | |
xor %di, %di | |
mov $_gdt_size/4, %cx | |
cld | |
rep movsl | |
mov $_idt, %si | |
mov $0x1100, %ax | |
mov %ax, %es | |
xor %di, %di | |
mov $_idt_size/4, %cx | |
rep movsl | |
lgdt GDTR | |
lidt IDTR | |
# we do not assign interrupts at all (IDT is empty) -> so disable interrupts at all | |
cli # disable int# | |
inb $0x70 | |
or $0x80, %al # disable NMI | |
outb $0x70 | |
# turn on 16bit i80286+ protected mode | |
mov %cr0, %eax | |
or $0x00000001, %eax | |
mov %eax, %cr0 | |
.byte 0xEA | |
.word next | |
.word 8 | |
# load other segment registers | |
next: mov $0x18, %ax | |
mov %ax, %es | |
mov $0x20, %ax | |
mov %ax, %ds | |
mov %ax, %ss | |
inb $0x70 | |
and $0x7F, %al # allow NMI | |
outb $0x70 | |
sti # allow int# | |
ret | |
_pde: .byte 0b010000111, 0, 0, 0 #PS=1, U/S=1, R/W=1, P=1, base=0 | |
pg: | |
mov $0x28, %ax | |
mov %ax, %es | |
mov %cs:_pde, %eax | |
xor %di, %di | |
stosl | |
mov $1023, %cx | |
xor %eax, %eax | |
rep stosl | |
mov $0x120000, %eax | |
mov %eax, %cr3 | |
mov $1, %eax | |
shl $4, %eax # PSE=1 // 4th in cr4 | |
mov %cr4, %ebx | |
or %eax, %ebx | |
mov %ebx, %cr4 | |
shl $27, %eax # PG=1 //last in cr0 | |
mov %cr0, %ebx | |
or %eax, %ebx | |
mov %ebx, %cr0 | |
ret | |
scanbios: | |
xor %bl, %bl | |
chcksm: | |
lodsw | |
addb %ah, %al | |
addb %al, %bl | |
decw %cx | |
jnz chcksm | |
or %bl, %bl | |
jnz skip | |
pusha | |
push %ds | |
push %es | |
push %fs | |
push %gs | |
push %cs | |
pushw $__ret | |
push %ds | |
pushw $3 | |
lret | |
__ret: | |
pop %gs | |
pop %fs | |
pop %es | |
pop %ds | |
popa | |
skip: | |
ret $0 | |
.set P0, 0x20 | |
.set P1, 0xA0 | |
init: | |
mov $0x20, %al | |
outb $P0 | |
outb $P1 | |
mov $0b00010000, %al | |
outb $P0 #icw1 pic0 | |
mov $0x20, %al | |
outb $P0 + 1 #icw2 pic0 | |
mov 0b100, %al | |
outb $P0 + 1 #icw3 pic0 | |
# mov al, 00010000b | |
# out 0A0h, al ;icw1 pic1 | |
# | |
# mov al, 70h | |
# out 0A1h, al ;icw2 pic1 | |
# | |
# mov al, 10b | |
# out 0A1h, al ;icw3 pic1 | |
mov $0b11111101, %al | |
outb $P0 + 1 #ocw1 pic0 | |
mov $com_l, %di | |
mov $ans_l, %si | |
w4: mov %cs:(%di), %bl | |
inc %di | |
cmp $0x11, %bl | |
jz kb_out | |
mov $0xFFF0, %cx | |
w40: inb $0x64 | |
test $2, %al | |
jz w41 | |
loop w40 | |
jmp error | |
w41: mov %bl, %al | |
xor %dx, %dx | |
mov %cs:(%di), %ah | |
inc %di | |
cmp $0x64, %ah | |
jnz o60 | |
outb $0x64 | |
jmp l5 | |
o60: outb $0x60 | |
# out dx, al | |
l5: mov %cs:(%si), %bl | |
inc %si | |
cmp $0x11, %bl | |
jz w4 | |
mov $0x2000, %cx | |
lo4: inb $0x64 | |
test $1, %al | |
jz w42 | |
inb $0x60 | |
cmp %al, %bl | |
jz l5 # ok | |
jmp error | |
w42: loop lo4 | |
jmp error | |
kb_out: | |
xor %ax, %ax | |
mov %ax, %es | |
cli | |
movw $i09_handler, %es:9*4 | |
movw %cs, %es:9*4+2 | |
movw $i16_handler, %es:0x16*4 | |
movw %cs, %es:0x16*4+2 | |
sti | |
mov %cs:COUNT, %ds # keyboard preparing | |
mov $1, %al | |
mov %al, %ds:0 | |
mov $2, %al | |
mov %al, %ds:1 | |
call timer_init | |
ret | |
error: | |
call wr | |
call stop | |
i09_handler: | |
push %ax | |
push %bx | |
push %cx | |
push %dx | |
push %si | |
push %ds | |
mov $0xAD, %al | |
outb $0x64 | |
xor %ax, %ax | |
inb $0x60 | |
test $0b10000000, %al | |
jnz rls | |
mov %cs:PCO, %ds | |
mov %ds:0, %dx | |
cmp %dl, %dh | |
jz rls | |
dec %ax | |
mov $alpha, %bx | |
add %ax, %bx | |
mov %cs:(%bx), %al | |
xor %cx, %cx | |
mov %al, %cl # shift randomizing | |
inb $0x42 | |
test $1, %al | |
jz sss | |
xor $32, %cl | |
sss: | |
xor %ax, %ax | |
mov %dh, %al | |
mov %ax, %si | |
mov %cl, %ds:(%si) | |
inc %al | |
and $0b00011111, %al | |
jnz nz | |
mov $2, %al | |
nz: mov %al, %ds:1 | |
rls: | |
mov $0x20, %al #eoi | |
outb $P0 | |
mov $0xAE, %al #scan allow | |
outb $0x64 | |
pop %ds | |
pop %si | |
pop %dx | |
pop %cx | |
pop %bx | |
pop %ax | |
iret | |
i16_handler: | |
lahf | |
push %dx | |
push %bx | |
push %si | |
push %ds | |
mov %ax, %bx | |
mov %cs:PCO, %ds | |
mov %ds:0, %dx | |
inc %dl | |
and $0b00011111, %dl | |
jnz norm | |
mov $2, %dl | |
norm: cmp %dl, %dh | |
jz sk4 | |
xor %ax, %ax | |
mov %dl, %al | |
mov %dl, %ds:0 | |
mov %ax, %si | |
mov %ds:(%si), %al | |
and $0b10111111, %bh | |
jmp sk5 | |
sk4: or $0b1000000, %bh | |
sk5: mov %bh, %ss:12(%esp) | |
pop %ds | |
pop %si | |
pop %bx | |
pop %dx | |
iret | |
timer_init: | |
push %ax | |
inb $0x61 | |
and $0b11111101, %al | |
or $0b00000001, %al | |
outb $0x61 | |
mov $0b10110100, %al | |
outb $0x43 | |
xor %al, %al | |
outb $0x42 | |
mov $5, %al | |
outb $0x42 | |
pop %ax | |
ret | |
wr: | |
push %cs | |
push $msg1 | |
push $0 | |
int $0x60 | |
add $6, %sp | |
ret | |
msg1: .asciz "Error!!1" | |
stop: | |
cli | |
hlt | |
jmp stop | |
alpha: .ascii " 1234567890-+ " | |
.ascii "qwertyuiop[] " | |
.ascii "asdfghjkl;\"` " | |
.ascii "\\zxcvbnm,./ " | |
.ascii " " | |
.byte 0 | |
# real startup entry begins at F000:FFF0 | |
.org 0xFFF0 | |
.byte 0xEA | |
.word start | |
.word 0xF000 | |
.org 0xFFFE | |
.word 0x99FC | |
.end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment