ch-6-7 RVOS

·  阅读 215

Hello RVOS(上)

image-20210812171213300

这个virt_memmap是一个虚拟地址到物理地址的映射,虚拟地址被分成了很多很多,比如看内存的虚拟地址,就被分到了0x80000000 ...

image-20210812171729677

系统引导的过程:

当上电的时候,CPU开始运行,硬件首先跑到0x1000这个地址,这是一个烧录的ROM,里面有boot的汇编指令,这里的代码可以做一些初始化硬件等事情,然后跳转到Kernel代码的``0x80000000`去执行,所以要把第一条指令放在0x80000000.

在我们的Qemu中,是将代码放到0x80000000,然后boot之后就会自动执行这部分代码:

image-20210812172053884

可以看到,这部分指定了代码放到0x80000000

  • 硬件上,8个核同时都会去执行0x80000000的代码,这里为了讲解方便,就让以额

image-20210812172129032

我们这里的课程做一个简化,就是只用一个核,实际上还是8个核. 由于每个核都会执行一遍这个引导程序,所以做一个判断即可,是否是第一个hart,是第一个hart才正常去跑,不是第一个hart的都空转

如何判断当前 hart 是不是第一 个 hart?

image-20210812221332717

每个权限Level都有自己的一组控制寄存器,高级别Level的可以访问低级别Level的CSR.

  • 一上电的时候是在Machine模式,所以我们先关注M模式下的CSR:

    image-20210812221603663

    CSR寄存器的读写不能用通用寄存器那种读写来操作,是要用新的指令:

    image-20210812221737636

    我们关注CSRRW和CSRRS

    一、CSRRW (Atomic Read/Write CSR)

    image-20210812221828124

    CSRRW RD,CSR,RS1:先CSR的值写到RD,RS1的值写到CSR (这两步是原子的)

    即 RD=CSR , CSR = RS1

    由这个产生一个常用的伪指令——csrw——csrw csr,rs等价于csrrw x0,csr,rs,即将rs的值赋值给csr寄存器

    二、CSRRS(Atomic Read and Set Bits in CSR)

    image-20210812222425185

    CSRRS RD,CSR,RS1: RD = CSR , CSR |= RS1 (这两步原子操作完成)

    利用CSRRS产生一个常用的伪指令——csrr——csrr rd,csr:等价于csrrs rd,csr,x0,即将csr赋值给rd,即``rd=csr`


ok,我们进入正题了.

image-20210812222927025

mhartid存放着当前hart的ID.

image-20210812223042457

当上电后,跳转到0x80000000时:

  • csrr t0,mhartid:t0=mhartid

  • mv tp,t0:tp=t0

  • bnez t0,park:如果t0的值不等于0,就跳转到park,park这边的逻辑是一个死循环

Hello RVOS(下)

image-20210812232943231

  • UART:串口通信 (Universal Asynchronous Receiver/Transmitter 异步收发传输器)

1.UART 的硬件连接方式

image-20210812233453689

像显示器等复杂的东西,一般都不会在开发板上就直接做出来,往往是通过上面这根红色的串口线来连到我们的主机上,我们的主机上运行一个串口的接收程序(可以认为是一个客户端),这样就可以把信息打印到我们的屏幕上

我们使用的是模拟器,所以内部不会实际上去接这样的串口线,但要知道,实际上是模拟了这样的串口线.

串口线其实就是一收一发,TX是发送端(Transmitter),RX是接收端(Receiver)

2.UART 的 特点

image-20210812234047470

3.UART 的通讯协议

4.NS16550a 编程接口介绍

image-20210812234608710

NS16550a是我们的模拟器模拟的串口收发器的型号.

地址0x1000-0000 ~ 0x1000-0100是留给串口设备的寄存器使用,通过这个地址来访问这些寄存器

image-20210813000330335

5.NS16550a 的初始化

6.NS16550a 的数据读写

image-20210813001333571

UART里面有一个寄存器来存当前的传来的字节,我们需要用轮询(一直检查是否空闲,可以发下个字节了)或中断(空闲了触发中断)处理的方式知道这个字节什么时候发出去了,发出去了才能传下个字节

  • THR:这个就是放数据的寄存器
  • LSR:这里有一个特殊的bit来告知当前是否空闲了

这两个配合就可以完成数据发送的任务,

代码如下:

image-20210813002047251

可以看到,就是如果LSR的第5位是0,那么一直空转,直到第5位是1了,说明空闲了,才将这个字节放到THR:这是一种轮询方式

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改