|
| 1 | +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +use std::io::Write; |
| 5 | + |
| 6 | +const MOCK_KERNEL_PATH: &str = "src/utils/mock_kernel/kernel.bin"; |
| 7 | + |
| 8 | +// Kernel header for aarch64 that comes from the kernel doc Documentation/arm64/booting.txt. |
| 9 | +#[derive(Default)] |
| 10 | +#[repr(C, packed)] |
| 11 | +struct KernelHeader { |
| 12 | + code0: u32, // Executable code |
| 13 | + code1: u32, // Executable code |
| 14 | + text_offset: u64, // Image load offset, |
| 15 | + image_size: u64, // Effective Image size, little endian |
| 16 | + flags: u64, // kernel flags, little endian |
| 17 | + res2: u64, // reserved |
| 18 | + res3: u64, // reserved |
| 19 | + res4: u64, // reserved |
| 20 | + magic: u32, // Magic number, little endian, "ARM\x64" |
| 21 | + res5: u32, // reserved (used for PE COFF offset) |
| 22 | +} |
| 23 | + |
| 24 | +fn main() { |
| 25 | + if cfg!(target_arch = "x86_64") { |
| 26 | + println!("cargo:rerun-if-changed=src/utils/mock_kernel/main.c"); |
| 27 | + let status = std::process::Command::new("gcc") |
| 28 | + .args([ |
| 29 | + // Do not use the standard system startup files or libraries when linking. |
| 30 | + "-nostdlib", |
| 31 | + // Prevents linking with the shared libraries. |
| 32 | + "-static", |
| 33 | + // Do not generate unwind tables. |
| 34 | + "-fno-asynchronous-unwind-tables", |
| 35 | + // Remove all symbol table and relocation information. |
| 36 | + "-s", |
| 37 | + "-o", |
| 38 | + MOCK_KERNEL_PATH, |
| 39 | + "src/utils/mock_kernel/main.c", |
| 40 | + ]) |
| 41 | + .status() |
| 42 | + .expect("Failed to execute gcc command"); |
| 43 | + if !status.success() { |
| 44 | + panic!("Failed to compile mock kernel"); |
| 45 | + } |
| 46 | + } else if cfg!(target_arch = "aarch64") { |
| 47 | + let header = KernelHeader { |
| 48 | + magic: 0x644D5241, |
| 49 | + ..std::default::Default::default() |
| 50 | + }; |
| 51 | + // SAFETY: This is safe as long as `header` is valid as `KernelHeader`. |
| 52 | + let header_bytes = unsafe { |
| 53 | + std::slice::from_raw_parts( |
| 54 | + (&header as *const KernelHeader).cast::<u8>(), |
| 55 | + std::mem::size_of::<KernelHeader>(), |
| 56 | + ) |
| 57 | + }; |
| 58 | + |
| 59 | + let mut file = std::fs::File::create(MOCK_KERNEL_PATH).expect("Failed to create a file"); |
| 60 | + file.write_all(header_bytes) |
| 61 | + .expect("Failed to write kernel header to a file"); |
| 62 | + } else { |
| 63 | + panic!("Unsupported arch"); |
| 64 | + } |
| 65 | +} |
0 commit comments