课程链接:https://pdos.csail.mit.edu/6.S081/2020/
MIT 6.S081是著名的操作系统课程,理论与实践相结合的经典。通过实现部分内核功能来学习设计和实现操作系统。
本文讲解如何搭建6.S081的环境,主要涉及到仿真模拟器(qemu)、镜像文件、依赖。Ubuntu20搭建起来比较简单,执行以下命令即可。6.S081环境搭建
只有了解底层原理才能写好上层应用,曾经几度想要系统地学习OS课程,尝试去看了《计算机操作系统》、《Operating Systems: Three Easy Pieces》、《UNIX环境高级编程》,均以半途而废告终。被大量的抽象概念所淹没,对操作系统如何工作,用户程序如何运行,与CPU等硬件如何交互等问题完全没有清晰的认识。所以这次选择了以动手实践为主的课程,直接对内核源码进行学习和扩展,一步步揭开OS的神秘面纱。
在实验之前,推荐阅读一下官网LEC1中提供的资料。其中Introduction是对该课程的的概述,examples则是几个系统编程的样例,这两部分快速浏览一遍即可。对于xv6 book的第一章,则建议稍微细致地阅读一遍,特别是对fork()、exec()、pipe()、dup()这几个系统调用的介绍,会在后面实验中用到。
需要注意的是,这两个工具都需要是 RISC-V 版本的,因为 xv6 是依赖 RISC-V 指令集架构的。
一直想了解下操作系统相关的东西,发现了这个资源(MIT的6.S081课程),希望能借此来掌握操作系统的一些知识。学习的是2020年秋季学期(2020 fall)的资源。
记录一下 MIT 6.S081 的学习过程。主要是写 Lab 的经历吧,知识相关的笔记就不写了。
在本实验中,您将为用户级线程系统设计上下文切换机制,然后实现它。你的 xv6 有两个文件 user/uthread.c 和 user/uthread_switch.S,以及 Makefile 中的一个规则来构建一个 uthread 程序。uthread.c 包含大部分用户级线程包,以及三个测试线程的代码。但线程包中缺少一些用于创建线程和线程间切换的代码。
这个系列的目的还是以讲解xv6-riscv的代码以及记录我在做的事情为主,也会掺杂许多mini-riscv-os的代码介绍(关于xv6-riscv和mini-riscv-os的链接请看参考),并非教程倾向(但也会尽可能讲解一些基础知识),很多细节不会讲到。如果想要更详细的教程我建议你查看参考资料中引用的内容,在这一期我会列出一部参考的项目。
在本作业中,您将增加xv6文件的最大大小。目前,xv6文件限制为268个块或268*BSIZE字节(在xv6中BSIZE为1024)。此限制来自以下事实:一个xv6 inode包含12个“直接”块号和一个“间接”块号,“一级间接”块指一个最多可容纳256个块号的块,总共12+256=268个块。
在对应的C906的 main.c 函数最后面加上下列代码,配置 GPIO MUX 为 JTAG
输入 file ./kernel/kernel载入符号表,然后target remote loaclhost:26000即可:
本实验将使您熟悉多线程。您将在用户级线程包中实现线程之间的切换,使用多个线程来加速程序,并实现一个屏障。
最近有一些riscv的项目做,虽然以前也用过例如k210之类的riscv架构的芯片,但是都止于能够做一些应用,并未特别关注其芯片的体系架构方面的东西,但是随着接触的芯片架构的种类的逐渐的增加,发现要想使用一款好芯片的,仅仅做上层应用并不能完全发挥出特定架构芯片的全部优势。比如aarch64的el层级和虚拟化的模型,mips的mmu特性,以及sparc的窗口寄存器等等,芯片架构的特点要是能够完全的发挥出来,写起应用起来,那真是觉得很爽的事情。
然后在 Git Bash 中执行 make 命令,可以生成 benos_payload.bin 文件,如下图所示:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
与CPU、硬件打交道的时候,有时候看不出自己的代码或者系统出现了什么问题,这时候内核调试工具就显得尤为重要了。
COW fork() creates just a pagetable for the child, with PTEs for user memory pointing to the parent’s physical pages. COW fork() marks all the user PTEs in both parent and child as not writable. When either process tries to write one of these COW pages, the CPU will force a page fault. The kernel page-fault handler detects this case, allocates a page of physical memory for the faulting process, copies the original page into the new page, and modifies the relevant PTE in the faulting process to refer to the new page, this time with the PTE marked writeable. When the page fault handler returns, the user process will be able to write its copy of the page.
本实验探索如何使用陷阱实现系统调用。您将首先使用栈做一个热身练习,然后实现一个用户级陷阱处理的示例。
xv6中提供有sh.c的实现,除了重定向和管道,还对括号、列表命令、后台命令等做了支持,且整体设计较为复杂。所以我们无需过多参考已有代码,可以选择简单的思路来满足需求,在完成后再去阅读xv6的shell实现。
This lab explores how system calls are implemented using traps. You will first do a warm-up exercises with stacks and then you will implement an example of user-level trap handling.
对于esp32c3裸机开发,用openocd结合gdb非常的有用,这是裸机开发的关键工具。
gcc工具链是一个复杂而又巧妙的工程,随着riscv上层软件的逐渐完善,工具链和底层系统软件的开发也显得尤为重要。深入理解gcc的原理,能够更好的对计算机体系结构有一个完整的了解。
上一期主要讲解了shdr计算更新的部分以及osec offset的设置,这期则是做链接最后的工作。上期在对段shrink的时候也提到部分synthetic的符号值还未固定,本期就会从这部分的值提起,之后则是对debug_section进行压缩,同时文件的大小也会产生变化,到了这里整个文件内部的layout以及文件的大小也就固定了。
做嵌入式开发时,很多时候都会使用到GDB,从底层去理解GDB的调试过程,将更加容易的理解调试的过程。
继阿里推出阿里OS,华为推出鸿蒙OS,腾讯的TencentOS tiny之后,小米也高调的推出Xiaomi Vela。各大互联网公司都在做自己的物联网操作系统,物联网操作系统已呈现百花齐放百家争鸣的态势。这篇文章主要讲Nuttx的使用。
本文主要描述树莓派64位的编译及运行方式,并且通过在qemu上运行仿真体验一下rt-thread 的64位效果。对于手上没有树莓派但是又想体验一下树莓派64位的朋友来说非常方便。当在qemu上运行通过后,再下载到真实的树莓派3b的板子上运行,效果一致。通过这种方式可以方便调试程序。
嵌入式开发的过程中,很多时间都是要和硬件设备打交道,通过程序控制硬件的具体行为,这些往往是单片机延续下来的开发模式,在目前复杂的嵌入式系统中,很多都需要借助设计模式来进行开发,比如文件系统,网络,图形,算法等等,这些如果能够利用软件模拟器进行开发,可以大大的减少上板调试的时间。减少硬件连接的烦恼,在家也能随时分析软件代码。
本文主要梳理riscv32在qemu的移植过程,将通过几天时间将其整理和最小系统的bring up。为了保证代码的可维护性,所有修改符合rt-thread bsp制作规范。目标就是riscv32 qemu 上运行rt-thread。以RT-Thread v4.0.3 released为工程代码的基线,进行开发移植工作。
对于向量中断,其中断发生后,pc指针会根据中断的类型跳转到基地址+中断号*4的地址处去执行中断处理程序,做过stm32的,应该比较清楚向量中断的大概样子。当然,riscv也是支持这种向量中断,这样每个地址处会安排一个特定的中断处理函数,当中断发生后,跳转到特定的函数去执行即可。
前一段时间分享的活动NXP恩智浦VEGA织女星开发板免费申请,不知道大家申请了吗?现在官方中文网站open-isa.cn刚上线不久,开发板很好申请,身边几个朋友都申请到了,还没申请的朋友可以申请一块体验一下RISC-V内核MCU的开发。本篇文章介绍一下,Windows环境下搭建基于Eclipse + RISC-V gcc编译器的RISC-V开发环境,配合openocd调试软件,可以实现RISC-V内核程序的编译、下载和调试。
xv6中的sleep函数本质就是软件定时器的实现,但是其思路并不是在每次时钟中断发生时,唤醒所有到期的定时任务,而是直接唤醒所有睡眠的任务,让其自身去检查是否睡够了,如果没睡够,那么就继续接着睡。
RISC-V(跟我读:“risk----------------five”)是一个基于精简指令集(RISC)原则的开源指令集架构(ISA)。
mit 6.828 lab 代码和笔记,以及中文注释源代码已放置在github中: https://github.com/yunwei37/xv6-labs
任何芯片在启动之前都需要有一段汇编代码,从这段汇编代码上就可以体现一些架构设计的特点。往往做嵌入式底层开发都需要关注这段汇编代码的含义,这样在使用的时候才能全面的了解启动时做了什么事情,在后续的程序中遇到问题也能复盘推演。
Yocto 项目 (YP) 是一个开源协作项目,可帮助开发人员创建基于 Linux 的定制系统,无论硬件架构如何。该项目提供了一套灵活的工具和空间,全世界的嵌入式开发人员可以共享技术、软件堆栈、配置和最佳实践,这些技术、软件堆栈、配置和最佳实践可用于为嵌入式和物联网设备或任何需要定制 Linux 操作系统的地方创建定制的 Linux 映像。
线程可以认为是一种在有多个任务时简化编程的抽象。一个线程可以认为是串行执行代码的单元。如果你写了一个程序只是按顺序执行代码,那么你可以认为这个程序就是个单线程程序,这是对于线程的一种宽松的定义。虽然人们对于线程有很多不同的定义,在这里,我们认为线程就是单个串行执行代码的单元,它只占用一个CPU并且以普通的方式一个接一个的执行指令。
xv6中的fork()系统调用将父进程的所有用户空间内存复制到子进程中。如果父进程较大,则复制可能需要很长时间。更糟糕的是,这项工作经常造成大量浪费;
Vivado安装iverilog安装gtkwave 安装安装iverilog_gtkwave实例使用清华镜像站安装 gtkwave安装iverilog仿真实战MCU JTAG安装RISC-V工具链安装
由于RISCV的模块化的指令集的定义,各家都有着自己的实现方式。从当前看来,除了标准的CSR外,很多都实现了自己的CSR指令扩展。如何自定义CSR并且让编译器能够识别,本文将进行一定的分析,同时从riscv gcc开发的角度出发,来分析编译器开发的流程。
上一篇文章中,我们通过源码跟踪了整个Trap的执行流程,本文追踪我们通过Debug的方式,来验证上一篇文章的说法。
曾经我刚开始学习 shell 脚本时,除了知道用 echo 输出一些信息外,并不知道其他方法,仅仅依赖 echo 来查找错误,比较难调试且过程繁琐、效率低下。本文介绍下我常用的一些 shell 脚本调试方法,希望能对 shell 的初学者有所帮助。
riscv支持指令集自定义扩展,这大大增加了riscv的可玩性,同时对于一些实际应用中,自己通过一条指令来实现特定的功能,效率非常高,当然,前提是硬件平台需要对该指令的支持。
这是 os summer of code 2020 项目每日记录的一部分: 每日记录github地址(包含根据实验指导实现的每个阶段的代码):https://github.com/yunwei37/os-summer-of-code-daily
一些操作系统(例如 Linux)通过在用户空间和内核之间共享只读区域中的数据来加速某些系统调用。 这消除了在执行这些系统调用时对内核交叉的需要。
Loco 是 Rust 的 Web 或 API 框架。它也是开发人员的生产力套件:它包含您培养爱好或下一次创业所需的一切。它也受到 Rails 的强烈启发。
领取专属 10元无门槛券
手把手带您无忧上云