Ho due file che sono assemblati/compilati/collegati in un kernel minimalista.Rustc/LLVM genera codice errato per aarch64 con opt-level = 0
start.S:
.set CPACR_EL1_FPEN, 0b11 << 20
.set BOOT_STACK_SIZE, 8 * 1024
.global __boot_stack
.global __start
.global __halt
.bss
.align 16
__boot_stack:
.fill BOOT_STACK_SIZE
.text
__start:
/* disable FP and SIMD traps */
mov x0, #CPACR_EL1_FPEN
msr cpacr_el1, x0
/* set stack */
adr x0, __boot_stack
add sp, x0, #BOOT_STACK_SIZE
/* call the Rust entry point */
bl __boot
__halt:
/* halt CPU */
wfi
b __halt
boot.rs: '!'
#[no_mangle]
pub extern fn __boot() {
unsafe {
let ptr = 0x9000000 as *mut u8;
*ptr = '!' as u8;
}
}
Per opt-livello = 3 le uscite codice risultante singoli a una porta seriale (come era previsto). Per opt-level = 0 ho uno strano loop infinito (ad esempio '!!!!!!!!! ....'). Ecco la discarica disassemblato del codice problematico:
0000000000000000 <__kernel_begin>:
0: d2a00600 mov x0, #0x300000 // #3145728
4: d5181040 msr cpacr_el1, x0
8: 100007c0 adr x0, 100 <__boot_stack>
c: 9140081f add sp, x0, #0x2, lsl #12
10: 94000003 bl 1c <__boot>
0000000000000014 <__halt>:
14: d503207f wfi
18: 17ffffff b 14 <__halt>
000000000000001c <__boot>:
1c: a9bf7bfd stp x29, x30, [sp,#-16]!
20: 910003fd mov x29, sp
24: 94000003 bl 30 <aarch64::boot::__boot::__rust_abi>
28: a8c17bfd ldp x29, x30, [sp],#16
2c: d65f03c0 ret
0000000000000030 <aarch64::boot::__boot::__rust_abi>:
30: d10043ff sub sp, sp, #0x10
34: 52a12008 mov w8, #0x9000000 // #150994944
38: 2a0803e9 mov w9, w8
3c: f90007e9 str x9, [sp,#8]
40: 52800428 mov w8, #0x21 // #33
44: 39000128 strb w8, [x9]
48: 910043ff add sp, sp, #0x10
4c: d65f03c0 ret
Il codice è testato utilizzando qemu-system-aarch64. Non vedo gravi problemi con esso (eccetto ridondanza). Puoi suggerire una possibile causa di questo comportamento anormale?
P.S. Questa è la versione ottimizzata che funziona correttamente:
0000000000000000 <__kernel_begin>:
0: d2a00600 mov x0, #0x300000 // #3145728
4: d5181040 msr cpacr_el1, x0
8: 1007ffc0 adr x0, 10000 <__boot_stack>
c: 9140081f add sp, x0, #0x2, lsl #12
10: 94000003 bl 1c <__boot>
0000000000000014 <__halt>:
14: d503207f wfi
18: 17ffffff b 14 <__halt>
000000000000001c <__boot>:
1c: 52a12008 mov w8, #0x9000000 // #150994944
20: 52800429 mov w9, #0x21 // #33
24: 39000109 strb w9, [x8]
28: d65f03c0 ret
Sembra una segnalazione di bug, non una domanda. In tal caso, dovrebbe essere [archiviato sul repository Github] (https://github.com/rust-lang/rust/issues). – Shepmaster
Non sono sicuro che questo sia un bug. Forse ho perso alcuni passaggi obbligatori di inizializzazione della CPU in start.s. – ababo
Non vedo nulla di evidentemente sbagliato nel codice prodotto. Potresti pubblicare un disassemblaggio del codice con opt-level = 3? Inoltre, probabilmente dovresti fare una fase di bootstrap in C per impostare alcuni pagetables, poiché nella mia esperienza Rust genera accessi non allineati (che non ho potuto disabilitare) e gli accessi non allineati sono vietati prima di impostare gli impaginati. (nota: non so se qemu emula questo comportamento) – Vaelden