我的实验代码在裸机x86_64-metal上运行时崩溃(当IDT尚未设置时页面错误),但在aarch64上运行完美.
通过仔细的跟踪,我发现这个页面错误的原因包括损坏的地址(远高于0x200_000,而只有前2M页面被映射为1:1)的函数"f"作为参数传递给core :: fmt :: ArgumentV1 :: new()函数:
#[doc(hidden)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!")]
pub fn new<'b, T>(x: &'b T,
f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> {
unsafe {
ArgumentV1 {
formatter: mem::transmute(f),
value: mem::transmute(x)
}
}
}
Run Code Online (Sandbox Code Playgroud)
AFAIK这个值是由rustc编译器硬编码的,是format_args编译时处理的结果!可变参数.
也许你有建议这个案子有什么问题.谢谢.
当我在不使用libcore的情况下编写一个简单的裸机代码时,我收到以下错误:
错误:二进制操作
!=无法应用于类型u32[E0369]
直接实施面临鸡蛋问题:
#![crate_type = "lib"]
#![feature(no_std, no_core, lang_items)]
#![no_std]
#![no_core]
#[lang = "sized"]
pub trait Sized {}
#[lang = "sync"]
pub trait Sync {}
pub const CONST1: u32 = 1;
pub const CONST2: u32 = 2;
pub struct Struct {
pub field: u32,
}
impl Sync for Struct {}
pub static VAR: Struct = Struct {
field: CONST1 + CONST2,
};
Run Code Online (Sandbox Code Playgroud)
在这里我收到以下错误:
错误:二进制操作
+无法应用于类型u32[E0369]
有没有一种方法可以使下面的常量在不违反golang命名约定的情况下更具可读性?
const ( // stream types
MPEGDASHStream = iota
HLSStream = iota
MPEGTSUDPStream = iota
MPEGTSRTPStream = iota
)
Run Code Online (Sandbox Code Playgroud) 在x86_64体系结构上,write!宏使用字符串参数按预期工作,但不使用整数.当使用整数参数时,我得到一个奇怪的循环(例如write!(writer, "Hello {}!", 123)产生无限的"Hello Hello Hello ...").在aarch64上,write!宏根本不起作用.
我使用以下命令构建libcore:
rustc -C opt-level=3 -Z no-landing-pads -C no-stack-check \
--crate-type rlib --target {arch}-unknown-linux-gnu lib.rs
Run Code Online (Sandbox Code Playgroud)
{arch}分别在哪里x86_64或aarch64.
我的代码使用相同的代码生成选项构建.libcore版本对应于我的编译器.有问题的代码在这里.你能说出问题的可能原因吗?
重要更新:
这是更精简的代码.libcore是在项目中构建的,因此一切都在掌控之中.上面的循环来自机器重启.代码完全适用于aarch64,但奇怪的是在x86_64上的Write :: write_fmt内崩溃.仔细检查我的启动程序集 - 似乎没有错误.
我有一个空的 Git 存储库(即它尚未包含任何提交)。git worktree add有没有办法使用命令(带有--no-checkout选项)为此存储库创建工作树?我的意思是指示 Git 不要将新创建的工作树与任何工作树关联HEAD。
我有两个文件组装/编译/链接到minimalistic内核.
的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
Run Code Online (Sandbox Code Playgroud)
boot.rs:
#[no_mangle]
pub extern fn __boot() {
unsafe {
let ptr = 0x9000000 …Run Code Online (Sandbox Code Playgroud) 除了禁用警告,为什么会发生?
use serde_json::from_str;
use serde_json::error::Result;
#[derive(Deserialize)]
pub struct Config {
#[serde(rename="cudaBlasDylibPath")]
pub cuda_blas_dylib_path: String,
}
impl Config {
pub fn new() -> Result<Config> {
from_str("{}")
}
}
Run Code Online (Sandbox Code Playgroud)
src/config.rs:4:10:4:21警告:未使用的属性,#[warn(unused_attributes)]默认为src/config.rs:4#[derive(Deserialize)]
添加#[allow(unused_attributes)]没有帮助.
也许我错过了一些东西,但是仍然没有找到这样的设置。从形式上讲,clang-format这不会产生正确的UNIX文本文件,因为最后几行始终缺少EOL字符。
假设我们有一个单地址空间的操作系统.为了保持稳定性,我们需要强制用户应用程序的内存保护,例如禁止使用'unsafe'关键字,除非用户具有特殊功能.
我们的用户需要有一种方法可以安全地从/向字节流(例如文件)读/写任意结构.当然,我们谈论的是不包含引用的结构(否则我们会失去内存安全性).
现在我尝试实现这种通用的阅读器功能:
#![feature(core)]
use std::io;
use std::mem;
use std::raw;
fn read<T>(reader: &mut io::Read, dest: &mut T) -> io::Result<usize> {
let slice = raw::Slice{ data:dest, len:mem::size_of::<T>() };
let buf: &mut [u8] = unsafe { mem::transmute(slice) };
reader.read(buf)
}
Run Code Online (Sandbox Code Playgroud)
上面的实现有一个严重的问题.它允许读取包含引用的结构.那我怎么解决这个问题呢?
根据架构概述文档,Aarch64支持4k和64k页面.一些CPU也支持16k页.查看地址转换方案的详细信息,我得出的结论是,这些CPU 不支持同时存在不同大小的页面(与允许的x86_64不同).我对吗?
我有&[&mut Foo]。我可以&mut self在这个切片中调用-method of Foo 吗?
当我在 tokio 多线程运行时生成一个任务时,是否保证它会选择一个运行时操作系统线程并仅在其上运行?或者在轮询 future 时它可能会在不同的操作系统线程之间跳转?
更新:如果一项任务可以在操作系统线程之间切换,是否可以将其配置为仅使用一个线程?
rust ×8
osdev ×6
arm64 ×2
acronym ×1
arm ×1
clang-format ×1
git ×1
git-worktree ×1
go ×1
json ×1
paging ×1
qemu ×1
rust-tokio ×1
serde ×1