+LEXT(_pstart)
+ mov %ds, %bx
+ mov %bx, %es
+ mov %eax, %ebp // Move kernbootstruct to ebp
+ POSTCODE(_PSTART_ENTRY)
+ movl KADDR(%ebp), %ebx // Load boot image phys addr
+ movl %ebx, %edx // Set edx with boot load phys addr
+ addl KSIZE(%ebp), %edx // Add boot image size
+ addl $(NBPG-1), %edx // Round to a page size
+ andl $(-NBPG), %edx // Set edx to first free page
+ movl %edx, %esp // Set temporay stack
+ addl $(NBPG), %esp // add page size
+ call Ls1
+Ls1: popl %esi // Get return address
+ cmpl $(PA(Ls1)), %esi // Compare with static physicall addr
+ je EXT(pstart) // Branch if equal
+ subl $(PA(Ls1)), %esi // Extract relocation offset
+ movl %esi, %esp // Store relocation offset in esp
+ leal (PA(Lreloc_start))(%esp),%esi
+ // Set esi to reloc_start boot phys addr
+ movl %edx, %edi // Set edi to first free page
+ movl $(Lreloc_end-Lreloc_start), %ecx
+ // Set ecx to copy code size
+ cld // count up
+ rep
+ movsb // copy reloc copy code
+ wbinvd // Write back and Invalidate cache
+ movl %ebx, %esi // Set esi to kernbootstruct kaddr
+ movl KADDR(%ebp), %edi // Load boot image phys addr
+ subl %esp, %edi // Adjust to static phys addr
+ movl KSIZE(%ebp), %ecx // Set ecx to kernbootstruct ksize
+ addl $(NBPG-1), %ecx // Add NBPG-1 to ecx
+ andl $(-NBPG), %ecx // Truncate ecx to a page aligned addr
+ sarl $2, %ecx // Divide ecx by 4
+ movl %esp, (PA(EXT(KernelRelocOffset)))(%esp)
+ // Store relocation offset
+ movl %edi, KADDR(%ebp) // Relocate kaddr in kernbootstruct
+ subl %esp, MEMORYMAP(%ebp) // And relocate MemoryMap
+ subl %esp, DEVICETREEP(%ebp) // And relocate deviceTreeP
+ subl %esp, %ebp // Set ebp with relocated phys addr
+ jmp *%edx // Branch to relocated copy code
+Lreloc_start:
+ POSTCODE(_PSTART_RELOC)
+ rep
+ movsl // Copy boot image at BASE_KERNEL_PADDR
+ wbinvd // Write back and Invalidate cache
+ movl $(PA(EXT(pstart))), %edx // Set branch target
+ jmp *%edx // Far jmp to pstart phys addr
+Lreloc_end:
+ /* NOTREACHED */
+ hlt
+
+ .text
+ .globl __start
+ .set __start, PA(EXT(_pstart))
+
+/*
+ * BSP CPU continues here after possible relocation.
+ * ebp points to kernbootstruct
+ */
+ .align ALIGN
+ .globl EXT(pstart)