This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld linking.
- From: Brian Beardall <brian at rapsure dot net>
- To: binutils at sources dot redhat dot com
- Date: Tue, 13 Nov 2007 23:15:58 -0700
- Subject: ld linking.
as -o lab8.o lab8.S
ld -Tbss 0x00000 -Ttext 0xE0000 --oformat binary -o lab8.bin lab8.o
lab8.o: In function `initialize':
(.text+0x183): relocation truncated to fit: R_X86_64_16 against `.text'
lab8.o: In function `initialize':
(.text+0x1fffc): relocation truncated to fit: R_X86_64_16 against
`_start'
These are the commands I am running on the code that is listed below.
The program that is compiled is being programmed into a flash memory
located at 0xE0000, but I don't seem to be able to get the linker to
generate the binary file. How might I go about to get the jump at the
bottom of the file to work, and the following line of code:
movw $isr0,%es:vector1
# Ramtest program
.arch i8086
.code16
# Set constants for the size of ram, rom, and the location of the red,
and green
# led.
.equ ram_size, 8192
.equ rom_size, 131072
.equ prog_size, 131072
.equ red_led_seg, 0x2000
.equ green_led_seg, 0x4000
#.equ io_set, 0x89
.equ io_set, 0x89 # 0b10001001
.equ ppiaddress, 0x2000
.equ ppicontrol, 0x0003
.equ ppiportA, 0x0000
.equ ppiportB, 0x0001
.equ ppiportC, 0x0002
.equ pitaddress, 0x4000
.equ pitcountzero, 0x0000
.equ pitcountone, 0x0001
.equ pitcounttwo, 0x0002
.equ pitwritemode, 0x0003
.equ pit_timer0_mode, 0x36 # 0b00110110 Mode 0, Interrupt on terminal
count
.equ pit_timer1_mode, 0x70 # 0b01110000 Mode 3, Square wave rate
generator.
.equ picaddress, 0x0000
.equ pica, 0x0001
.equ vector1,0x0020
.equ vector2,0x0024
.equ vector3,0x0028
.equ vector4,0x002C
.equ vector5,0x0030
.equ vector6,0x0034
.equ vector7,0x0038
.equ vector8,0x003C
#.equ jumplocation, startup
.equ enableir0, 0xFE # Disables all interrupts but IR0
.equ icw1, 0x17 # Interrupt initialization control word one.
.equ icw2, 0x08 # Sets the interrupt number.
.equ icw4, 0x01 # Sets the pic into 8086 mode, specific end interrupt.
.equ ocw2_priority, 0xC0 # 0b11000000 # Set priority zero on ir0.
.equ ocw2_clear_ir0, 0x60 # 0b01100000 # Clear any pending interrupts
on ir0
# bss section, and align the section to the beginning of ram.
# Then allocate 1024 bytes for the interrupt vector.
.section .bss
.align 0,,0
.lcomm intvec0, 1024
.lcomm button0, 2
.lcomm output, 2
.lcomm value, 2
# Set the jump offset for the processor to jump into the program.
.equ code_seg, 0xE000
# Set the .text segment
.section .text
.align 0,,0x100000 - prog_size
.equ start_location, _start - .
# Blink The Green LED, and then the Red LED for knowing that the
processor has
# loaded the program correctly.
.global _start
_start:
cli
movw $3, %dx
load_test:
movw $green_led_seg,%bx
movw $0xFFFF,%cx
movw %bx,%ds
led_on:
movb 0,%al
loop led_on
movw $0xFFFF,%cx
movw $red_led_seg,%bx
movw %bx,%ds
led_off:
movb 0,%al
loop led_off
dec %dx
jnz load_test
sti
# The main loop for reading the inputs, and controlling the output.
xor %ax,%ax
movw %ax,%ds
movw %ax,%ds
movw %ax,%ss
call initialize
push %bp
movw %sp,%bp
/* variable address space is allocated. -2(bp) is value for the both
port A, and B
-4(bp) stores the value from port C. -6(bp) stores */
sub $6,%sp
movw $0,-6(%bp)
movw $0,-4(%bp)
# Button latch catching method.
movw $0xFFFF, -2(%bp)
movw $0xFFFF, output
movw $0xFFFF,%ax
movw $(pitaddress+pitcountone),%dx
outb %al,%dx
movb %ah,%al
outb %al,%dx
movw $0x0000,value
main_loop:
xor %ax,%ax
# cli
movw value,%ax
cmp $10,%ax
jnz continue_count
xor %ax,%ax
movw %ax, value
continue_count:
/* movw %ax,%cx
cmp $0,%cx
jz special_case1
cmp $1,%cx
jz special_case2
sub $1,%cx
movw $2,%ax
movb $2,%dl
led_position:
mul %dl
loop led_position
jmp show_bar
special_case1:
movw $0x0200,%ax
jmp show_bar
special_case2:*/
# movw $0x0001,%dx
# sti
show_bar:
push %ax
movw $output,%ax
push %ax
call bar_display
add $4,%sp
movw value,%ax
push %ax
movw $output,%ax
push %ax
call seven_seg
add $4,%sp
movw $output,%ax
push %ax
call portA_portB
add $2,%sp
jmp main_loop
# bar_display destroys %ax, %bx, %cx, and %dx.
# This also pushes the %bp, and gets two variables from the stack.
# The first variable is a pointer, and the second is a constant
# 16 bit number.
bar_display:
push %bp
movw %sp,%bp
movw 4(%bp),%bx
movw 6(%bp),%ax
# now set the mask for the bits.
movb $4,%cl
sal %cl,%ax
and $0x3FF0,%ax
push %bx
sub $2,%sp
movw $0,-4(%bp)
movb $5,%ch
movw $0x2000,%bx
movb $9,%cl
reorder_one:
movw %ax,%dx
sal %cl,%dx
and %bx,%dx
or %dx,-4(%bp)
sub $2,%cl
sar $1,%bx
sub $1,%ch
jnz reorder_one
movb $5,%ch
movw $0x0010,%bx
movb $9,%cl
reorder_two:
movw %ax,%dx
sar %cl,%dx
and %bx,%dx
or %dx,-4(%bp)
sub $2,%cl
sal $1,%bx
sub $1,%ch
jnz reorder_two
movw -4(%bp),%ax
not %ax
add $2,%sp
pop %bx
xchg %ax,%es:(%bx)
and $0xC00F,%ax
or %ax,%es:(%bx)
# movw %ax,(%bx)
pop %bp
ret
# portA_portB destroys %ax, %bx, and %dx
# Writes the contents of the parameter passed into the function to port
A, and B
# on the ppi.
portA_portB:
push %bp
movw %sp,%bp
movw 4(%bp),%bx
movw %es:(%bx),%ax
movw $(ppiaddress+ppiportA),%dx
outw %ax,%dx
pop %bp
ret
seven_seg:
push %bp
movw %sp,%bp
movw 4(%bp),%bx
movw 6(%bp),%ax
and $0x000F,%ax
xchg %ax,%es:(%bx)
and $0xFFF0,%ax
or %ax,%es:(%bx)
pop %bp
ret
/*
timer_zero:
timer_one:
*/
isr0:
.equ isr0_location, . - _start
push %ax
push %bx
push %cx
push %dx
xor %ax,%ax
movw %ax,%bx
movw %ax,%cx
movw %ax,%dx
movw $(ppiaddress+ppiportC),%dx
inb %dx,%al
not %ax
and $0x0010,%ax
test $0x0010,%ax
xchg button0,%ax
jz endisr0
xor button0,%ax
test $0x0010,%ax
jz endisr0
# movw %ax,button0
movw value,%ax
add $1,%ax
movw %ax,value
# jmp endisr0
# button_reset:
# movw $0,button0
# movw %ax,-4(%bp)
# movw %ax,button0
endisr0:
movw $0xFFFF,%ax
movw $(pitaddress+pitcountone),%dx
outb %al,%dx
movb %ah,%al
outb %al,%dx
pop %dx
pop %cx
pop %bx
pop %ax
movw $(picaddress), %dx
movb $0b01100000,%al
outb %al,%dx
iret
initialize:
xor %bx,%bx
movw %bx,%ds
movw $(ppicontrol + ppiaddress), %dx
movb $io_set,%al
outb %al,%dx
movw $(ppiaddress + ppiportA), %dx
# first initial set for port A,B on the ppi.
movw $0xFFFF,%ax
outw %ax,%dx
movw $(pitaddress + pitwritemode),%dx
movb $pit_timer0_mode,%al # 0b00110110,%al
outb %al, %dx
movb $pit_timer1_mode,%al # 0b01110000,%al
outb %al, %dx
# Setup the interrupt controller now that all of the tests are complete.
cli
xor %ax,%ax
movw %ax,%es
movw $code_seg,%es:vector1+2
movw $isr0,%es:vector1
# movw $isr0,%ax
movw $picaddress,%dx
# ICW1
movb $icw1,%al
outb %al,%dx
movw $(picaddress + pica), %dx
# ICW2
movb $icw2, %al
outb %al,%dx
# ICW4
movb $icw4,%al
outb %al,%dx
movb $enableir0,%al
outb %al,%dx
movw $picaddress,%dx
movb $ocw2_priority,%al
outb %al,%dx
movb $ocw2_clear_ir0,%al
outb %al,%dx
sti
ret
# Fill the program with FF so that the file matches the size of the
flash.
#.fill prog_size - 0x10 - (. - startup_test),1,0xFF
#.balign 131056,0xFF
.org 0x1FFF0,0xFF
# Entry point of the program where the microprocessor starts executing
code.
# last command jumps to the beginning of the flash.
xor %ax,%ax
movw %ax,%ds
movw %ax,%ss
movw %ax,%es
movw $ram_size,%sp
jmp $code_seg, $_start
#ljmp _start