1、编译运行¶
Makefile等在M3实验中已详细说明,这里不再赘述。
这小节代码完整实现请查看:https://github.com/thomas-coding/baremetal
1.1 代码¶
先用一行汇编,看下arm系列的编译,elf情况
Vectors:
b Reset_Handler
b .
.globl Reset_Handler
Reset_Handler:
mov r0, #1
mov r1, #2
mov r2, #3
b .
MEMORY
{
FLASH (rwx) : ORIGIN = 0, LENGTH = 0x08000000
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
*(.text*)
} > FLASH
}
链接脚本,从0地址开始放,只有代码段
Note
makefile链接flag修改为-nostdlib -mcpu=cortex-a15
1.2 qemu命令行¶
qemu_option+=" -machine virt,secure=on -cpu cortex-a15"
qemu_option+=" -bios ${shell_folder}/output/target.bin"
qemu_option+=" -nographic"
1.3 运行结果¶
=> 0x0 <Vectors>: b 0x8 <Reset_Handler>
(gdb) si
0x00000008 in Reset_Handler ()
1: x/i $pc
=> 0x8 <Reset_Handler>: mov r0, #1
(gdb) si
0x0000000c in Reset_Handler ()
1: x/i $pc
=> 0xc <Reset_Handler+4>: mov r1, #2
(gdb) info reg r0
r0 0x1 1
Note
开头pc在 0x0 地址,然后跳转到0x8 的 Reset_Handler ,给 r0 赋值为1,执行完看赋值成功了。最后会进入循环。
1.4 Memory layout¶
static const MemMapEntry base_memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
[VIRT_FLASH] = { 0, 0x08000000 },
[VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
/* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
[VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
[VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
[VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
[VIRT_GIC_HYP] = { 0x08030000, 0x00010000 },
[VIRT_GIC_VCPU] = { 0x08040000, 0x00010000 },
/* The space in between here is reserved for GICv3 CPU/vCPU/HYP */
[VIRT_GIC_ITS] = { 0x08080000, 0x00020000 },
/* This redistributor space allows up to 2*64kB*123 CPUs */
[VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 },
[VIRT_UART] = { 0x09000000, 0x00001000 },
[VIRT_RTC] = { 0x09010000, 0x00001000 },
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
[VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
[VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 },
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
/* Actual RAM size depends on initial RAM and device memory settings */
[VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES },
};
qemu 代码hw/arm/virt.c,看memory map