Skip to content

Commit 0b76300

Browse files
committed
Add initial LoongArch guest kernel support
Signed-off-by: Zewei Yang <yangzewei@loongson.cn>
1 parent 430e31b commit 0b76300

4 files changed

Lines changed: 3665 additions & 6 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Cross-build loongarch64 kernel
2+
on: [pull_request, create]
3+
4+
jobs:
5+
build:
6+
if: github.event_name == 'pull_request'
7+
name: Cross-build loongarch64 kernel
8+
runs-on: ubuntu-24.04
9+
steps:
10+
- name: Code checkout
11+
uses: actions/checkout@v2
12+
13+
- name: Install dependencies
14+
run: sudo apt-get update && sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev gcc-loongarch64-linux-gnu
15+
16+
- name: Build loongarch64 kernel
17+
run: make ARCH=loongarch CROSS_COMPILE=loongarch64-linux-gnu-

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ else ifeq ($(ARCH),riscv)
3535
GUESTARCH := riscv64
3636
CC := $(CROSS_COMPILE)gcc
3737
STRIP := $(CROSS_COMPILE)strip
38+
else ifeq ($(ARCH),loongarch)
39+
GUESTARCH := loongarch64
40+
CC := $(CROSS_COMPILE)gcc
41+
STRIP := $(CROSS_COMPILE)strip
3842
else
3943
GUESTARCH := $(ARCH)
4044
CC := $(CROSS_COMPILE)gcc
@@ -44,10 +48,13 @@ endif
4448
KBUNDLE_TYPE_x86_64 = vmlinux
4549
KBUNDLE_TYPE_aarch64 = Image
4650
KBUNDLE_TYPE_riscv64 = Image
51+
KBUNDLE_TYPE_loongarch64 = linux_pe
4752

4853
KERNEL_BINARY_x86_64 = $(KERNEL_SOURCES)/vmlinux
4954
KERNEL_BINARY_aarch64 = $(KERNEL_SOURCES)/arch/arm64/boot/Image
5055
KERNEL_BINARY_riscv64 = $(KERNEL_SOURCES)/arch/riscv/boot/Image
56+
KERNEL_BINARY_loongarch64 = $(KERNEL_SOURCES)/arch/loongarch/boot/vmlinux.efi
57+
5158

5259
KRUNFW_BINARY_Linux = libkrunfw$(VARIANT).so.$(FULL_VERSION)
5360
KRUNFW_SONAME_Linux = libkrunfw$(VARIANT).so.$(ABI_VERSION)

bin2cbundle.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
# Use 64k page size for rounding. This should cover 4k/16k/64k kernels
77
PAGE_SIZE = 65536
88
AARCH64_LOAD_ADDR = '0x80000000'
9+
LINUX_PE_HEADER_SIZE = 64
10+
LINUX_PE_MAGIC = 0x818223cd
11+
LINUX_PE_KERNEL_ENTRY_OFFSET = 8
12+
LINUX_PE_LOAD_OFFSET_OFFSET = 24
13+
LINUX_PE_MAGIC_OFFSET = 56
14+
LOONGARCH_DRAM_START = 0x40000000
15+
LOONGARCH_VMLINUX_LOAD_ADDRESS = 0x9000000000200000
916

1017
def write_header(ofile, bundle_name):
1118
ofile.write('#include <stddef.h>\n')
@@ -69,11 +76,27 @@ def write_elf_cbundle(ifile, ofile) -> int:
6976

7077

7178
def write_raw_cbundle(ifile, ofile) -> int:
79+
data = ifile.read()
80+
write_data_cbundle(data, ofile)
81+
82+
def write_linux_pe_cbundle(ifile, ofile) -> int:
83+
data = ifile.read()
84+
assert(len(data) >= LINUX_PE_HEADER_SIZE)
85+
kernel_entry = data[LINUX_PE_KERNEL_ENTRY_OFFSET:LINUX_PE_KERNEL_ENTRY_OFFSET + 8]
86+
load_offset = data[LINUX_PE_LOAD_OFFSET_OFFSET:LINUX_PE_LOAD_OFFSET_OFFSET + 8]
87+
magic = data[LINUX_PE_MAGIC_OFFSET:LINUX_PE_MAGIC_OFFSET + 4]
88+
assert(int.from_bytes(magic, 'little') == LINUX_PE_MAGIC)
89+
image_load_addr = LOONGARCH_DRAM_START + int.from_bytes(load_offset, 'little')
90+
entry_offset = int.from_bytes(kernel_entry, 'little') - LOONGARCH_VMLINUX_LOAD_ADDRESS
91+
entry_addr = image_load_addr + entry_offset
92+
write_data_cbundle(data, ofile)
93+
return hex(image_load_addr), hex(entry_addr)
94+
95+
def write_data_cbundle(data, ofile):
7296
col = 0
7397
total_size = 0
74-
byte = ifile.read(1)
75-
while byte:
76-
ofile.write('\\x{:x}'.format(byte[0]))
98+
for byte in data:
99+
ofile.write('\\x{:x}'.format(byte))
77100

78101
if col == 15:
79102
ofile.write('"\n"')
@@ -82,13 +105,10 @@ def write_raw_cbundle(ifile, ofile) -> int:
82105
col = col + 1
83106

84107
total_size = total_size + 1
85-
byte = ifile.read(1)
86-
87108
rounded_size = int((total_size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE
88109
padding = rounded_size - total_size
89110
write_padding(ofile, padding, col)
90111

91-
92112
def write_footer_generic(ofile, bundle_name):
93113
footer = """
94114
char * krunfw_get_{}(size_t *size)
@@ -145,6 +165,9 @@ def main() -> int:
145165
elif args.t == 'initrd':
146166
bundle_name = 'INITRD'
147167
ifmt = 'raw'
168+
elif args.t == 'linux_pe':
169+
bundle_name = 'KERNEL'
170+
ifmt = 'linux_pe'
148171
else:
149172
print('Invalid bundle type')
150173
return -1
@@ -158,6 +181,8 @@ def main() -> int:
158181
load_addr, entry_addr = write_elf_cbundle(ifile, ofile)
159182
elif ifmt == 'raw':
160183
write_raw_cbundle(ifile, ofile)
184+
elif ifmt == 'linux_pe':
185+
load_addr, entry_addr = write_linux_pe_cbundle(ifile, ofile)
161186

162187
if bundle_name == 'KERNEL':
163188
if ifmt == 'raw':

0 commit comments

Comments
 (0)