最新TinyEMU源码分析之虚拟机初始化,2024年最新Linux运维开发基础课程

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

// 初始化设备
/\* virtio console \*/
if (p->console) {
    s->common.console_dev = virtio\_console\_init(vbus, p->console);
    vbus->addr += VIRTIO_SIZE;
}

...

if (p->input_device) {
	// 键盘
	s->keyboard_dev = virtio\_input\_init(vbus,
										VIRTIO_INPUT_TYPE_KEYBOARD);
	vbus->addr += VIRTIO_SIZE;

	// 鼠标
	s->mouse_dev = virtio\_input\_init(vbus,
									 VIRTIO_INPUT_TYPE_TABLET);
	vbus->addr += VIRTIO_SIZE;
}

// 拷贝BIOS和Kernel;手动写入5条指令
copy\_bios(s, p->files[VM_FILE_BIOS].buf, p->files[VM_FILE_BIOS].len,
          p->files[VM_FILE_KERNEL].buf, p->files[VM_FILE_KERNEL].len,
          p->files[VM_FILE_INITRD].buf, p->files[VM_FILE_INITRD].len,
          p->cmdline);

return (VirtMachine \*)s;

}


首先,初始化VirtMachineClass、ram大小、max\_xlen,以及内存映射初始化等。  
 然后,在riscv\_cpu\_init函数中,会完成pc赋初值和TLB初始化(赋值为-1)。



s->pc = 0x1000;
s->cpu_state = riscv_cpu_init(s->mem_map, max_xlen);



> 
> cpu\_state的类型为RISCVCPUState结构,该结构中,包含mstatus、mtvec、mscratch等CSR寄存器定义。
> 
> 
> 


**我们猜测,第一条指令地址,就是0x1000**。


初始化结构参数,其实就是把一些参数,保存到RISCVMachine对象中。


## 2 配置RAM地址空间


我们对本部分代码,进行分析,并结合以下常量定义。



#define LOW_RAM_SIZE 0x00010000 /* 64KB */
#define RAM_BASE_ADDR 0x80000000
#define CLINT_BASE_ADDR 0x02000000
#define CLINT_SIZE 0x000c0000
#define HTIF_BASE_ADDR 0x40008000
#define IDE_BASE_ADDR 0x40009000
#define VIRTIO_BASE_ADDR 0x40010000
#define VIRTIO_SIZE 0x1000
#define VIRTIO_IRQ 1
#define PLIC_BASE_ADDR 0x40100000
#define PLIC_SIZE 0x00400000
#define FRAMEBUFFER_BASE_ADDR 0x41000000


发现代码,构成了,如下的内存地址空间:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c8d3e269796a475ebee31c5f14841a46.png#pic_center)  
 这里,主要是,确定Low Dram、CLINT、HTIF、VBUS、PLIC、High Dram的地址空间范围(申请内存),可以结合上面代码,好好看看,比较简单。


因为,在执行指令时,必须要知道具体的内存空间,是如何分布的,以便正确访问内存。


## 3 初始化设备


初始化console、net device、block device、filesystem、display device、input device。  
 不详述,自己看源码。


## 4 拷贝BIOS和Kernel


在copy\_bios函数中,完成拷贝BIOS和Kernel,其代码如下:



static void copy_bios(RISCVMachine *s, const uint8_t *buf, int buf_len,
const uint8_t *kernel_buf, int kernel_buf_len,
const uint8_t *initrd_buf, int initrd_buf_len,
const char *cmd_line)
{
// 拷贝BIOS到0x80000000
ram_ptr = get_ram_ptr(s, RAM_BASE_ADDR, TRUE);
memcpy(ram_ptr, buf, buf_len);

// 拷贝Kernel到0x80200000
kernel_base = 0;
if (kernel_buf_len > 0) {
    /\* copy the kernel if present \*/
    if (s->max_xlen == 32)
        align = 4 << 20; /\* 4 MB page align \*/
    else
        align = 2 << 20; /\* 2 MB page align \*/
    kernel_base = (buf_len + align - 1) & ~(align - 1);
    memcpy(ram_ptr + kernel_base, kernel_buf, kernel_buf_len);
}

// 创建设备树,并写入内存地址(0x1000+8\*8)处
ram_ptr = get\_ram\_ptr(s, 0, TRUE);
fdt_addr = 0x1000 + 8 \* 8;
riscv\_build\_fdt(s, ram_ptr + fdt_addr,
                RAM_BASE_ADDR + kernel_base, kernel_buf_len,
                RAM_BASE_ADDR + initrd_base, initrd_buf_len,
                cmd_line);

// 手动写入5条指令
/\* jump\_addr = 0x80000000 \*/
q = (uint32\_t \*)(ram_ptr + 0x1000);
q[0] = 0x297 + 0x80000000 - 0x1000; /\* auipc t0, jump\_addr \*/
q[1] = 0x597; /\* auipc a1, dtb \*/
q[2] = 0x58593 + ((fdt_addr - 4) << 20); /\* addi a1, a1, dtb \*/
q[3] = 0xf1402573; /\* csrr a0, mhartid \*/
q[4] = 0x00028067; /\* jalr zero, t0, jump\_addr \*/

}


* 将bios(bbl64.bin)拷贝到0x80000000地址处(物理地址),本例中bbl64.bin长度为0xd21a。
* 将kernel(kernel-riscv64.bin)拷贝到0x80200000地址处(物理地址),本例中kernel-riscv64.bin长度为0x3d5324。
* 创建设备树,并写入内存地址(0x1000+8\*8)处(物理地址)。


拷贝BIOS和Kernel的地址,与上图中内存地址空间,一致。


## 5 手动写入5条指令


手动写入的5条指令,翻译过来,就是如下:





**先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里**

**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/9a26f5ff68b55db34cebb46a3709b0c1.png)
![img](https://img-blog.csdnimg.cn/img_convert/b930edf033992ee5c65df909b22a134f.png)
![img](https://img-blog.csdnimg.cn/img_convert/0dbd0df7975cf0bb73ed6695a70eb1d5.png)
![img](https://img-blog.csdnimg.cn/img_convert/bf2dcb9808c063084a659dc019dfce7d.png)
![img](https://img-blog.csdnimg.cn/img_convert/a7c69ac46e9bee4ed596f040395a940f.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值