操作系统定义与分类

操作系统(英语:Operating System,缩写:OS)是一组系统软件程序,狭义上就是内核如 Linux,广义上就是内核加一组软件组成的发行包,如 Ubuntu,Debian:

• 主管并控制计算机操作、运用和运行硬件、软件资源

• 提供公共服务来组织用户交互。

Responsive Image

Responsive Image

硬件的基本概念

Responsive Image

  • Hart
  • Platform 不能说是个板子,应该理解为芯片。早期的板子就是一块芯片加上各种外设,但是随着技术发展,板子越来越小,外设却并没有变少,是因为外设都被集成到了芯片中。当所有外设都被集成,那么芯片就是 platform。
  • SoC(System on Chip) 片上系统

Responsive Image

QEMU 模拟 virt 这个平台,这个平台有八个 Hart。

地址映射

Responsive Image

为了方便访问外设,现在主流的 platform 会对外设的内存地址做一个映射。映射到 platform 的真实物理地址。对真实物理地址进行操作时,就是对外设的地址进行操作。

物理地址从最低位到最高位都被分配给了各种外设。

引导过程介绍

Responsive Image

通电后,会先到箭头所指的地址,这个地址就是对应的 ROM 外设首地址。ROM 相当于一个小硬盘,断电后不会丢失数据。这里面固化了一些指令。

主要就是跳转指令,运行到 kernel 段继续执行。

Responsive Image

八核同时会执行这个过程。

以上是硬件的部分过程,软件该如何写?

Responsive Image

为了简化学习流程和降低调试难度,目前只支持单核,其余七个核处于空转状态。

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

Responsive Image

Responsive Image

这些寄存器必须使用以下的指令读写:

Responsive Image

Responsive Image

以上指令就是将寄存器值进行一次交换,只不过这个过程是原子性的,不能被打断。

CSRRW经常会用在伪指令CSRW中,完整指令中,第一步向x0写入数据,就是空操作,第二步将rs写入csr。这个伪指令就是完成了一个写入csr的操作。

Responsive Image

Responsive Image

mhartid就是machine hart id

学习以上几个指令,就可以完成判断 hart 是否为第一个的工作了,

Responsive Image

csrr t0, mhartid    #读寄存器值
mv tp, t0           #
bnez t0, park       # 跳转指令,不等于 0 就跳转到 park 标签
wfi
休眠指令

如何初始化栈空间

如何跳转到 C 语言环境

# start.S
#include "platform.h"

    # size of each hart's stack is 1024 bytes
    .equ    STACK_SIZE, 1024

    .global    _start

    .text
_start:
    # park harts with id != 0
    csrr    t0, mhartid     # read current hart id
    mv      tp, t0          # keep CPU's hartid in its tp for later usage.
    bnez    t0, park        # if we're not on the hart 0
                            # we park the hart
    # Setup stacks, the stack grows from bottom to top, so we put the
    # stack pointer to the very end of the stack range.
    slli    t0, t0, 10      # shift left the hart id by 1024

    ###### 初始化栈空间 ######
    # set the initial stack pointer to the end of the first stack space
    la      sp, stacks + STACK_SIZE    
    # move the current hart stack pointer to its place in the stack space
    add     sp, sp, t0       
    ###### 初始化栈空间  ######
    
    ###### 跳转到C语言环境 ######
    j       start_kernel     # hart 0 jump to c, start_kernel is the entry point of the kernel
    ###### 跳转到C语言环境 ######

park:
    wfi
    j    park

stacks:
    # allocate space for all the harts stacks
    .skip    STACK_SIZE * MAXNUM_CPU 
    .end                # End of file
// kernel.c
void start_kernel(void)
{
  while (1) {}; // stop here!
}

通过 UART 打印信息

连接方式

Responsive Image

真实的硬件开发是有一个快开发板,但是这个课程里使用的是 QEMU 来模拟开发板的硬件环境。如果要在程序里打印一段信息,正常的情况是在开发板上连接显示器,但是这里是通过将信息用串口传到主机上,然后用主机的屏幕显示信息。

串口线里是有两根线,负责收信息和发信息。

UART 特点

Responsive Image

  • 并行就是需要多根线,比如有两根线,那么就可以一次发送两位。但是串行节省材料。
  • 数据通信就会涉及同步的问题,同步的话需要一根时钟线来协商好发送时间和接收时间。而 UART 使用异步,发送的数据不仅仅是真实的数据,还会带有一些标识信息。这些标识可以判断出是收还是发。

物理接口

Responsive Image

UART 通讯协议

Responsive Image

图示中横轴可以表示时间,纵轴表示高低电平。

在需要发送数据时,会进行“下拉”1bit,1bit 持续的时间就是波特率分之一秒。

数据在发送过程中可能会受到干扰,会产生畸变,所以需要检验位来判断是否发生畸变。

Responsive Image

初始化

Responsive Image

在软件中,配置 UART 就是配置寄存器的信息。

在板子上有个元器件叫晶振(crystal),他会产生固定频率的时钟。一种是 1.8432MHZ,一种是 7.3728MHZ。想要获得指定的输出频率就需要对寄存器进行配置。查表可以得到配置信息。比如获得 38.4K 频率的输出,就要配置寄存器值为 3。

Responsive Image

LCR 寄存器功能比较多,将第 7 位设置为 1 就是用来设置波特率。

图中DLLDLM寄存器就是需要配置的寄存器。因为 UART 寄存器都是 8 位的,将值0x0003高位0x00存在DLM中,将低位0x03存入DLL