2016-06-26 2 views
1

저는 x86 리얼 모드 프로그래밍을 배우고 있으며, 이것을 테스트하기 위해 QEMU을 사용하여 작은 부트 로더를 작성했습니다. 나는 학습을 위해 GNU 어셈블러를 선택했다. 다음 텍스트가 QEMU 디스플레이에 표시됩니다Int 10H가 QEMU에서 작동하지 않습니다.

# 
# boot.s 
# 

.section .text 
.globl start 
start: 
//setup stack  
    mov  $0x7c0,  %ax 
    mov  %ax,  %ss 
    mov  $512,  %sp 

    //setup video 
    mov  $0x0,  %eax 
    mov  $0x0,  %al 
    int  $0x10 

    //print a character say 'm' 
    mov  $'m',  %al 
    mov  $0x0E,  %ah 
    int  $0x10 
1: 
    jmp 1b 

: 하드 디스크에서

부팅 ...

문제 여기

어셈블리 코드 : 위의 메시지가 인쇄되고, 그 메시지는 계속 표시됩니다. ng.

내가 조립하는 데 사용되는 스크립트, 링크는 다음과 같습니다

> to assemble :  gcc -c boot.s 
> to link  :  ld -T link.ld boot.o -o b.bin 
> to put on bootsector of Hard-disk image 
    dd if=b.bin of=HD.img conv=notrunc 
> to attach boot magic 
    echo -ne "\x55\xaa" | dd seek=510 bs=1 of=HD.img 
> to emulate:  qemu-system-i386 HD.img 

내가 하나를 자신을 만드는 방법을 알고하지 않았기 때문에, 어디 선가 본 온라인 튜토리얼에서 복사 링커 스크립트 :

OUTPUT_FORMAT("binary") 
ENTRY(start) 
phys = 0x00100000; 
SECTIONS 
{ 
.text phys : AT(phys) { 
    code = .; 
    *(.text) 
    *(.rodata) 
    . = ALIGN(4096); 
} 
.data : AT(phys + (data - code)) 
{ 
    data = .; 
    *(.data) 
    . = ALIGN(4096); 
} 
.bss : AT(phys + (bss - code)) 
{ 
    bss = .; 
    *(.bss) 
    . = ALIGN(4096); 
} 
end = .; 
} 

추가 인수를 지정해야합니까, 아니면 코드에 실수가 있습니까? 스택의 설정이라고 생각했지만 많은 가능성을 시도했지만 작동하지 않았습니다.

하드 디스크 부팅 메시지가 나타나서 내 부트 로더가 화면에 m 문자를 표시하도록하려면 어떻게해야합니까?

내 작업 플랫폼은 당신의 링커 스크립트는 보호 모드 커널이 0x00100000라는로드 될 수있는 환경을 위해 작성된 것으로 보인다 페도라 23

+1

"작동하지 않음"은 무엇을 의미합니까? 그것은 의미있는 문제 설명이 아닙니다. –

답변

7

입니다. 이것은 multiboot specification을 따르는 부트 로더에 일반적입니다. 귀하와 같은 리얼 모드 부트 로더는 디스크의 처음 512 바이트에서 읽히고 메모리의 0x7c00에 배치됩니다. 원점 0x7c00을 사용하는 링커 스크립트가 필요합니다. 또한 링커 스크립트를 사용하여 부트 디스크 서명 0xAA55를 출력 할 수 있습니다. 귀하가 boot.s 16 비트 코드를 생성하라고하지 않을

OUTPUT_FORMAT("binary"); 
ENTRY(start); 
SECTIONS 
{ 
    . = 0x7C00; 
    .text : AT(0x7C00) { 
     *(.text); 
    } 
    .data : SUBALIGN(0) { 
     *(.data); 
     *(.rodata); 
    } 
    .bss : SUBALIGN(4) { 
     __bss_start = .; 
     *(COMMON); 
     *(.bss) 
     . = ALIGN(4); 
     __bss_end = .; 
    } 
    __bss_sizel = SIZEOF(.bss)>>2; 
    __bss_sizeb = SIZEOF(.bss); 

    /* Boot signature */ 
    .sig : AT(0x7DFE) { 
     SHORT(0xaa55); 
    } 
} 

:

기본 부트 로더 링커 스크립트는이 link.ld 같은 것을 볼 수 있었다. 어셈블리 파일의 맨 위에 지시문 .code16을 배치하여 강제로 16 비트 명령어를 생성 할 수 있습니다. 또한 GCC 명령을 수정하여 16 비트 코드로 컴파일해야하며 링커에는 -melf_i386 옵션이 필요합니다.

부트 로더 코드는 실제로 DS 레지스터와 스택을 설정해야합니다. 링커 스크립트는 코드가 메모리 위치 0x07c00에 있다고 가정하므로 DS을 0으로 설정해야합니다. segmented model에서 실제 주소 = (세그먼트 < < 4) + 오프셋. DS은 0으로 설정되고 0x7c00의 원본 (기본 오프셋)은 (0 < < 4) + 0x7c00 = BIOS가 부트 로더를로드하는 실제 주소 0x07c00으로 매핑됩니다.

나는 약간 가치가 있을지도 모른다 어떤 general bootloader tip를 가진 응답을 썼다.

# 
# boot.s 
# 

.code16 
.section .text 
.globl start 
start: 
    //setup stack 
    mov  $0x7c0, %ax 
    mov  %ax, %ss 
    mov  $512, %sp 

    xor  %ax, %ax # AX = 0 
    mov  %ax, %ds # Set DS = 0 since origin point is 0x7c00 

    //setup video 
    xor  %ax, %ax # Zero 16-bit AX register (includes AL and AH) 
    //mov $0x0, %ax # Works but is not preferred for zeroing a reg 
    int  $0x10 

    //print a character say 'm' 
    mov  $'m',  %al 
    mov  $0x0E,  %ah 
    int  $0x10 
1: 
    jmp 1b 

조립, 링크 및 사용할 수있는 디스크 이미지 생성하려면 :

gcc -c boot.s -m16 
ld -melf_i386 -T link.ld boot.o -o b.bin -nostdlib --nmagic 
dd if=b.bin of=HD.img conv=notrunc 

당신은 다음 플로피로 이미지를 사용하여 실행할 수를 같은

가 청소 boot.s는 볼 수 있었다 :

qemu-system-i386 -fda HD.img 

또는 사용하는 하드 드라이브 이미지 :

qemu-system-i386 -hda HD.img 
+0

그건 정말 마이클 선생님, 덕분에 일부 vga 드라이버 및 하드 디스크 드라이브 일종의 물건을 할 수있는 몇 가지 문서 (ATA, SATA, PCI IDE의) 지점을 바랍니다 수 있습니다. 나는 구글에서 많은 것을 검색했지만 모두가 레디 메이드 코드를 제공한다. osdev.org조차 포트를 프로그래밍하는 방법이 아닙니다. –

+0

@Madhusoodan : 디스크 관련 일에 관한 문서는 Ralf Brown의 인터 터트리스트 http://www.ctyme.com/intr/cat-003.htm이 좋은 시작입니다. VGA 물건은 광범위합니다, 당신은 그걸 할 수 있어야합니다. –

+0

아니요 더 이상 BIOS에 의존하지 않고 Linux 나 다른 소스에서 복사하는 것을 원하지 않습니다. –

관련 문제