我正在尝试使用 CPU cortex m4 模拟 STM32 机器的时钟控制。STM32参考手册中规定,向内核提供的时钟是由HCLK提供的。
RCC 为 Cortex 系统定时器 (SysTick) 的外部时钟提供除以 8 的 AHB 时钟 (HCLK)。SysTick 可以使用此时钟或 Cortex 时钟 (HCLK) 工作,可在 SysTick 控制和状态寄存器中进行配置。
现在 Cortex m4 已经由 QEMU 模拟,我正在使用相同的 STM32 模拟。我的困惑是我应该提供我为STM32开发的“HCLK”时钟频率以将时钟脉冲发送到cortex m4还是cortex -m4本身设法拥有自己的时钟,HCLK时钟频率为168MHz?或者时钟频率不同?
如果我必须将此频率传递给皮层 m4,我该怎么做?
我正在尝试在 QEMU 上运行 u-boot。但是当启动 QEMU 时它什么也没给出,那么为什么这不起作用以及如何调试以找出原因?
这是我尝试过的:
在 Windows 上安装Ubuntu 18.04 WSL2。
为Raspi2编译u-boot
sudo apt install make gcc bison flex
sudo apt-get install gcc-arm-none-eabi binutils-arm-none-eabi
export CROSS_COMPILE=arm-none-eabi-
export ARCH=arm
make rpi_2_defconfig all
Run Code Online (Sandbox Code Playgroud)启动QEMU
qemu-system-arm -M raspi2 -nographic -kernel ./u-boot/u-boot.bin
并且在Windows端也尝试了QEMU,结果是一样的。
PS C:\WINDOWS\system32> qemu-system-arm.exe -M raspi2 --nographic -kernel E:\u-boot\u-boot.bin
尝试在测试引导加载程序上实现硬件中断。例外正在工作(因此发现它是 GPF)。当尝试时sti,会发生 GPF。这是我的主要代码:
cli
lgdt [gdt_desc]
lidt [idt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:bit_32
bit_32:
[bits 32]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, 0x8000
mov esp, eax
mov ebp, esp
sti ; exception raised
Run Code Online (Sandbox Code Playgroud)
这就是我的 GDT 的样子:
start_gdt:
null:
dd 0x0
dd 0x0
code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 01000000b
db 0x0
data:
dw 0xffff …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) 假设我有一台 x86 机器。通过 Linux KVM API 可以轻松创建 x86 VM。
请参阅:vm_init()在kvm-host中:
if ((v->kvm_fd = open("/dev/kvm", O_RDWR)) < 0)
return throw_err("Failed to open /dev/kvm");
if ((v->vm_fd = ioctl(v->kvm_fd, KVM_CREATE_VM, 0)) < 0)
return throw_err("Failed to create vm");
if (ioctl(v->vm_fd, KVM_SET_TSS_ADDR, 0xffffd000) < 0)
return throw_err("Failed to set TSS addr");
...
if ((v->vcpu_fd = ioctl(v->vm_fd, KVM_CREATE_VCPU, 0)) < 0)
return throw_err("Failed to create vcpu");
Run Code Online (Sandbox Code Playgroud)
在这个项目中,很容易在 x86 机器上创建 x86 VM。
然而,我的问题是,如果我希望该虚拟机是 ARM 架构怎么办?
我相信这是适用的,因为我们有qemu-system-arm,而我试图实现的正是它所做的。
来自https://firecracker-microvm.github.io/:
\n\n\nFirecracker 是 QEMU 的替代品,专为安全高效地运行无服务器功能和容器而构建,仅此而已。Firecracker 是用 Rust 编写的,为客户操作系统提供了所需的最小设备模型,同时排除了非必要的功能(仅提供 5 个模拟设备:virtio-net、virtio-block、virtio-vsock、串行控制台和最小键盘)控制器仅用于停止 microVM)。这与简化的内核加载过程一起实现了 < 125 ms 的启动时间和 < 5 MiB 的内存占用。Firecracker 进程还提供 RESTful 控制 API,处理 microVM 的资源速率限制,并提供 microVM 元数据服务以实现主机和来宾之间的配置数据共享。
\n
那么导致 qemu 变慢的主要原因是什么\xe2\x80\x94(主要是设备模拟)?
\n而 125ms + 5MB 的启动时间与……形成对比的是什么呢?
\n我在做 2018 版本 MIT 6.828 时遇到了一些奇怪的事情,该实验室在模拟 80386 CPU 的 QEMU 上运行:
我想做的是初始化 INTEL 82540EM 芯片(也称为 E1000)的接收过程。我基本上只是将一些字节写入设备的寄存器。
首先我定义了一个带有位域的结构,因为它实际上是硬件中的寄存器:
struct rx_addr_reg {
// low 32 bit
unsigned ral : 32; // 0 - 31
// high 32 bit
unsigned rah : 16; // 0 -15
unsigned as : 2; // 16 - 17
unsigned rs : 13; // 18 - 30
unsigned av : 1; // 31
};
Run Code Online (Sandbox Code Playgroud)
我决定通过 C 宏使用它:
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define …Run Code Online (Sandbox Code Playgroud) 我正在学习x86实模式编程,并使用QEMU编写了一个小型引导加载程序来测试它.我选择了GNU汇编程序来学习.
这是汇编代码:
#
# boot.s
#
.section .text
.globl start
start:
//setup stack
mov $0x7c0, %ax
mov %ax, %ss
mov $512, %sp
//setup video
mov $0x0, %eax
mov $0x0, %al
int $0x10
//print a character say 'm'
mov $'m', %al
mov $0x0E, %ah
int $0x10
1:
jmp 1b
Run Code Online (Sandbox Code Playgroud)
QEMU显示屏上显示以下文本:
从硬盘启动...
问题:打印上面的消息,它似乎仍然没有做任何事情.
我用来组装的脚本链接是:
> to assemble : gcc -c boot.s
> to link : ld -T link.ld boot.o -o b.bin
> to put on bootsector of Hard-disk …Run Code Online (Sandbox Code Playgroud) 我正在学习如何使用https://intermezzos.github.io构建基本的OS内核
我已经创建了.iso文件,并且正在qemu-system-x86_64 -cdrom os.iso
运行我按Enter键的地方,QEMU运行带有以下输出的窗口:
Booting from Floppy...
Boot failed: could not read the boot disk
Booting from DVD/CD...
Boot failed: Could not read from CDROM (code 0004)
Booting from ROM...
iPXE (PCI 00:03.0) starting execution...ok
iPXE initializing devices...ok
iPXE 1.0.0+git-20131111.c3d1e78-2ubuntu1.1 -- Open Source Network Boot Firmware
-- http://ipxe.org
Features: HTTP HTTPS iSCSI DNS TFTP AoE bzImage ELF MBOOT PXE Menu
net0: 52:54:00:12:34:56 using 82549em on PCI00:03.0 (open)
[Link:up, TX:0 TXE:0 RX:0 RXE:01]
Configuring (net0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试为arm bear metal编译代码构建二进制翻译器,并尝试通过将其与qemu-arm进行比较来验证正确的执行流程.我使用以下命令来转储程序流:
qemu-arm -d in_asm,cpu -singlestep -D a.flow a.out
我注意到一些奇怪的东西,程序似乎跳转到一个无关的指令,因为0x000080b4不是分支,也不是0x000093ec之后的下一条指令.
0x000093ec: 1afffff9 bne 0x93d8
R00=00000000 R01=00009c44 R02=00000002 R03=00000000
R04=00000001 R05=0001d028 R06=00000002 R07=00000000
R08=00000000 R09=00000000 R10=0001d024 R11=00000000
R12=f6ffed88 R13=f6ffed88 R14=000093e8 R15=000093ec
PSR=20000010 --C- A usr32
R00=00000000 R01=00009c44 R02=00000002 R03=00000000
R04=00000001 R05=0001d028 R06=00000002 R07=00000000
R08=00000000 R09=00000000 R10=0001d024 R11=00000000
R12=f6ffed88 R13=f6ffed88 R14=000093e8 R15=000093d8
PSR=20000010 --C- A usr32
----------------
IN:
0x000080b4: e59f3060 ldr r3, [pc, #96] ; 0x811c
Run Code Online (Sandbox Code Playgroud)
实际执行的指令对应<frame_dummy>于反汇编中标记的开始.有人可以解释模拟器中实际发生了什么,这种行为在ARM架构中是否正常?该计划编制为:arm-none-eabi-gcc --specs=rdimon.specs a.c
这是没有CPU状态的程序流的相同部分:
0x0000804c: e59f3018 ldr r3, [pc, #24] ; 0x806c …Run Code Online (Sandbox Code Playgroud) qemu ×10
c ×4
assembly ×3
bootloader ×2
kvm ×2
x86 ×2
arm ×1
bios ×1
cortex-m ×1
firecracker ×1
gcc ×1
gdb ×1
hypervisor ×1
interrupt ×1
ipxe ×1
linux ×1
linux-kernel ×1
osdev ×1
stm32 ×1
u-boot ×1