во-первых компилятор даёт предупреждение, … , но ошибки не производит. Я спокойно линкую файл недо-драйвера с основным ядром, (конечный результат - .efi),
Дело в том, что у EFI-приложений нет динамической линковки, а неопределённый символ после копирования из .so в .efi просто ссылается в никуда. Если вывести неопределённые символы для bootx64.so, то inportb будет среди них:
objdump -t bootx64.so | grep UND
0000000000000000 *UND* 0000000000000000 inportb
В qemu результат вызова этой функции выглядит так:
Trace 0: 0x7fb15d338e80 [0000000000000000/000000007e6e22de/0x40c2b0]
----------------
IN:
0x7e6e2081: bf 60 00 00 00 movl $0x60, %edi
0x7e6e2086: b8 00 00 00 00 movl $0, %eax
0x7e6e208b: e8 90 57 00 00 callq 0x7e6e7820
Trace 0: 0x7fb15d3390c0 [0000000000000000/000000007e6e2081/0x40c2b0]
----------------
IN:
0x7e6e7820: af scasl (%rdi), %eax
0x7e6e7821: af scasl (%rdi), %eax
0x7e6e7822: af scasl (%rdi), %eax
0x7e6e7823: af scasl (%rdi), %eax
0x7e6e7824: af scasl (%rdi), %eax
0x7e6e7825: af scasl (%rdi), %eax
0x7e6e7826: af scasl (%rdi), %eax
0x7e6e7827: af scasl (%rdi), %eax
0x7e6e7828: af scasl (%rdi), %eax
0x7e6e7829: af scasl (%rdi), %eax
0x7e6e782a: af scasl (%rdi), %eax
0x7e6e782b: af scasl (%rdi), %eax
…
С другой стороны, если предоставить такую функцию:
unsigned char
inportb(unsigned short port)
{
unsigned char v;
asm volatile ("in {%1|%b0}, {%b0|%1}\n" : "=a"(v) : "d"(port));
return v;
}
то она прекрасно вызывается и возвращает значение.
Можно добавить опцию
-zdefs
в команду линковки чтобы получать ошибку линковки при наличии ссылок на неопределённые символы.
Чтобы посмотреть, какой именно код выполняется, я запускаю qemu с монитором в консоли (дополнительным ключом
-monitor stdio
). Я нажимаю ESC когда в QEMU запускается tianocore и выбираю Boot Manager -> EFI Internal Shell, а там пишу
fs0:efi\boot\bootx64.efi
, после этого в мониторной консоли включаю логгирование (командами
logfile log
,
log in_asm,exec
), после чего нажимаю enter в консоли EFI. После этого можно смотреть в файл log и искать в нём знакомые байты из objdump.