>I have just checked it, the startup.elf and realmode.elf are fine. Only few changes are required for mainline kernel and one >commit has to be reverted from lld and a few patches have to be applied.> >The only step when I have used BFD is linking vmlinux. I have manually set LD variable in vmlinux_link() function. The vmlinux >produced by lld doesn't work yet. I will compare it to the one produced by GNU ld and try to figure out what is wrong (maybe >you can suggest some useful objdump flags?) > >Regards, >DmitryJust want to share latest results of investigation from my side. I traced kernel linked with LLD to find where it fails. LLD linked kernel starts execution and then I came up to protected_mode_jump? function, which intention to jump to startup_64: jmpl *%eax # Jump to the 32-bit entrypoint (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/pmjump.S#L76) (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/kernel/head_64.S#L48) It does not happen. Code executes right before jmpl and then fail on this call for me, so startup_64 never called. startup_64 is a part of vmlinux binary. So as you said vmlinux has troubles and after doing readelf -a on LLD linked and bfd linked ones, I found that LLD outputs vmlinux as executable and bfd output is DSO. Had no chance to investigate why that happens, but pretty sure that is the not fine. Invocation line for us does not contain -shared: -m elf_x86_64 --script home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/vmlinux.lds home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/head_64.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/misc.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/string.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cmdline.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/error.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/piggy.o home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cpuflags.o -o vmlinux George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170208/7ae05798/attachment.html>
On Wed, Feb 8, 2017 at 7:59 AM, George Rimar <grimar at accesssoftek.com> wrote:> >I have just checked it, the startup.elf and realmode.elf are fine. Only > few changes are required for mainline kernel and one >commit has to be > reverted from lld and a few patches have to be applied. > > > >The only step when I have used BFD is linking vmlinux. I have manually > set LD variable in vmlinux_link() function. The vmlinux >produced by lld > doesn't work yet. I will compare it to the one produced by GNU ld and try > to figure out what is wrong (maybe >you can suggest some useful objdump > flags?) > > > >Regards, > >Dmitry > > Just want to share latest results of investigation from my side. > I traced kernel linked with LLD to find where it fails. > > LLD linked kernel starts execution and then I came up to > protected_mode_jump​ function, which intention to jump to startup_64: > jmpl *%eax # Jump to the 32-bit entrypoint > (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b > 5075173a25/arch/x86/boot/pmjump.S#L76) > (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b > 5075173a25/arch/x86/kernel/head_64.S#L48) > > It does not happen. Code executes right before jmpl and then fail on this > call for me, so startup_64 never called. >That address seems to come from here: https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/pm.c#L124 ``` protected_mode_jump(boot_params.hdr.code32_start, (u32)&boot_params + (ds() << 4)); ``` That boot_params.hdr.code32_start field is probably either invalid (bad reloc or something else causing the bootloader to calculate the wrong address) or valid but the thing it thinks it is pointing to wasn't loaded (missing PT_LOAD etc.). Btw, how did you narrow it down to that specific instruction? That's pretty handy.> > startup_64 is a part of vmlinux binary. So as you said vmlinux has > troubles and after doing readelf -a on LLD linked and bfd linked ones, I > found that LLD outputs vmlinux as executable and bfd output is DSO. Had > no chance to investigate why that happens, but pretty sure that is the not > fine. >> Invocation line for us does not contain -shared: > > -m elf_x86_64 > --script home/umb/linux_kernel/linux/linux/arch/x86/boot/ > compressed/vmlinux.lds > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/head_64.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/misc.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/string.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cmdline.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/error.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/piggy.o > home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cpuflags.o > -o vmlinux >I think you can also get DSO with -pie I think, but I don't see that either. This is quite mysterious. I also did a quick look at the linker script and didn't see anything at first glance that would cause DSO output (can linker scripts even control EType?). The bootloader might not even look at the EType though. -- Sean Silva> > George. > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170208/762750e6/attachment.html>
>That address seems to come from >here: https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/pm.c#L124 > >``` >protected_mode_jump(boot_params.hdr.code32_start, > (u32)&boot_params + (ds() << 4)); >``` > >That boot_params.hdr.code32_start field is probably either invalid (bad reloc or something else causing the bootloader to >calculate the wrong address) or valid but the thing it thinks it is pointing to wasn't loaded (missing PT_LOAD etc.).boot_params.hdr.code32_start field is valid :) It is 0x100000, like expected (btw thanks for those links on info how kernel boots, they were pretty useful). I checked it is valid using trace: void go_to_protected_mode(void) { if (boot_params.hdr.code32_start == 0x100000) puts("go_to_protected_mode 1\n"); else puts("go_to_protected_mode 2\n"); while (1) {}; I had to use infinite loop here, because QEMU does not crash for me, but do domething what looks like reboot and clears all my traces output. Infinite loop helps to see traces text, if placed before dead point.> >Btw, how did you narrow it down to that specific instruction? That's pretty handy.I used very simple approach, did not know how to do that properly :), so inserted infinite loops in asm code: foo: jmp foo And watched for behavior of QEMU. If it just hanged that was fine, I knew I am inside my loop, if QEMU rebooted, I knew it crashed at point I was looking for. So tracing bfd linked kernel and using documentation I found that startup_64 ?is next destination POI, and found that this instruction is the last before QEMU reboots for me.>I think you can also get DSO with -pie I think, but I don't see that either. This is quite mysterious. I also did a quick look at the >linker script and didn't see anything at first glance that would cause DSO output (can linker scripts even control EType?). The >bootloader might not even look at the EType though. > >-- Sean SilvaI think best way would be to look at what is invocation for BFD here. I am pretty sure -shared/-pie flag is just lost because of some configuration issue, probably it checks that we are running bfd may be. Just a guess. George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170209/e379b810/attachment.html>
>I think you can also get DSO with -pie I think, but I don't see that either. This is quite mysterious. I also did a quick look at the >linker script and didn't see anything at first glance that would cause DSO output (can linker scripts even control EType?). The >bootloader might not even look at the EType though.> >-- Sean SilvaPlace is: https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/Makefile#L51 It checks if -z noreloc-overflow is available and adds -pie and other flags in that case. If I comment out this lines: #LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ # && echo "-z noreloc-overflow -pie --no-dynamic-linker")? Then as expected bfd linked vmlinux also becomes executable. And it is even still boots for me. George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170217/29834207/attachment.html>