Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Loongarch support #2955

Draft
wants to merge 35 commits into
base: master
Choose a base branch
from
Draft

Conversation

opsiff
Copy link

@opsiff opsiff commented Aug 26, 2024

issue #2628 #2686 #2726 #2780

  • mod-grub2 (GCC 13 support)
  • mod-edk2
  • dmsetup
  • FUSEISO
  • busybox
  • vtoycli
  • cpio
  • vtoyfat/gpt
  • VtoyTool
  • cross-compile

Add PE machine types [1] and relocation types [2] for LoongArch to
the current in-repo definitions.

[1] https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types
[2] https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
Add ELF e_machine ID [1] and relocations types [2] for LoongArch to
the current in-repo definitions.

[1] https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_machine_identifies_the_machine
[2] https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_relocations

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
This patch adds a setjmp implementation for LoongArch.

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Sun Haiyong <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
On entry, we need to save the system table pointer as well as our image
handle. Add an early startup file that saves them and then brings us
into our main function.

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
This patch adds support of the stack-based LoongArch relocations
throughout GRUB, including tools, dynamic linkage, and support for
conversion of ELF relocations into PE ones. A stack machine is required
to handle these per the spec [1] (see the R_LARCH_SOP types), of which
a simple implementation is included.

These relocations are produced by binutils 2.38 and 2.39, while the newer
v2.00 relocs require more recent toolchain (binutils 2.40+ & gcc 13+, or
LLVM 16+). GCC 13 has not been officially released as of early 2023, so
support for v1.00 relocs are expected to stay relevant for a while.

[1] https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_relocations

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
A new set of relocation types was added in the LoongArch ELF psABI v2.00
spec [1], [2] to replace the stack-based scheme in v1.00. Toolchain
support is available from binutils 2.40 and gcc 13 onwards.

This patch adds support for the new relocation types, that are simpler
to handle (in particular, stack operations are gone). Support for the
v1.00 relocs are kept for now, for compatibility with older toolchains.

[1] loongson/LoongArch-Documentation#57
[2] https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_appendix_revision_history

Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
Add support for manipulating architectural cache and timers, and EFI
memory maps.

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
This patch adds LoongArch to the GRUB build system and various tools,
so GRUB can be built on LoongArch as a UEFI application.

Signed-off-by: Zhou Yang <[email protected]>
Signed-off-by: Xiaotian Wu <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
In the case of an error grub_initrd_load() uses argv[] to print the
filename that caused the error. It is also possible to obtain the
filename from the file handles and there is no need to duplicate that
information in argv[], so let's drop it.

Signed-off-by: Nikita Ermakov <[email protected]>
Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Backport-commit: also for mips64
Signed-off-by: Wentao Guan <[email protected]>
ARM64 linux loader code is written in such a way that it can be reused
across different architectures without much change. Move it to common
code so that RISC-V doesn't have to define a separate loader.

Signed-off-by: Atish Patra <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
The PE/COFF spec permits the COFF signature and file header to appear
anywhere in the file, and the actual offset is recorded in 4 byte
little endian field at offset 0x3c of the image.

When GRUB is emitted as a PE/COFF binary, we reuse the 128 byte MS-DOS
stub (even for non-x86 architectures), putting the COFF signature and
file header at offset 0x80. However, other PE/COFF images may use
different values, and non-x86 Linux kernels use an offset of 0x40
instead.

So let's get rid of the grub_pe32_header struct from pe32.h, given that
it does not represent anything defined by the PE/COFF spec. Instead,
introduce a minimal struct grub_msdos_image_header type based on the
PE/COFF spec's description of the image header, and use the offset
recorded at file position 0x3c to discover the actual location of the PE
signature and the COFF image header.

The remaining fields are moved into a struct grub_pe_image_header,
which we will use later to access COFF header fields of arbitrary
images (and which may therefore appear at different offsets)

Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
We bumped into the build error while testing gcc-10 pre-release.

../../grub-core/disk/mdraid1x_linux.c: In function 'grub_mdraid_detect':
../../grub-core/disk/mdraid1x_linux.c:181:15: error: array subscript <unknown> is outside array bounds of 'grub_uint16_t[0]' {aka 'short unsigned int[0]'} [-Werror=array-bounds]
  181 |      (char *) &sb.dev_roles[grub_le_to_cpu32 (sb.dev_number)]
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../grub-core/disk/mdraid1x_linux.c:98:17: note: while referencing 'dev_roles'
   98 |   grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty.  */
      |                 ^~~~~~~~~
