This code stub was extracted from linux kernel 3.18.3, arch/x86/boot/compressed/head_64.S
. There were added extra comments though.
All this code is executed in long mode (64 bits) with code segment selector: 0x10 and data segment selector: 0x18
xorl %eax, %eax /* Setting up all data segments selectors to zero */
movl %eax, %ds /* Including stack segment */
movl %eax, %es
movl %eax, %ss
movl %eax, %fs
movl %eax, %gs
leaq z_extract_offset(%rbp), %rbx
/* Set up the stack */
leaq boot_stack_end(%rbx), %rsp
/* Zero EFLAGS */
pushq $0 /* This instruction should fail since stack segment selector */
popfq /* is zero (pointing to null descriptor) /*
According to what I know this code should fail to execute because %ss = 0x0 which points to null descriptor in the gdt, when the stack instruction pushq is executed.
Nevertheless this seems to work, so I assume I'm missing some information. Why does this work?
Segmentation is mostly disabled in 64-bit mode, with only attributes of CS and the base of FS and GS being used.