Ortak açılış sözleşmesi
boot.S EL2 ise EL1h'e iner, BSS'i temizler, FP/SIMD erişimini ve EL1 vektör tablosunu kurar. QEMU ve LK7k ortak giriş koduna kartlarına özgü Image başlık alanlarını verir; konsol kart modülünden gelir.
QEMU virt açılışı duruyor. LK7k için ayrı bir AArch64 imajı üç stok UART portunu yoklayıp DTB, bellek ve PSCI raporunu yazacak şekilde derlendi. Dinamik rezervasyonlar çözülmediği için bu imaj telefona yazılmadı.
boot.S EL2 ise EL1h'e iner, BSS'i temizler, FP/SIMD erişimini ve EL1 vektör tablosunu kurar. QEMU ve LK7k ortak giriş koduna kartlarına özgü Image başlık alanlarını verir; konsol kart modülünden gelir.
Stok kernel başlığı ve vendor_boot yükleme alanına göre rustos-lk7k, 0x40000000 aday adresine bağlanır. Üç mediatek,mt6577-uart portunu yoklayacak giriş derlendi; dinamik rezervasyonlar nedeniyle yerleşim hâlâ reddediliyor.
Ayrı rustos-lk7k-probe imajı FDT ve PSCI'yi denetleyip beş saniye sonra sistem reseti ister. QEMU QMP guest-reset olayı doğrulandı; imzasız Android v4 adayı telefona gönderilmedi.
check_placement, adresi bilinmeyen üç reserved-memory isteği varken Ok dönmez. Kilitli bootloader ve farklı vbmeta blob'u dururken fastboot veya flash çalıştırılmaz.
Kartlar depodaki dosyadan derleme sırasında okunur. Her kesitin SHA-256 değeri o metne aittir. QEMU virt çıktısı kanıttır; LK7k imajı üretilmiştir ve telefona yazılmamıştır.
L19–L61src/boot.S::_start
0:
mov x19, x0
mrs x1, CurrentEL
cmp x1, #8
b.ne 1f
/* Enter non-secure AArch64 EL1h if QEMU starts us in EL2. */
movz x1, #0x8000, lsl #16
msr hcr_el2, x1
movz x1, #0x3c5
msr spsr_el2, x1
adr x1, 2f
msr elr_el2, x1
isb
eret
1:
cmp x1, #4
b.ne 3f
2:
msr spsel, #1
adrp x2, __bss_start
add x2, x2, :lo12:__bss_start
adrp x3, __bss_end
add x3, x3, :lo12:__bss_end
4:
cmp x2, x3
b.hs 5f
str xzr, [x2], #8
b 4b
5:
adrp x1, __stack_top
add x1, x1, :lo12:__stack_top
mov sp, x1
/* LLVM may use FP/SIMD for ordinary Rust aggregate copies. */
movz x1, #0x30, lsl #16
msr cpacr_el1, x1
adrp x1, exception_vectors
add x1, x1, :lo12:exception_vectors
msr vbar_el1, x1
isb
mov x0, x19
bl kernel_mainL18–L36src/lk7k_main.rs::kernel_main
#[no_mangle]
extern "C" fn kernel_main(dtb_address: usize) -> ! {
let image = Span {
start: core::ptr::addr_of!(__image_start) as u64,
size: (core::ptr::addr_of!(__image_end) as usize
- core::ptr::addr_of!(__image_start) as usize) as u64,
};
// Placement against dynamic reservations is still unresolved. This entry
// reports that fact; it does not treat the link address as certified.
bootlog::report(
&mut open_early_uart(),
"RustOS/LK7k phone entry",
dtb_address,
image,
);
loop {
unsafe { asm!("wfe", options(nomem, nostack)) };
}
}L53–L93src/board/lk7k.rs::open_early_uart
/// Physical 16550-style port. Logical register numbers are shifted for MTK.
#[cfg(target_arch = "aarch64")]
#[derive(Clone, Copy)]
pub struct MmioPort {
pub base: usize,
}
#[cfg(target_arch = "aarch64")]
impl RegisterIo for MmioPort {
fn read8(&mut self, offset: usize) -> u8 {
unsafe { core::ptr::read_volatile(register_address(self.base, offset) as *const u8) }
}
fn write8(&mut self, offset: usize, value: u8) {
unsafe {
core::ptr::write_volatile(register_address(self.base, offset) as *mut u8, value);
}
}
}
/// Probe the three stock ports and keep the first one that accepts a byte.
#[cfg(target_arch = "aarch64")]
pub fn open_early_uart() -> super::SerialWriter<PolledTx<MmioPort>> {
for &base in &UART_BASES {
let mut probe = PolledTx {
io: MmioPort { base },
poll_limit: 32,
};
if probe.putc(b'\r').is_ok() {
return super::SerialWriter(PolledTx {
io: MmioPort { base },
poll_limit: 8_000,
});
}
}
super::SerialWriter(PolledTx {
io: MmioPort {
base: UART_BASES[0],
},
poll_limit: 32,
})
}L215–L240src/memory.rs::Map::check_placement
/// Require explicit proof of dynamic allocations before claiming a safe placement.
pub fn check_placement(&self, image: Span, dtb: Span) -> Result<(), Error> {
for candidate in [image, dtb] {
if candidate.size == 0 || candidate.end().is_none() {
return Err(Error::InvalidRegion);
}
if !self.ram[..self.ram_count]
.iter()
.any(|r| r.contains(candidate))
{
return Err(Error::OutsideRam);
}
if self.reserved[..self.reserved_count]
.iter()
.any(|r| r.overlaps(candidate))
{
return Err(Error::ReservedOverlap);
}
}
if image.overlaps(dtb) {
return Err(Error::ReservedOverlap);
}
if self.dynamic_requests != 0 {
return Err(Error::DynamicReservationsUnresolved);
}
Ok(())L1–L16linker-lk7k.ld::ENTRY
/* Candidate LK7k physical address matches the stock kernel's text_offset=0
and vendor_boot kernel load address 0x40000000. Dynamic reservations remain
unresolved, so boot-preflight does not certify this placement. */
ENTRY(_start)
SECTIONS {
. = 0x40000000;
__image_start = .;
.text : ALIGN(4096) {
KEEP(*(.text.boot))
KEEP(*(.text.vectors))
*(.text .text.*)
}
.rodata : ALIGN(4096) { *(.rodata .rodata.*) }