../../grub-core/disk/mdraid1x_linux.c:127:33: note: defined here 'sb'
  127 |       struct grub_raid_super_1x sb;
      |                                 ^~
cc1: all warnings being treated as errors

Apparently gcc issues the warning when trying to access sb.dev_roles
array's member, since it is a zero length array as the last element of
struct grub_raid_super_1x that is allocated sparsely without extra
chunks for the trailing bits, so the warning looks legitimate in this
regard.

As the whole thing here is doing offset computation, it is undue to use
syntax that would imply array member access then take address from it
later. Instead we could accomplish the same thing through basic array
pointer arithmetic to pacify the warning.

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
The "ARM\x64" magic number in the file header identifies an image as one
that implements the bare metal boot protocol, allowing the loader to
simply move the file to a suitably aligned address in memory, with
sufficient headroom for the trailing .bss segment (the required memory
size is described in the header as well).

Note of this matters for GRUB, as it only supports EFI boot. EFI does
not care about this magic number, and nor should GRUB: this prevents us
from booting other PE linux images, such as the generic EFI zboot
decompressor, which is a pure PE/COFF image, and does not implement the
bare metal boot protocol.

So drop the magic number check.

Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
We bumped into the build error while testing gcc-10 pre-release.

In file included from ../../include/grub/file.h:22,
		from ../../grub-core/fs/zfs/zfs.c:34:
../../grub-core/fs/zfs/zfs.c: In function 'zap_leaf_lookup':
../../grub-core/fs/zfs/zfs.c:2263:44: error: array subscript '<unknown>' is outside the bounds of an interior zero-length array 'grub_uint16_t[0]' {aka 'short unsigned int[0]'} [-Werror=zero-length-bounds]
2263 |   for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian);
../../include/grub/types.h:241:48: note: in definition of macro 'grub_le_to_cpu16'
 241 | # define grub_le_to_cpu16(x) ((grub_uint16_t) (x))
     |                                                ^
../../grub-core/fs/zfs/zfs.c:2263:16: note: in expansion of macro 'grub_zfs_to_cpu16'
2263 |   for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian);
     |                ^~~~~~~~~~~~~~~~~
In file included from ../../grub-core/fs/zfs/zfs.c:48:
../../include/grub/zfs/zap_leaf.h:72:16: note: while referencing 'l_hash'
  72 |  grub_uint16_t l_hash[0];
     |                ^~~~~~

Here I'd like to quote from the gcc document [1] which seems best to
explain what is going on here.

"Although the size of a zero-length array is zero, an array member of
this kind may increase the size of the enclosing type as a result of
tail padding. The offset of a zero-length array member from the
beginning of the enclosing structure is the same as the offset of an
array with one or more elements of the same type. The alignment of a
zero-length array is the same as the alignment of its elements.

Declaring zero-length arrays in other contexts, including as interior
members of structure objects or as non-member objects, is discouraged.
Accessing elements of zero-length arrays declared in such contexts is
undefined and may be diagnosed."

The l_hash[0] is apparnetly an interior member to the enclosed structure
while l_entries[0] is the trailing member. And the offending code tries
to access members in l_hash[0] array that triggers the diagnose.

Given that the l_entries[0] is used to get proper alignment to access
leaf chunks, we can accomplish the same thing through the ALIGN_UP macro
thus eliminating l_entries[0] from the structure. In this way we can
pacify the warning as l_hash[0] now becomes the last member to the
enclosed structure.

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
commit 92bfc33db984 ("efi: Free malloc regions on exit")
introduced memory freeing in grub_efi_fini(), which is
used not only by exit path but by halt/reboot one as well.
As result of memory freeing, code and data regions used by
modules, such as halt, reboot, acpi (used by halt) also got
freed. After return to module code, CPU executes, filled
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
a code. Which leads to #UD exception later.

