Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system
-
In eboot.c using vi I don’t see a function called efi_main
/* -----------------------------------------------------------------------
*- Copyright 2011 Intel Corporation; author Matt Fleming
- This file is part of the Linux kernel, and is made available under
- the terms of the GNU General Public License version 2.
- ----------------------------------------------------------------------- */
#include <linux/efi.h>
#include <linux/pci.h>#include <asm/efi.h>
#include <asm/e820/types.h>
#include <asm/setup.h>
#include <asm/desc.h>#include “…/string.h”
#include “eboot.h”static efi_system_table_t *sys_table;
static struct efi_config *efi_early;
__pure const struct efi_config *__efi_early(void)
{
return efi_early;
}#define BOOT_SERVICES(bits)
static void setup_boot_services##bits(struct efi_config *c)
{
efi_system_table_##bits##_t *table;
table = (typeof(table))sys_table;
c->runtime_services = table->runtime;
c->boot_services = table->boottime; \ -
Okay. I believe I misunderstood when to edit the files, you mean after a successful build. In the build I hit one more error: Missing elfutils-libelf-devel so I installed that and started again and it’s building for a while now.
-
@mjaskowski Sorry, didn’t get to answer until now. Great to see you are making good progress on this!!
Not sure exactly why but turns out I missed to to
EARLY_PRINTK_EFI
in the kernel I provided earlier and it still seemed to work for you. So not sure if this is needed or not. In case you don’t get the test output as expected you might want to add theEARLY_PRINTK_EFI
as well and try again.In eboot.c using vi I don’t see a function called efi_main
Do you know how to search in VI? Make sure you are not in edit mode (hit ESC a couple of times) and type
/efi_main
then ENTER. It should jump to the first occurrence. If you want to step to the next hitn
or shift+n
to jump back. If this doesn’t work, just use page down to go to line 740. Should look like this: https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/eboot.c#L740Okay. I believe I misunderstood when to edit the files, you mean after a successful build.
Nope, before building. But it’s no big deal! One important thing I should mention is that
build.sh
is preparing a lot of things for you to make the build work. But as soon as you have called it once you can also go the manual route. This is quite often better.So to change the config in GUI mode do:
cd fos/kernelsourcex64/ make menuconfig
And to build the kernel just do:
cd fos/kernelsourcex64/ make bzImage
You can repeat the
make bzImage
over and over every time you make a change to theeboot.c
code to get a newbzImage
binary that has the code changes in it. -
@mjaskowski And when the kernel build fine you just need to copy it over to your FOG server in
/var/www/html/fog/service/ipxe/
. And I’d still name itbzImage-earlyprintk
so you don’t overwrite the original kernel binary. -
the last build failed with MK_FW firmware/bnx2x/bnx2x-e1h-7.13.1.0.fw.gen.S
make[1]: *** No rule to make targetlinux-firmware/bnx2x/bnx2x-e1h-7.13.1.0.fw'
, needed byfirmware/bnx2x/bnx2x-e1h-7.13.1.0.fw.gen.o'
. Stop.
make: *** [firmware] Error 2
Since I’m starting it over I’ll edit those files prebuild but what about this error, how do I prevent a repeat? -
@mjaskowski said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
make[1]: *** No rule to make target linux-firmware/bnx2x/bnx2x-e1h-7.13.1.0.fw’, needed by firmware/bnx2x/bnx2x-e1h-7.13.1.0.fw.gen.o’. Stop.
I’ve done my share of linux kernel building (watch that statement come back and bit me in the backside). What this is saying is that you don’'t have the linux kernel firmware downloaded and saved into the root of the directory where the .config file is.
git this: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
-
@mjaskowski That’s kind of strange as the firmware should be downloaded by the
build.sh
script for you - see here. Please runls -al fos/kernelsourcex64/linux-firmware
and post output here. If you get no such file or directory run as suggested by George:cd fos/kernelsourcex64/ git clone git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
-
running
ls -al fos/kernelsourcex64/linux-firmware
resulted inls: cannot access fos/kernelsourcex64/linux-firmware: No such file or directory
there is however afos/kernelsourcex64/firmware
directory -
@mjaskowski said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
there is however a
fos/kernelsourcex64/firmware
directoryThis is not the same as
fos/kernelsourcex64/linux-firmware
. You need both! -
@mjaskowski Did you get to compile the kernel yet?
-
I got pulled off this project and just back to it now. So I just updated to Kernel to bzImage Version: 4.19.48 and when I pxe boot to it I only get as far as rEFInd - Booting OS in a blue bar at the top of the screen and below prints:
Starting bootmgfw.efi
Using load options ’ ’and that’s all folks. What next?
-
@mjaskowski Great to see you back. When you see rEFInd that means your client chainloaded to boot from disk. Make sure it is registered and a task is scheduled for it.
-
I’m looking at https://wiki.fogproject.org/wiki/index.php/Building_a_Custom_Kernel and it’s not clear to me where I’m to perform step 1:
Build Process- Install [WHERE?] the required packages to build the kernel with:
RHEL/Fedora/CentOS/.rpm other: (need confirmation that this is all the packages required?!?, may also need qt-devel and a few others)
yum groupinstall “Development Tools” - Ubuntu/Debian/.deb other:
sudo apt-get install qt3-dev-tools libqt3-mt-dev
- Install [WHERE?] the required packages to build the kernel with:
-
@mjaskowski From the things you wrote weeks ago I though you where way beyond that point already. The development tools are needed to compile the kernel from source code. You install those on a machine you want to use for playing with the kernel build. You can use your FOG server for this but any other Linux machine will do just as well. Doesn’t really matter.
-
@Sebastian-Roth said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
@mjaskowski Great to see you back. When you see rEFInd that means your client chainloaded to boot from disk. Make sure it is registered and a task is scheduled for it.
That’s the thing, I never get to the FOG menu options including the Quick Registration and all. I’ve previously tried to manually register and perform a task to no avail but I’ll try that again.
-
@mjaskowski said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
@Sebastian-Roth said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
@mjaskowski Great to see you back. When you see rEFInd that means your client chainloaded to boot from disk. Make sure it is registered and a task is scheduled for it.
That’s the thing, I never get to the FOG menu options including the Quick Registration and all. I’ve previously tried to manually register and perform a task to no avail but I’ll try that again.
So I get the following:
Succeed to download NBP file.
iPXE initialising devices…okiPXE 1.0.0+ (9907f) – Open Source Network Boot Firmware – http://ipxe.org
Features: DNS FTP HTTP HTTPS iSCSI NFS TFTP SRP VLAN AoE EFI Menu
Configuring (net0 3c:18:a0:11:dc:62)… ok
Received DHCP answer on interface net0
tftp://xx.xx.x.xx/default.ipxe… ok
http://xx.xx.x.xx/fog/service/ipxe/boot.php… ok
bzImage-earlyprintk… ok
init.xz… ok
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text output
Text outputto the end of the visible screen.
-
@mjaskowski Ok, now we are on the right track!! Well done. Can you post the modified part of your eboot.c file here so we know where exactly you added the “Text output” prints.
-
@Sebastian-Roth said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
@mjaskowski Ok, now we are on the right track!! Well done. Can you post the modified part of your eboot.c file here so we know where exactly you added the “Text output” prints.
struct desc_ptr *gdt = NULL; efi_printk(sys_table, "Text output\n"); efi_loaded_image_t *image; efi_printk(sys_table, "Text output\n"); struct setup_header *hdr = &boot_params->hdr; efi_printk(sys_table, "Text output\n"); efi_status_t status; efi_printk(sys_table, "Text output\n"); struct desc_struct *desc; efi_printk(sys_table, "Text output\n"); void *handle; efi_system_table_t *_table; unsigned long cmdline_paddr; efi_printk(sys_table, "Text output\n"); efi_early = c; _table = (efi_system_table_t *)(unsigned long)efi_early->table; handle = (void *)(unsigned long)efi_early->image_handle; efi_printk(sys_table, "Text output\n"); sys_table = _table; /* Check if we were booted by the EFI firmware */ if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) goto fail; efi_printk(sys_table, "Text output\n"); if (efi_is_64bit()) setup_boot_services64(efi_early); else setup_boot_services32(efi_early); efi_printk(sys_table, "Text output\n"); /* * make_boot_params() may have been called before efi_main(), in which * case this is the second time we parse the cmdline. This is ok, * parsing the cmdline multiple times does not have side-effects. */ cmdline_paddr = ((u64)hdr->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); efi_parse_options((char *)cmdline_paddr); efi_printk(sys_table, "Text output\n"); /* * If the boot loader gave us a value for secure_boot then we use that, * otherwise we ask the BIOS. */ if (boot_params->secure_boot == efi_secureboot_mode_unset) boot_params->secure_boot = efi_get_secureboot(sys_table); efi_printk(sys_table, "Text output\n"); /* Ask the firmware to clear memory on unclean shutdown */ efi_enable_reset_attack_mitigation(sys_table); efi_retrieve_tpm2_eventlog(sys_table); efi_printk(sys_table, "Text output\n"); setup_graphics(boot_params); efi_printk(sys_table, "Text output\n"); setup_efi_pci(boot_params); efi_printk(sys_table, "Text output\n"); setup_quirks(boot_params); efi_printk(sys_table, "Text output\n"); efi_printk(sys_table, "Text output\n"); if (status != EFI_SUCCESS) { efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); goto fail; } efi_printk(sys_table, "Text output\n");
-
@mjaskowski Hmmm, that’s interesting. In the output you posted I counted “Text output” 17 times. Now when I look at the code you posted it also has 17 lines of “Text output”. What that means is that it gets as far as the last “Text output”. That’s really good news because on most systems we debugged this we only got as far as
setup_efi_pci
…Ok, please add another
efi_printk
after theexit_boot
call and check - see code here: https://elixir.bootlin.com/linux/v4.19.48/source/arch/x86/boot/compressed/eboot.c#L841Best if you make it a different text, e.g. “After exit_boot” so we don’t have to count the outputs.
-
@Sebastian-Roth said in Lenovo 300e ipxe boots ok but ipxe.efi can't resolve the system:
@mjaskowski Hmmm, that’s interesting. In the output you posted I counted “Text output” 17 times. Now when I look at the code you posted it also has 17 lines of “Text output”. What that means is that it gets as far as the last “Text output”. That’s really good news because on most systems we debugged this we only got as far as
setup_efi_pci
…Ok, please add another
efi_printk
after theexit_boot
call and check - see code here: https://elixir.bootlin.com/linux/v4.19.48/source/arch/x86/boot/compressed/eboot.c#L841Best if you make it a different text, e.g. “After exit_boot” so we don’t have to count the outputs.
So not even the ‘Exit boot 1’ prints
efi_printk(sys_table, "Text output 17\n"); hdr->pref_address = hdr->code32_start; hdr->code32_start = bzimage_addr; } status = exit_boot(boot_params, handle); if (status != EFI_SUCCESS) { efi_printk(sys_table, "exit_boot() failed!\n"); goto fail; } efi_printk(sys_table, "Exit boot 1\n"); memset((char *)gdt->address, 0x0, gdt->size); desc = (struct desc_struct *)gdt->address; /* The first GDT is a dummy. */ desc++; if (IS_ENABLED(CONFIG_X86_64)) { /* __KERNEL32_CS */ desc->limit0 = 0xffff; desc->base0 = 0x0000; desc->base1 = 0x0000; desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ; desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; desc->limit1 = 0xf; desc->avl = 0; desc->l = 0; desc->d = SEG_OP_SIZE_32BIT; desc->g = SEG_GRANULARITY_4KB; desc->base2 = 0x00; desc++; } else { /* Second entry is unused on 32-bit */ desc++; } efi_printk(sys_table, "Exit boot 2\n");