1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use core::arch::naked_asm;
// use super::entry::kernel_entry;
use crate::{
arch::addrspace::{EFI_IMAGE_BASE, KERNEL_LOAD_ADDRESS},
efi_stub::{efi_pe_entry, pe::*},
};
/// LoongArch64 kernel header implementing functionality similar to
/// Linux arch/loongarch/kernel/head.S _head section
#[unsafe(naked)]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".head.text")]
pub unsafe extern "C" fn _head() {
naked_asm!(
// EFI header following Linux kernel format
".word {dos_signature}", // "MZ", MS-DOS header
".org 0x8",
".dword _kernel_entry", // Kernel entry point (physical address)
".dword _kernel_asize", // Kernel image effective size
".quad {phys_link_kaddr}", // PHYS_LINK_KADDR - Kernel image load offset
".org 0x38", // 0x20 ~ 0x37 reserved
".long {linux_pe_magic}",
".long 4f - _head", // Offset to the PE header
"4:", // pe_header
// PE header
".long {image_nt_signature}", // IMAGE_NT_SIGNATURE
// COFF header
".short {file_machine}", // IMAGE_FILE_MACHINE_LOONGARCH64
".short 2", // NumberOfSections
".long 0", // TimeDateStamp
".long 0", // PointerToSymbolTable
".long 0", // NumberOfSymbols
".short 2f - 1f", // SizeOfOptionalHeader
".short {flags}", // Characteristics (IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED)
// Optional header
"1:",
".short 0x020b", // IMAGE_NT_OPTIONAL_HDR64_MAGIC
".byte 0x02", // MajorLinkerVersion
".byte 0x14", // MinorLinkerVersion
".long _etext - _stext", // SizeOfCode
".long _kernel_rsize", // SizeOfInitializedData
".long _kernel_vsize - _kernel_rsize", // SizeOfUninitializedData
".long {efi_pe_entry} - _head", // AddressOfEntryPoint
".long _stext - _head", // BaseOfCode
// Extra header fields
".quad {efi_image_base}", // ImageBase
".long PAGE_SIZE", // SectionAlignment (PECOFF_SEGMENT_ALIGN)
".long PECOFF_FILE_ALIGN", // FileAlignment (PECOFF_FILE_ALIGN)
".short 0", // MajorOperatingSystemVersion
".short 0", // MinorOperatingSystemVersion
".short {major_image_version}", // MajorImageVersion
".short {minor_image_version}", // MinorImageVersion
".short 0", // MajorSubsystemVersion
".short 0", // MinorSubsystemVersion
".long 0", // Win32VersionValue
".long _end - _head", // SizeOfImage
".long _stext - _head", // SizeOfHeaders
".long 0", // CheckSum
".short {image_subsystem}", // IMAGE_SUBSYSTEM_EFI_APPLICATION
".short 0", // DllCharacteristics
".quad 0", // SizeOfStackReserve
".quad 0", // SizeOfStackCommit
".quad 0", // SizeOfHeapReserve
".quad 0", // SizeOfHeapCommit
".long 0", // LoaderFlags
".long (2f - .) / 8", // NumberOfRvaAndSizes
// Data directories
".quad 0", // ExportTable
".quad 0", // ImportTable
".quad 0", // ResourceTable
".quad 0", // ExceptionTable
".quad 0", // CertificationTable
".quad 0", // BaseRelocationTable
"2:",
// Section table
".ascii \".text\\0\\0\\0\"",
".long _etext - _stext", // VirtualSize
".long _stext - _head", // VirtualAddress
".long _etext - _stext", // SizeOfRawData
".long _stext - _head", // PointerToRawData
".long 0", // PointerToRelocations
".long 0", // PointerToLineNumbers
".short 0", // NumberOfRelocations
".short 0", // NumberOfLineNumbers
".long 0x60000020", // Characteristics (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE)
// .data section
".ascii \".data\\0\\0\\0\"",
".long _kernel_vsize", // VirtualSize
".long _etext - _head", // VirtualAddress
".long _kernel_rsize", // SizeOfRawData
".long _etext - _head", // PointerToRawData
".long 0", // PointerToRelocations
".long 0", // PointerToLineNumbers
".short 0", // NumberOfRelocations
".short 0", // NumberOfLineNumbers
".long 0xc0000040", // Characteristics (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)
dos_signature = const IMAGE_DOS_SIGNATURE,
linux_pe_magic = const LINUX_PE_MAGIC,
phys_link_kaddr = const KERNEL_LOAD_ADDRESS,
efi_image_base = const EFI_IMAGE_BASE,
efi_pe_entry = sym efi_pe_entry,
image_nt_signature = const IMAGE_NT_SIGNATURE,
file_machine = const IMAGE_FILE_MACHINE_LOONGARCH64,
flags = const IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED,
major_image_version = const LINUX_EFISTUB_MAJOR_VERSION,
minor_image_version = const LINUX_EFISTUB_MINOR_VERSION,
image_subsystem = const IMAGE_SUBSYSTEM_EFI_APPLICATION,
)
}