보호 모드 프로그래밍에서 IDT 설정

gurugio의 이미지

처음 부팅돼고 보호 모드로 들어가기 전에

IDT를 NULL로 설정하려고 합니다.

리눅스 소스 arch/i386/boot/setup.S 에 나온대로

offsetIDT
.word 0
.word 0, 0

이렇게 idtr 에 저장할 값을 만들고

역시 소스그대로

lidt offsetIDT

이렇게 했더니 재부팅이 돼버립니다.

제가 뭘 잘못한걸까요?

전체 소스도 올립니다.

----------------------------------------------------------------

.equ SETUPSEG, 0x9020
.equ STACKSEG, 0x9000
.equ STACKOFF, 0x8000

.equ OSCODE, 0x8
.equ OSDATA, 0x10

.code16
.text

.global _start
_start
#movb $'3', %al
#call PRINT_CHAR
call PRINT_NL

#call PRINT_REGISTERS
jmp START_SETUP

nBytesPerSect
.word 0x200
nSectPerTrack
.word 0x12
nHeads
.word 0x2
bBootDrive
.byte 0x00

stGDT
.word 0, 0, 0, 0 # NULL descriptor
.word 0xffff, 0, 0x9a00, 0xcf # OS code descriptor
.word 0xffff, 0, 0x9200, 0xcf # OS data descriptor
.word 0, 0, 0, 0 # dummy

offsetGDT
.word 0x800
.word 0, 0

offsetIDT
.word 0
.word 0, 0


START_SETUP
# set data segment
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
#call PRINT_REGISTERS

# print setup message
movw $SETUP_MSG, %si
call PRINT_STRING

cli

call ACTIVATE_A20

# set IDT to null
lidt offsetIDT #=============>> 여기서 재부팅이 됍니다.
call PRINT_REGISTERS

# set GDT
xorl %eax, %eax # compute address of stGDT
movw %ds, %ax
shll $4, %eax
addl $stGDT, %eax
movl %eax, (offsetGDT+2) # save address in pIDT
lgdt offsetGDT # set gdtr

sti

call PRINT_REGISTERS
movw $PMODE_MSG, %si
call PRINT_STRING

movl %cr0, %eax
orl $0x1, %eax
movl %eax, %cr0

ljmp $OSCODE, $OK_PMODE

# activate A20 line
ACTIVATE_A20
pushw %ax

ACTIVATE_A20_UPPER
inb $0x64, %al
testb $0x2, %al
jnz ACTIVATE_A20_UPPER
movb $0xd1, %al
outb %al, $0x64

ACTIVATE_A20_BOTTOM
inb $0x64, %al
testb $2, %al
jnz ACTIVATE_A20_BOTTOM
movb $0xdf, %al
outb %al, $0x60

popw %ax
ret

# print registers
PRINT_REGISTERS
pusha

movb $'a', %al # print ax
call PRINT_CHAR
call PRINT_WORD
call PRINT_NL

movb $'b', %al # print bx
call PRINT_CHAR
movw %bx, %ax
call PRINT_WORD
call PRINT_NL

movb $'c', %al # print cx
call PRINT_CHAR
movw %cx, %ax
call PRINT_WORD
call PRINT_NL

movb $'d', %al # print dx
call PRINT_CHAR
movw %dx, %ax
call PRINT_WORD
call PRINT_NL

movb $'c', %al # print cs
call PRINT_CHAR
movw %cs, %ax
call PRINT_WORD
call PRINT_NL

movb $'d', %al # print ds
call PRINT_CHAR
movw %ds, %ax
call PRINT_WORD
call PRINT_NL

movb $'s', %al # print ss
call PRINT_CHAR
movw %ss, %ax
call PRINT_WORD
call PRINT_NL

movb $'p', %al # print sp
call PRINT_CHAR
movw %sp, %ax
call PRINT_WORD
call PRINT_NL

popa
ret

# print one character
# argument al
PRINT_CHAR
pushw bx
# int 0x10 - 0xe service
movb $0xe, %ah
movw $0x7, %bx
int $0x10
popw bx
ret

# print new-line
PRINT_NL
pushw %ax
movb $0xd, %al
call PRINT_CHAR
movb $0xa, %al
call PRINT_CHAR
popw %ax
ret

# print ascii-zero string
# argument si (pointer of string)
PRINT_STRING
pushw ax
PRINT_STRING_LOOP
movb (%si), %al
cmpb $0, %al
je PRINT_STRING_END
call PRINT_CHAR
incw %si
jmp PRINT_STRING_LOOP
PRINT_STRING_END
popw ax
ret

# print one word
# argument ax
PRINT_WORD
pushw %dx
movw %ax, %dx # save original value
movb %dh, %al # print upper byte
call PRINT_BYTE
movb %dl, %al # print bottom byte
call PRINT_BYTE
popw %dx
ret

# print one byte number
# argument al (number to print)
PRINT_BYTE
pushw %dx
pushw %bx
movw $0x7, %bx
movb $0xe, %ah

movb %al, %dl # save original value

shrb $4, %al # print upper nibble
addb $0x30, %al
cmp $0x39, %al
jle PRINT_BYTE_UPPER
addb $7, %al
PRINT_BYTE_UPPER
int $0x10

movb %dl, %al # restore al
andb $0xf, %al # print bottom nibble
addb $0x30, %al
cmp $0x39, %al
jle PRINT_BYTE_LOWER
addb $7, %al
PRINT_BYTE_LOWER
int $0x10

popw %bx
popw %dx
ret

SETUP_MSG
.ascii "start setup"
.byte 0xd, 0xa, 0x0

PMODE_MSG
.ascii "turn to protected mode"
.byte 0xd, 0xa, 0x0

.code32
OK_PMODE
movw $0x10, %ax
movw %ax, %ds
movl $0xb8000, %esi
movl $'O', (%esi)

END_SETUP
jmp END_SETUP

.org 1024

Necromancer의 이미지

8259A 마스킹이나 벡터 변경부분이 안보이네요.
그리고 idtr 레지스터는 처음 2Byte는 테이블 크기(대부분 0x7ff)이지만,
다음 4Byte에는 0이 아니고 IDT 테이블이 위치하는 절대주소가 와야 합니다.
제가 알고 있는것은 이정도네요.

또 인텔 문서에서는 GDTR이나 IDTR 값을 가져오는 변수의 주소는 8n+2의 값을 권장하고 있습니다.
즉, 8의 배수 +2의 값을 갖는 메모리 주소가 좋다는거죠.

아 참 그리고 환경도 궁금하네요.
도스환경이라면 보호모드잡는 emm386이나, dpmi류의 프로그램들이
떠있는건 아니겠죠. (얘네들이 V86모드로 돌리면 보호모드 진입은 불가입니다)

Written By the Black Knight of Destruction

gurugio의 이미지

이 소스는 부트 로더 바로 다음에 실행됩니다.

그래서 8259 마스킹을 안하고 테이블 절대 주소도 0으로 해서

사용하지 않으려고 한 것입니다.

음.. 흑기사님 말씀대로 IDT를 가짜로라도 만들어서

주소를 넣어서 해봐야겠습니다.

감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.