Protected Democode 에서

sanjuro의 이미지

인터넷에 있는 Protected Democode 를 도스용이 아닌 부팅하여 바로 전환되게 하려고 해 보았습니다.
문제점이 있었는데, 해결방법을 모르겠습니다.
일단 부트섹터는 플로피 디스크의 바로 뒤에 있는 섹터의 코드를 0x1000에 넣고, 0x1000:0000 으로 세그먼트를 바꾸어 점프합니다.
코드는 아래와 같습니다. 작동에는 이상이 없었습니다.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[org 0]
jmp 07C0h:start ; Goto segment 07C0

start:
; Update the segment registers
mov ax, cs
mov ds, ax
mov es, ax

reset: ; Reset the floppy drive
mov ax, 0 ;
mov dl, 0 ; Drive=0 (=A)
int 13h ;
jc reset ; ERROR => reset again

read:
mov ax, 1000h ; ES:BX = 1000:0000
mov es, ax ;
mov bx, 0 ;

mov ah, 2 ; Load disk data to ES:BX
mov al, 2 ; Load 5 sectors
mov ch, 0 ; Cylinder=0
mov cl, 2 ; Sector=2
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!

jc read ; ERROR => Try again

jmp 1000h:0000 ; Jump to the program

times 510-($-$$) db 0
dw 0AA55h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

문제가 있었던 곳은 Protected Mode Democode 1번의 소스인데요...
너무 길어서 앞부분만 올립니다.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 16]
[ORG 0]
start:

mov ax, cs
mov ds, ax
xor ebx, ebx
mov bx, ds
shl ebx, 4
mov eax, ebx
mov [gdt2+2], ax ; GDT테이블영역에
mov [gdt3+2], ax ; 베이스어드레스등 이러저러한 것을
mov [gdt4+2], ax ; 설정합니다.
mov [gdt5+2], ax ; limit은 0xFFFF로 설정되어 있음.
; GDT는 지금 올린 글에 나와있지
; 않습니다.
shr eax, 16

mov [gdt2+4], al
mov [gdt3+4], al
mov [gdt4+4], al
mov [gdt5+4], al

mov [gdt2+7], ah
mov [gdt3+7], ah
mov [gdt4+7], ah
mov [gdt5+7], ah

lea eax, [gdt+ebx] ; lgdt 명령을 위하여
mov [gdtr+2], eax ; GDT 테이블의 베이스어드레스와
; 크기를 설정.
cli

lgdt [gdtr]

mov eax, cr0
or al, 1
mov cr0, eax ;<-----------문제의 코드


jmp SYS_CODE_SEL:do_pm ; 프로텍티드 모드로...
; SYS_CODE_SEL은
; GDT디스크립터중 하나.
; 32비트 코드의 위치를
; 가리킴.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
화면에 글자를 프린트하는 코드를 넣어서 확인해 보니,
위의 문제의 코드 부분에서 PC가 재부팅 해버립니다.
왜 그런지 이해를 못 하겠습니다.
왜 cr0 레지스터에 값을 쓸 수 없는 건가요?
코드 앞 부분은 정상적으로 실행되는 것 같습니다.
좋은 답변 부탁드립니다.
빨리 제 OS를 만들어 보고 싶습니다. t('_'t)
이만...

sliver의 이미지

삽질 엄청 했슴당..-_-;

[BITS 16]
[ORG 0]
start:

mov ax, cs
mov ds, ax
xor ebx, ebx
mov bx, ds
shl ebx, 4
mov eax, ebx
mov [gdt2+2], ax ; GDT테이블영역에
mov [gdt3+2], ax ; 베이스어드레스등 이러저러한 것을
mov [gdt4+2], ax ; 설정합니다.
mov [gdt5+2], ax ; limit은 0xFFFF로 설정되어 있음.
; GDT는 지금 올린 글에 나와있지
; 않습니다.
shr eax, 16

mov [gdt2+4], al
mov [gdt3+4], al
mov [gdt4+4], al
mov [gdt5+4], al

mov [gdt2+7], ah
mov [gdt3+7], ah
mov [gdt4+7], ah
mov [gdt5+7], ah


lea eax, [gdt+ebx] ; lgdt 명령을 위하여
mov [gdtr+2], eax ; GDT 테이블의 베이스어드레스와
; 크기를 설정.

위 코드는 base address만 설정합니다.
따라서 limit도 설정하려면,
mov ax,0xffff
mov [gdtr],ax
를 추가해야 합니다.
cli

lgdt [gdtr]

mov eax, cr0
or al, 1
mov cr0, eax ;<-----------문제의 코드
jmp SYS_CODE_SEL:do_pm ; 프로텍티드 모드로... 


위에서 cr0의 PE bit를 1로 세팅하는 부분은 아무문제 없습니다.

아래는 코드의 뒷부분을 더 추가하고 약간 수정한 코드입니다:

[BITS 16]
[ORG 0]
start:

mov ax, cs
mov ds, ax
xor ebx, ebx
mov bx, ds
shl ebx, 4
mov eax, ebx
mov [gdt2+2], ax ; GDT테이블영역에
mov [gdt3+2], ax ; 베이스어드레스등 이러저러한 것을
mov [gdt4+2], ax ; 설정합니다.
mov [gdt5+2], ax ; limit은 0xFFFF로 설정되어 있음.
; GDT는 지금 올린 글에 나와있지
; 않습니다.
shr eax, 16

mov [gdt2+4], al
mov [gdt3+4], al
mov [gdt4+4], al
mov [gdt5+4], al

mov [gdt2+7], ah
mov [gdt3+7], ah
mov [gdt4+7], ah
mov [gdt5+7], ah


lea eax, [gdt+ebx] ; lgdt 명령을 위하여
mov [gdtr+2], eax ; GDT 테이블의 베이스어드레스와
mov ax,0xffff
mov [gdtr],ax ; 크기를 설정.
cli

lgdt [gdtr]

mov eax, cr0
or al, 1
mov cr0, eax ;<-----------문제의 코드
jmp 0x0008:do_pm ; 프로텍티드 모드로...
; 1 << 3 == 8

; 1번째 segment descriptor의 addressing mode는 32bit(db=1)이고, 바로 위에서
;  far jmp를 통해 CS register를 reload했으므로 여기서부터는 32bit mode로 어셈블 해야 합니다. 따라서 [BITS 32]가 필요합니다.
[BITS 32]
do_pm:
mov ax,0x0010
mov ds,ax ; reload DS register
xor ecx,ecx
again:
inc cl
mov [0xa8000],cl ; 0xB8000 = 0xA8000 + 0x10000(base address=0x10000이므로)
jmp again

align 8 ; gdt는 8byte-aligned되어야함
gdt: ; 0번째 descriptor는 null-descriptor가 되어야함
dd 0,0
gdt2: ; Code segment     limit=0xffff, db=1(32bit addressing mode), G=1(4KB unit), P=1, DPL=0, S=0, Type=1011b(Code:Execute/Read,accessed)
dd 0x0000ffff,00000000110011111001101100000000b
gdt3: ; Data segment     Type=0011(Data:Read/Write,accessed)를 제외하고 Code segment와 모두 같음
dd 0x0000ffff,00000000110011111001001100000000b
gdt4:
dd 0,0
gdt5:
dd 0,0
gdtr:

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.