2011-08-16 4 views
14

전 서글 부트 로더의 초보자입니다. helloworld 부트 로더를 asm에 작성했습니다. C에서 helloworld 부트 로더를 작성했지만 컴파일 할 수 없습니다.부트 로더를 C로 작성하십시오

이것은 내 코드입니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 내가 잘못된 접근법을 완전히 취하고 있습니까?

void print_char(); 
int main(void){ 
char *MSG = "Hello World!"; 
int i; 

__asm__(
    "mov %0, %%SI;" 
    : 
    :"g"(MSG) 
); 
for(i=0;i<12;i++){ 
    __asm__(
     "mov %0, %%AL;" 
     : 
     :"g"(MSG[i]) 
    ); 
    print_char(); 
} 

return 0; 
} 

void print_char(){ 
__asm__(
    "mov $0X0E, %AH;" 
    "mov $0x00, %BH;" 
    "mov $0x04, %BL;" 
    "int $0x10" 
); 
} 

답변

13

난 당신이 http://wiki.osdev.org/Rolling_Your_Own_Bootloader 살펴도의 부트 로더 섹션을하는 것이 좋습니다 것입니다. 또한 더 많은 정보가 필요하면 freenode의 #osdev 채널에 참여하여 토론에 참여할 수 있습니다.

+0

위대한 자습서. 감사합니다. –

3

부트 로더는 ASM으로 작성됩니다.

C 코드 (또는 C++ 등)를 컴파일 할 때 컴파일러는 사람이 읽을 수있는 코드를 기계어로 '변환'합니다. 따라서 결과에 대해 확신 할 수 없습니다.

PC가 부팅되면 BIOS가 특정 주소의 코드를 실행합니다. 해당 코드는 직접 실행 가능해야합니다.

그래서 어셈블리를 사용합니다. 수정되지 않은 코드는 프로세서에서 작성된대로 실행하는 유일한 방법입니다.

C로 코딩하려면 ASM 부트 로더를 코딩해야합니다. 그러면 ASM 부트 로더가 컴파일러에 의해 생성 된 기계 코드를 올바르게로드해야합니다.

각 컴파일러는 실행 전에 사전 처리가 필요할 수있는 다른 기계 코드를 생성한다는 점을 알아야합니다.

BIOS는 기계 코드를 사전 처리하도록 허용하지 않습니다. PC 부팅은 메모리 위치로의 점프 일 뿐이므로이 위치에있는 머신 코드가 직접 실행됩니다. http://www.brokenthorn.com/Resources/OSDevIndex.html

자신이 스스로 자신의 부트 로더를 만들기 위해 시작하는 좋은 자습서가 있습니다

+1

나는 C 함수의 최초의 호출로 이어지는, 모든 일 부트 로더, 진입 점을 호출 할 것입니다 C로 작성 될 수 있습니다 (이 시작 코드의 실제 어셈블러는 인라인 어셈블러를 사용하는 것보다 낫습니다). –

+0

답장을 보내 주셔서 감사합니다. 하지만 나는 내가 그것을 부팅 할 수 있도록 어떻게 C 코드에서. bin 파일을 만들 수 있는지 알고 싶다. 이 사이트 http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html에서 컴파일 지침을 보았습니다. 그러나 그것은 ld 명령 즉 linker.ld 파일에 오류를줍니다. 찾을 수 없습니다. 도와주세요 –

+2

@Dnyanesh : 부트 로더를 동적 라이브러리에 링크해서는 안됩니다. 심지어 stdc에 연결되지 않았습니다. – jweyrich

1

GCC를 사용하고 있으므로 다른 "대상 환경"에 대한 정보 페이지를 읽어야합니다. 대부분 - 플래그를 사용하고 싶을 것입니다. 또한 -fno-stack-protector 플래그를 사용하여 컴파일러의 추악한 마술을 피하십시오.

그런 다음 memset 등이 없다는 링커 오류가 표시됩니다. 따라서 자신 만의 버전을 구현하고 링크해야합니다.

1

몇 년 전에 시도했는데 옵션이 변경되었을 수 있습니다. 당신은 x86에서 부트 로더를 실행하려면 :

당신은 -nostdlib

+0

부트 로더와 CSU를 제외하고 관련 FreeBSD 코드를 살펴보십시오. ELF 시작 코드는 하위 수준 C-asm 믹스를 수행하는 좋은 예를 제공합니다. –

9

것은 나를 여기에 많은 것을 가정하자 (연결하지 마십시오) -ffreestandinggcc를 실행 한 다음 플래그 -staticld을 사용하여 연결해야 시스템에서는 * nix 상자에 gcc toolchain을 설정해야합니다.

부트 로더를 작성할 때 고려해야 할 몇 가지 사항이 있습니다

  1. 도 덜 MBR 예정 파티션 테이블에 VBR에 대한 510 바이트 제한,
  2. (시스템은 하나를 필요로하는 경우) 리얼 모드 - 16 개 비트 레지스터 및 SEG :
  3. 부트 로더를 해결 오프는 물리적 주소 7C00H에 실행되도록 연결되어 있어야 평면 바이너리를해야합니다
  4. 없는 외부 '라이브러리'참조 (대만족!)

이제 gcc에서 이러한 바이너리를 출력하려면 몇 가지 트릭을 재생해야합니다.

  1. gcc는 기본적으로 32 비트 코드를 나눕니다. 리얼 모드로 실행되는 gcc 출력 코드를 얻으려면 __asm__(".code16gcc\n")을 각 C 파일의 맨 위에 추가하십시오.
  2. gcc는 ELF에서 컴파일 된 객체를 출력합니다. 우리는 7c00h에 정적으로 연결된 빈이 필요합니다. 이미 ASM과 부트 로더를 구축 한 이후 부트 로더

    $ gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -o bootloader.o bootloader.c 
    $ ld -static -Tlinker.ld -nostdlib --nmagic -o bootloader.elf bootloader.o 
    $ objcopy -O binary bootloader.elf bootloader.bin 
    
  3. ENTRY(main); 
    SECTIONS 
    {  
        . = 0x7C00;  
        .text : AT(0x7C00) 
        { 
         _text = .; 
         *(.text); 
         _text_end = .; 
        } 
        .data : 
        { 
         _data = .; 
         *(.bss); 
         *(.bss*); 
         *(.data); 
         *(.rodata*); 
         *(COMMON) 
         _data_end = .; 
        }  
        .sig : AT(0x7DFE)  
        {   
         SHORT(0xaa55); 
        }  
        /DISCARD/ : 
        { 
         *(.note*); 
         *(.iplt*); 
         *(.igot*); 
         *(.rel*); 
         *(.comment); 
         /* add any unwanted sections spewed out by your version of gcc and flags here */  
        } 
    } 
    
  4. bootloader.c에서 부트 로더 코드를 작성

    다음과 같은 내용으로 파일 linker.ld을 만들고 구축 같아요 나머지는 명백하다 당신.

- 내 블로그에서 가져온 : 어셈블러 네,하지만 부트 로더의 대부분은 http://dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html

+0

좋은 답변입니다. –

관련 문제