2012-03-07 4 views
3

과 관련하여 제가 질문을 통해 온 gas, 당신은 어떻게 알 수 있습니까 사용하여 간단한 부트 로더를 구축하기 위해 GNU의 바이너리 유틸리티를 사용하는 방법을 이해하는 링커는 .org를 사용하여 파일 크기를 512 바이트로 유지하면서 위치 카운터를 향상시키는 파일에 데이터를 저장할 위치를 지정합니다. 나는 이것을 할 길을 찾을 수없는 것 같습니다.: 내 노력에 LD

이 작업을 수행하려고 조립 프로그램입니다 :

# Author: Matthew Hoggan 
# Date Created: Tuesday, Mar 6, 2012 

.code16      # Tell assembler to work in 16 bit mode 
.section .data 
msg:       # Message to be printed to the screen 
    .asciz "hello, world" 

.section .text 
.globl _start    # Help linker find start of program 
_start: 
    xor %ax, %ax    # Zero out ax register (ah used to specify bios function to Video Services) 
    movw %ax, %ds    # Since ax is 0x00 0x00 use it to set data segment to 0 
    mov $msg, %si    # Use source index as pointer to string 

loop: 
    movb %ds:(%si), %al  # Pass data to BIOS function in low nibble of ax 
    inc %si     # Advance the pointer 
    or %al, %al    # If byte stored in al is equal to zero then... 
    jz _hang     # Zero signifies end of string 
    call print_char   # Print current char in al 
    jmp loop     # Repeat 

# 
# Function that uses bios function calls 
# to print char to screen 
# 
print_char: 
    movb $0x0e, %ah    # Function to print a character to the screen 
    movb $0x07, %bl    # color/style to use for the character 
    int $0x10     # Video Service Request to Bios 
    ret 

# 
# Function used as infinite loop 
# 
_hang: 
    jmp _hang 

.org 510 
.byte 0x55, 0xAA 

.end 

UPDATE 나는 다음과 같은 오류 얻을 다음 명령을 사용 : 이런 종류의 일을 위해

[email protected]:~/Code/svn_scripts/assembly/bootloader/gas$ ld --oformat binary -o string string.o 
string.o: In function `_start': 
(.text+0x5): relocation truncated to fit: R_X86_64_16 against `.data' 
+0

이 오류를 생성하는 간단한 예와 의미 : http://stackoverflow.com/a/32639540/895245 작업 섹터가있는 저장소 + BIOS 예제 : https://github.com/cirosantilli/x86-bare- metal-examples –

답변

4

을 당신은 자신의 linker script을 써야합니다. -T 옵션을 사용하여 링커에 전달하면됩니다. 거의 동일한 문제에 대한

내 스크립트했다 : 당신은 어셈블러에 0x55 0xAA을 둘 필요가 이벤트 그렇지 않은 트릭으로

SECTIONS 
{ 
    . = 0x1000; 
    bootsec : 
    { 
     *(.text) 
     *(.data) 
     *(.rodata) 
     *(.bss) 
     endbootsec = .; 
     . = 0x1FE; 
     SHORT(0xAA55) 
    } 
    endbootsecw = endbootsec/2; 
    image = 0x1200; 
} 

! 처음에

0x1000

: 그 사용되지 않도록 실제로 모든 점프는 상대적 있지만

endbootsecw, endbootsecimage이 기호는 다른 곳에서 사용하는 ... 보호 모드로 점프 나중에 필요 코드에서.

+0

Binutils 2.24에서 링커 스크립트로 a.ld : 11 위치 카운터를 거꾸로 (0000000000001200에서 00000000000011까지) 이동할 수 없습니다. –

+1

@CiroSantilli 당신의 섹션이 넘쳐 흐르고있는 것 같습니다. 즉, 여러분의 코드는'0x1200'에서 끝나고 링커에서'0x11FE'로 포인터를 되돌려 놓으려는 시도가 허용되지 않습니다. 이것은 asm에 너무 많은 코드가 있거나 링커 트릭 **과 ** .org 같은 것을 동시에 수행하는 경우에 발생할 수 있습니다. – rodrigo

+0

"동시에 링커 트릭과 .org 일을하고 있습니다."DOH! –