grub> halt
!!!! X64 Exception Type - 06(#UD - Invalid Opcode)  CPU Apic ID - 00000000 !!!!
RIP  - 0000000003F4EC28, CS  - 0000000000000038, RFLAGS - 0000000000200246
RAX  - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
RBX  - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
RSI  - 00000000064DB768, RDI - 000000000832C5C3
R8   - 0000000000000002, R9  - 0000000000000000, R10 - 00000000061E2E52
R11  - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
R14  - 0000000003E10D80, R15 - 00000000061E2F60
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007598018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F0F4C0

Proposal here is to continue to free allocated memory for
exit boot services path but keep it for halt/reboot path
as it won't be much security concern here.
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
loader flag to be used by efi halt/reboot path.

Signed-off-by: Alexey Makhalov <[email protected]>
Reviewed-by: Darren Kenny <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
…oonarch64

log :
gcc -DHAVE_CONFIG_H -I. -I..  -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=LOONGARCH64_EFI -nostdinc -isystem /usr/lib/gcc/loongarch64-linux-gnu/12/include -I../include -I../include -DGRUB_FILE=\"kern/loongarch64/cache.c\" -I. -I. -I.. -I.. -I../include -I../include -I../grub-core/lib/libgcrypt-grub/src/   -DGRUB_KERNEL=1  -D_FILE_OFFSET_BITS=64 -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations -Wcast-align  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -freg-struct-return -mno-explicit-relocs -fno-plt -Wa,-mla-global-with-abs -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables -fno-unwind-tables -mcmodel=large -fno-stack-protector -Wtrampolines -Werror   -ffreestanding -fshort-wchar   -MT kern/loongarch64/kernel_exec-cache.o -MD -MP -MF kern/loongarch64/.deps-core/kernel_exec-cache.Tpo -c -o kern/loongarch64/kernel_exec-cache.o `test -f 'kern/loongarch64/cache.c' || echo './'`kern/loongarch64/cache.c
kern/loongarch64/cache.c:35:1: error: no previous prototype for ‘grub_arch_sync_dma_caches’ [-Werror=missing-prototypes]
   35 | grub_arch_sync_dma_caches (volatile void *address __attribute__((unused)),
      | ^~~~~~~~~~~~~~~~~~~~~~~~~
mv -f kern/loongarch64/.deps-core/kernel_exec-cache_flush.Tpo kern/loongarch64/.deps-core/kernel_exec-cache_flush.Po
gcc -E -DGRUB_LST_GENERATOR -Dgrub_fs_register=FS_LIST_MARKER -Dgrub_video_register=VIDEO_LIST_MARKER -Dgrub_parttool_register=PARTTOOL_LIST_MARKER -Dgrub_partition_map_register=PARTMAP_LIST_MARKER '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' -DHAVE_CONFIG_H -I. -I..  -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=LOONGARCH64_EFI -nostdinc -isystem /usr/lib/gcc/loongarch64-linux-gnu/12/include -I../include -I../include -DGRUB_FILE=\"lib/efi/halt.c\" -I. -I. -I.. -I.. -I../include -I../include -I../grub-core/lib/libgcrypt-grub/src/    -D_FILE_OFFSET_BITS=64 lib/efi/halt.c commands/halt.c > halt.marker.new || (rm -f halt.marker; exit 1)
cc1: all warnings being treated as errors
make[3]: *** [Makefile:40251:kern/loongarch64/kernel_exec-cache.o] 错误 1

Signed-off-by: Wentao Guan <[email protected]>
Signed-off-by: Wentao Guan <[email protected]>
@opsiff opsiff marked this pull request as draft August 26, 2024 05:30
INSTALL/ventoy/ventoy_${postfix}.efi
INSTALL/ventoy/vtoyutil_${postfix}.efi
VDiskChain/Tool/vdiskchain_${postfix}.efi

Signed-off-by: Wentao Guan <[email protected]>
use musl-gcc to build smallest binary:
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -static -O2 -D_FILE_OFFSET_BITS=64  vtoygpt.c crc32.c -o vtoygpt

Signed-off-by: Wentao Guan <[email protected]>
gcc -specs /usr/local/musl/lib/musl-gcc.specs -Os  -DVTOY_LOONGARCH64 -D_FILE_OFFSET_BITS=64  *.c BabyISO/*.c -IBabyISO -Wall -DUSE_MUSL_C -DBUILD_VTOY_TOOL  -o  vtoytool_la64

Signed-off-by: Wentao Guan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant