我想了解 Zircon 的(Fuchsia OS 内核)如何在 ARM64 中分配页面,所以我找到了 mmu.cpp https://fuchsia.googlesource.com/fuchsia/+/4277d3203daa0fc5e4dd1625cf96891dd9882f44/zircon/zircon/ .cc#328
但它只是:
if (likely(!test_page_alloc_func_)) {
status = pmm_alloc_page(0, &page, paddrp);
}
Run Code Online (Sandbox Code Playgroud)
从哪里来pmm_alloc_page:https : //fuchsia.googlesource.com/fuchsia/+/4277d3203daa0fc5e4dd1625cf96891dd9882f44/zircon/kernel/vm/pmm.cc#61
此处定义的 pmm 节点:https : //fuchsia.googlesource.com/fuchsia/+/4277d3203daa0fc5e4dd1625cf96891dd9882f44/zircon/kernel/vm/pmm_node.h说:
// per numa node collection of pmm arenas and worker threads
class PmmNode {
Run Code Online (Sandbox Code Playgroud)
我在谷歌和 Fuchsia 文档中都找不到 PMM 区域是什么。有人可以向我澄清这些概念吗?
我想了解在 Zircon 内核上的 ARM64 中如何处理 MMU
根据ARM手册:
在 4kB 颗粒的情况下,硬件可以使用 4 级查找过程。48 位地址的每个转换级别有 9 个地址位(即每个 512 个条目),最后 12 位选择 4kB 中直接来自原始地址的字节。
512 条目 L0 表中虚拟地址索引的位 [47:39]。这些表条目中的每一个都跨越 512GB 的范围并指向一个 L1 表。在该 512 个条目的 L1 表中,位 [38:30] 用作索引来选择一个条目,每个条目指向一个 1GB 块或一个 L2 表。
位 [29:21] 索引到 512 个条目的 L2 表,每个条目指向一个 2MB 块或下一个表级别。在最后一层,bits [20:12] 索引到一个 512 条目的 L2 表,每个条目指向一个 4kB 的块
这对我来说 100% 有意义。L0、L1、L2 表和最终到达物理地址的偏移量。
但是,看看这个代码:https : //github.com/bztsrc/raspi3-tutorial/blob/abaf5a5b2bc1a9fdfe5a9d8191c061671555da3d/10_virtualmemory/mmu.c#L66,解释在这里:
因为我们选择 4k 作为页面大小,并且一个翻译条目是 8 字节,这意味着我们在每页上有 512 个条目。因此 indeces 0..511 属于第一页,512..1023 属于第二页,依此类推。换句话说,paging[0] 的地址等于_end(第一页),paging[512] 的地址等于_end + PAGESIZE(第二页)。
看起来它正在设置手册中提到的 L0、L1 和 …
我正在尝试构建一个 cpp cmake 项目并链接到我的 Rust 项目。
cmake_minimum_required(VERSION 3.0)
set (CMAKE_CXX_STANDARD 17)
project(ZLMediaKit_LIB CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(ENABLE_TESTS OFF FORCE)
option(ENABLE_TESTS OFF)
set(ENABLE_OPENSSL FALSE FORCE)
option(ENABLE_OPENSSL OFF)
add_subdirectory(ZLMediaKit)
add_library(libzlmediakit_cpp_interface STATIC interface.cpp)
target_include_directories(libzlmediakit_cpp_interface PUBLIC
.
${CMAKE_CURRENT_SOURCE_DIR}/ZLMediaKit/src
${CMAKE_CURRENT_SOURCE_DIR}/ZLMediaKit/3rdpart/ZLToolKit/src)
target_link_libraries(libzlmediakit_cpp_interface zlmediakit zltoolkit mpeg mov flv libstdc++)
install(TARGETS libzlmediakit_cpp_interface DESTINATION .)
Run Code Online (Sandbox Code Playgroud)
这是我的build.rs:
extern crate cmake;
use cmake::Config;
fn main()
{
let dst = Config::new("zlmediakit_lib").build();
println!("cargo:rustc-link-search=native={}", dst.display());
println!("cargo:rustc-link-lib=static=libzlmediakit_cpp_interface");
}
Run Code Online (Sandbox Code Playgroud)
但我收到未定义的参考错误:
ong)':
/usr/include/c++/9/ext/new_allocator.h:128: undefined reference to `operator delete(void*)'
/usr/bin/ld: /home/dev/orwell/liborwell_rust/zlmediakit_rust/target/debug/build/zlmediakit_rust-499cc82f14515635/out/liblibzlmediakit_cpp_interface.a(interface.cpp.o): in function `ZLRTSPClient::~ZLRTSPClient()':
/home/dev/orwell/liborwell_rust/zlmediakit_rust/zlmediakit_lib/ZLRTSPClient.h:14: undefined …Run Code Online (Sandbox Code Playgroud) 有时我运行时git add .会添加不应该添加的大文件。如何在未提交的情况下查看添加了哪些文件?以及如何一次“取消添加”这些文件或所有文件,以便我可以修复.gitignore?
使用 cxx 板条箱:https://crates.io/crates/cxx
我在 Rust 上有以下结构:
#[cxx::bridge]
pub(crate) mod ffi {
enum SizeType {
BYTE,
WORD,
DWORD,
QWORD,
}
unsafe extern "C++" {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
这也映射到 C++ 上。我如何使用UniquePtr<SizeType>Rust?我必须编写一个 C++ 函数才能获得它吗?如果我这样做,那么将结构放在 Rust 方面就没有意义了。
我试过
let byte_ptr = UniquePtr::new(SizeType::BYTE);
但它不起作用。
我在zircon kernel start.S中找到了这行汇编代码
str x0, [tmp, #:lo12:zbi_paddr]
Run Code Online (Sandbox Code Playgroud)
对于ARM64。我还发现zbi_paddrC++ 中定义了:
extern paddr_t zbi_paddr;
Run Code Online (Sandbox Code Playgroud)
所以我开始研究这#:lo12:意味着什么。
我发现/sf/answers/2702611691/看起来像是一个很好的解释,但它没有解释非常基本的内容:什么是重新分配以及为什么需要一些东西。
我猜想,由于在 C++ 代码中zbi_paddrr定义并使用,由于在地址从 0 开始的目标文件上生成,因此链接过程必须将其中的所有地址重新分配到最终可执行文件中的地址。start.Sstart.Sstart.o
为了跟踪需要重新分配的符号,ELF 存储这些结构,如答案中所述:
typedef struct
{
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
} Elf64_Rel;
typedef struct
{
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
Elf64_Sxword r_addend; /* Constant part …Run Code Online (Sandbox Code Playgroud) https://github.com/qemu/qemu/blob/stable-4.2/cpus.c#L1290中有 Qemu 非常重要的一部分。我猜这是 KVM 上 CPU 的事件循环。
这是代码:
static void *qemu_kvm_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
cpu->can_do_io = 1;
current_cpu = cpu;
r = kvm_init_vcpu(cpu);
if (r < 0) {
error_report("kvm_init_vcpu failed: %s", strerror(-r));
exit(1);
}
kvm_init_cpu_signals(cpu);
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
r = kvm_cpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
}
}
qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
qemu_kvm_destroy_vcpu(cpu); …Run Code Online (Sandbox Code Playgroud) Theorem law_of_contradiction : forall (P Q : Prop),\n P /\\ ~P -> Q.\nProof.\n intros P Q P_and_not_P.\n destruct P_and_not_P as [P_holds not_P].\nRun Code Online (Sandbox Code Playgroud)\n我正在尝试真正理解这个intros关键字。假设我们想证明P /\\ ~P -> Q。好的,以某种方式intros P Q介绍P和Q。但是这是什么意思?它能识别出P要Q证明的事物吗?关于什么P_and_not_P?它是什么?为什么P和Q使用相同的名称,而is却P_and_not_P定义了一个名称?
更新:
\n看起来它是逐项匹配的:
\nTheorem modus_tollens: forall (P Q : Prop),\n (P -> Q) -> ~Q -> ~P.\nProof.\nintro P.\nintro Q.\nintro P_implies_Q.\nintro not_q.\nintro not_p.\nRun Code Online (Sandbox Code Playgroud)\n给出
\nP Q \xe2\x84\x99\nP_implies_Q P \xe2\x86\x92 …Run Code Online (Sandbox Code Playgroud) 我为我的应用程序创建了一个侧边栏来显示一些图标:
\nWidget build(BuildContext context) {\n return Container(\n color: widget.backgroundColor,\n //width: double.infinity,\n child: Column(\n mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n children: [\n Container(\n child: FittedBox(\n child: Image(image: AssetImage('my_icon.png')))),\n FittedBox(child: Image(image: AssetImage('my_st.png'))),\n FittedBox(child: Image(image: AssetImage('my_cart_2.png'))),\n FittedBox(child: Image(image: AssetImage('my_info_2.png'))),\n FittedBox(child: Image(image: AssetImage('my_rotate_2.png')))\n ],\n ),\n );\n }\nRun Code Online (Sandbox Code Playgroud)\n尽管它呈现完美,但我收到此错误:
\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 Exception caught by rendering library \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown during performLayout():\n'package:flutter/src/rendering/box.dart': Failed assertion: line 320 pos 12: 'width > 0.0': is not true.\n\n\nEither the assertion indicates an error in the framework itself, or we should …Run Code Online (Sandbox Code Playgroud) 我Rc用于对实现特征的对象进行动态调度。然后我需要内部可变性,所以我改为RefCell. 我认为这RefCell只是Rc内部可变性的一个,但它不会接受我的 trait 对象。
use std::cell::RefCell;
use std::rc::Rc;
trait Test {}
struct A;
impl Test for A {}
fn main() {
// This works:
let x: Rc<dyn Test> = Rc::new(A);
// But this not:
// let x: RefCell<dyn Test> = RefCell::new(A);
}
Run Code Online (Sandbox Code Playgroud)
错误:
error[E0308]: mismatched types
--> src/main.rs:18:32
|
18 | let x: RefCell<dyn Test> = RefCell::new(A);
| ----------------- ^^^^^^^^^^^^^^^ expected trait object `dyn Test`, found struct `A`
| |
| expected …Run Code Online (Sandbox Code Playgroud)