Hello Bin, in arch/x86/include/asm/global_data.h
#ifndef __ASSEMBLY__ # if defined(CONFIG_EFI_APP) || CONFIG_IS_ENABLED(X86_64) /* TODO(s...@chromium.org): Consider using a fixed register for gd on x86_64 */ #define gd global_data_ptr #define DECLARE_GLOBAL_DATA_PTR extern struct global_data *global_data_ptr # else static inline __attribute__((no_instrument_function)) gd_t *get_fs_gd_ptr(void) { gd_t *gd_ptr; #if CONFIG_IS_ENABLED(X86_64) asm volatile("fs mov 0, %0\n" : "=r" (gd_ptr)); #else asm volatile("fs movl 0, %0\n" : "=r" (gd_ptr)); #endif return gd_ptr; } From this I take: * fs is only used in i386 but not on amd64 to store the global data pointer. * The function gd_ptr() does not exist on amd64. * On i386 register fs is not used to indicate a segment but an address. The UEFI spec requires: When a 32-bit UEFI OS is loaded, the system firmware hands off control to the OS in flat 32-bit mode. All descriptors are set to their 4GiB limits so that all of memory is accessible from all segments. It seems that this is not matched by the GDT initialization in arch_setup_gd(). Can't we have the same initialization as in setup_fsp_gdt() for the whole of U-Boot? If this is not possible, we should disable CONFIG_EFI_LOADER for the i386 architecture. Best regards Heinrich