小编aba*_*abo的帖子

Write :: write_fmt导致裸机上的页面错误

我的实验代码在裸机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编译时处理的结果!可变参数.

也许你有建议这个案子有什么问题.谢谢.

osdev rust

14
推荐指数
1
解决办法
240
查看次数

在不使用libcore的情况下实现内置类型的基本操作

当我在不使用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]

osdev rust

7
推荐指数
1
解决办法
404
查看次数

胶合首字母缩写词和golang命名约定

有没有一种方法可以使下面的常量在不违反golang命名约定的情况下更具可读性?

const ( // stream types
    MPEGDASHStream  = iota
    HLSStream       = iota
    MPEGTSUDPStream = iota
    MPEGTSRTPStream = iota
)
Run Code Online (Sandbox Code Playgroud)

naming-conventions acronym go

7
推荐指数
2
解决办法
3152
查看次数

Write :: write_fmt在裸机上无法正常工作

在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_64aarch64.

我的代码使用相同的代码生成选项构建.libcore版本对应于我的编译器.有问题的代码在这里.你能说出问题的可能原因吗?

重要更新:

是更精简的代码.libcore是在项目中构建的,因此一切都在掌控之中.上面的循环来自机器重启.代码完全适用于aarch64,但奇怪的是在x86_64上的Write :: write_fmt内崩溃.仔细检查我的启动程序集 - 似乎没有错误.

osdev rust

6
推荐指数
1
解决办法
312
查看次数

我可以为空的 Git 存储库创建工作树吗?

我有一个空的 Git 存储库(即它尚未包含任何提交)。git worktree add有没有办法使用命令(带有--no-checkout选项)为此存储库创建工作树?我的意思是指示 Git 不要将新创建的工作树与任何工作树关联HEAD

git git-worktree

6
推荐指数
1
解决办法
833
查看次数

Rustc/LLVM为aarch64生成错误代码,opt-level = 0

我有两个文件组装/编译/链接到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)

qemu osdev rust arm64

5
推荐指数
1
解决办法
256
查看次数

如何在使用Serde库时禁用"unused attribute"警告?

除了禁用警告,为什么会发生?

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)]没有帮助.

json rust deserialization serde

5
推荐指数
1
解决办法
364
查看次数

如何指示clang格式在文件末尾添加EOL字符?

也许我错过了一些东西,但是仍然没有找到这样的设置。从形式上讲,clang-format这不会产生正确的UNIX文本文件,因为最后几行始终缺少EOL字符。

clang-format

5
推荐指数
1
解决办法
237
查看次数

Helper功能可以安全地从流中读取结构

假设我们有一个单地址空间的操作系统.为了保持稳定性,我们需要强制用户应用程序的内存保护,例如禁止使用'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)

上面的实现有一个严重的问题.它允许读取包含引用的结构.那我怎么解决这个问题呢?

osdev rust

3
推荐指数
1
解决办法
232
查看次数

在Aarch64上同时存在不同大小的页面

根据架构概述文档,Aarch64支持4k和64k页面.一些CPU也支持16k页.查看地址转换方案的详细信息,我得出的结论是,这些CPU 不支持同时存在不同大小的页面(与允许的x86_64不同).我对吗?

paging arm osdev virtual-memory arm64

3
推荐指数
1
解决办法
978
查看次数

有没有办法通过不可变切片中的可变引用来改变对象?

我有&[&mut Foo]。我可以&mut self在这个切片中调用-method of Foo 吗?

rust

1
推荐指数
1
解决办法
51
查看次数

多线程 tokio 是否在单个操作系统线程上运行任务?

当我在 tokio 多线程运行时生成一个任务时,是否保证它会选择一个运行时操作系统线程并仅在其上运行?或者在轮询 future 时它可能会在不同的操作系统线程之间跳转?

更新:如果一项任务可以在操作系统线程之间切换,是否可以将其配置为仅使用一个线程?

rust rust-tokio

1
推荐指数
1
解决办法
1407
查看次数