Чудеса кросс-компиляции. Реально странные вещи.
alman
Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
На основе bootstrap30 сделал простейшее приложение, которое печатает приветствие и организует loopback на dbgu порту. То есть принятые байты отправляет обратно на терминал. Размер исполняемого модуля порадовал - 328 байт.
Код приложу к этом сообщению. Сборочный скрипт выглядит следующим образом:
Код
#!/bin/sh
# remove previous object files
rm *.o test test.bin at91_sd.bin
# compile simple runtime lib
arm-none-linux-gnueabi-as -g -Wall crt0_gnu.S -o crt0_gnu.o > /dev/null
# compile test module
arm-none-linux-gnueabi-gcc -fno-builtin -g -Os -Wall -nostdlib -nodefaultlibs -nostartfiles dbgu.c -o dbgu.o -DAT91SAM9G45
# link executable
arm-none-linux-gnueabi-ld -nostartfiles -T elf32-littlearm.lds --Ttext 0x73e00000 crt0_gnu.o dbgu.o -o test
# create binary file
arm-none-linux-gnueabi-objcopy --strip-all test -O binary test.bin
# build boot image
./mkimage -A arm -O u-boot -T standalone -C none -n "UART test" -a 0x73e00000 -e 0x73e00000 -d test.bin at91_sd.bin
# Show executable information
if [ -r test ]; then
# arm-none-linux-gnueabi-readelf -Dlh test | less
# arm-none-linux-gnueabi-objdump -h -x -S -g -s -l dbgu.o | less
arm-none-linux-gnueabi-objdump -h -x -S -g -s -l test | less
fi
Вот так выглядит функция main собственно тестового приложения:
Код int main()
{
char ch;
#define MASTER_CLOCK (132096000)
dbgu_init(BAUDRATE(MASTER_CLOCK, 115200));
dbgu_print("\n\rAlman greetings you!\r\n");
while(1)
{
ch = dbgu_getc();
while (!(read_dbgu(DBGU_CSR) & AT91C_US_TXRDY)) ;
write_dbgu(DBGU_THR, ch);
}
}
Самое удивительное, что loopback работает, но вот удивительные вещи происходят со строкой "\n\rAlman greetings you!\r\n". Вместо неё выводится "мусор". Посмотрев ассемблерный код, удивлению не было предела:
test: file format elf32-littlearm
test
architecture: arm, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x73e00000
Program Header:
LOAD off 0x00000060 vaddr 0x73e00000 paddr 0x73e00000 align 2**4
filesz 0x00000108 memsz 0x00000108 flags r-x
private flags = 4000002: [Version4 EABI] [has entry point]
Contents of section .text:
73e00000 28d09fe5 28109fe5 0229a0e3 002081e5 (...(....)... ..
73e00010 20409fe5 0fe0a0e1 14ff2fe1 0801e073 @......../....s
73e00020 0801e073 0801e073 0801e073 0801e073 ...s...s...s...s
73e00030 00a03000 44fdffff b800e073 0000a0e1 ..0.D......s....
73e00040 012ae0e3 0030e0e3 f33102e5 ad3083e2 .*...0...1...0..
73e00050 ff3102e5 0e3ca0e3 df0102e5 fb3102e5 .1...<.......1..
73e00060 db3e43e2 ff3102e5 1eff2fe1 0010a0e3 .>C..1..../.....
73e00070 01cae0e3 040000ea eb311ce5 020013e3 .........1......
73e00080 fcffff0a e3210ce5 011081e2 0020d1e7 .....!....... ..
73e00090 000052e3 f7ffff1a 1eff2fe1 012ae0e3 ..R......./..*..
73e000a0 eb3112e5 010013e3 fcffff0a e70112e5 .1..............
73e000b0 ff0000e2 1eff2fe1 10402de9 4800a0e3 ....../..@-.H...
73e000c0 deffffeb 1c009fe5 e7ffffeb 014ae0e3 .............J..
73e000d0 f1ffffeb eb3114e5 020013e3 fcffff0a .....1..........
73e000e0 e30104e5 f9ffffea 40810000 0a0d416c ........@.....Al
73e000f0 6d616e20 67726565 74696e67 7320796f man greetings yo
73e00100 75210d0a 00000000 u!......
Disassembly of section .text:
73e000b8 <main>:
main():
73e000b8: e92d4010 stmdb sp!, {r4, lr}
73e000bc: e3a00048 mov r0, #72 ; 0x48
73e000c0: ebffffde bl 73e00040 <dbgu_init>
73e000c4: e59f001c ldr r0, [pc, #28] ; 73e000e8 <main+0x30>
73e000c8: ebffffe7 bl 73e0006c <dbgu_print>
73e000cc: e3e04a01 mvn r4, #4096 ; 0x1000
73e000d0: ebfffff1 bl 73e0009c <dbgu_getc>
73e000d4: e51431eb ldr r3, [r4, #-491]
73e000d8: e3130002 tst r3, #2 ; 0x2
73e000dc: 0afffffc beq 73e000d4 <main+0x1c>
73e000e0: e50401e3 str r0, [r4, #-483]
73e000e4: eafffff9 b 73e000d0 <main+0x18>
73e000e8: 00008140 andeq r8, r0, r0, asr #2
73e000ec: 6c410d0a mcrrvs 13, 0, r0, r1, cr10
73e000f0: 206e616d rsbcs r6, lr, sp, ror #2
73e000f4: 65657267 strvsb r7, [r5, #-615]!
73e000f8: 676e6974 undefined
73e000fc: 6f792073 svcvs 0x00792073
73e00100: 0a0d2175 beq 741486dc <.text+0x3486dc>
73e00104: 00000000 andeq r0, r0, r0
Обратите внимание на адрес 73e000c4 - в регистр r0 загружается адрес ячейки 73e000e8, в которой (должен) хранится адрес выводимой строки, однако, при линковке исполняемого файла адрес не поменялся, а остался таким же, как и в объектом файле. Почему так?
Насколько я понимаю, для корректной работы тестовой программы, содержимое ячейки 73e000e8 должно быть 73e000eс
Тестовый проект в аттаче (если аттач пройдёт).
alman
Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Valentinus
Пункты: 2138
Регистрация: 23.01.2010
Пол: Мужчина
попробуй для строки объявить переменную const char *
и ее передать в функцию dbgu_print
sasamy
Пункты: 79218
Регистрация: 14.08.2009
Цитата
arm-none-linux-gnueabi-gcc -fno-builtin -g -Os -Wall -nostdlib -nodefaultlibs -nostartfiles dbgu.c -o dbgu.o -DAT91SAM9G45
Обратите внимание на адрес 73e000c4 - в регистр r0 загружается адрес ячейки 73e000e8, в которой (должен) хранится адрес выводимой строки, однако, при линковке исполняемого файла адрес не поменялся, а остался таким же, как и в объектом файле. Почему так?
Потому что вы забыли указать флаг -с для компелятора в результате еще запустился линковщик который прописал туда "левый" адрес а вам нужен чистый объектный файл, вот так должно работать:
# compile test module
arm-none-linux-gnueabi-gcc -с -g -Os -Wall dbgu.c -o dbgu.o -DAT91SAM9G45
# link executable
arm-unknown-linux-gnueabi-ld \
-T elf32-littlearm.lds \
--Ttext 0x73e00000 \
crt0_gnu.o dbgu.o -n -o test
Потом вот это все лишнее
crt0_gnu.S:
/* Init the stack */
_init_stack:
ldr sp, =0x0030A000
/* relocation is slow, disable the watchdog or it will trigger */
ldr r1, =0xFFFFFD44
mov r2, #0x00008000
str r2, [r1]
стек уже проинициализирован в бутстрапе
dbgu.c
#define MASTER_CLOCK (132096000)
dbgu_init(BAUDRATE(MASTER_CLOCK, 115200));
dbgu уже проинициализирован в бутсрапе
alman
Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Спасибо! Проблема решена.