操作系统基础:内存管理
内存
CPU是高速设备,磁盘是一种低速设备,为了使数据读写不拖累CPU的计算速度,二者通过内存进行交互,内存速度高,但存储空间小于外存,用于存放CPU处理的数据。
首先要搞明白革命对象,存储器涵盖的种类是十分广泛的,有些存储器概念太久不接触也会混淆。
外存
外存就是最常见的存储器件,例如电脑硬盘等,用于大量存放数据,掉电也可以保存数据,只是相对内存而命名。
内存
内存就是暂存硬盘数据的存储器,硬件上是一种内存条的东西,硬盘的IO读写速度不能满足CPU要求,因此内存应运而生,一旦掉电,内存数据就会被清空。内存也称主存,一般是属于DRAM。
cache
cache是比内存更加高速的缓存,对CPU而言,内存的速度仍然是欠缺的,因此高速的读写需要cache的帮助,cache存在于内存和CPU之间,也因为其对速度的追求,其大小一般很小,几十k到几十M。现代CPU一般采取多级缓存架构,越靠近CPU,容量越小,速度越快。cache一般使用的是SRAM。
RAM与ROM与Flash
RAM是随机读取存储器,可以对存储器进行任意读写,但是掉电数据也会丢失;RAM被分成静态随机读取存储 ...
操作系统MIT 6.S081 xv6内核:基础理论
从常规操作系统原理和xv6系统原理两个方面入手,记录了一些重要的操作系统理论,有助于帮助加深lab的理解。
中断和异常
xv6的中断系统并不多,只有缺页中断、系统调用中断、设备中断以及其他故障中断,这里中断一节是针对操作系统的概述,而其余内容基本仅面对xv6及其源码。
中断的作用
CPU上的运行程序分为两种,一种是操作系统内核程序,另一种是应用程序,在合适情况下,操作系统会把CPU使用权交给应用程序,此时从内核态切换到用户态,通过执行一条特权指令:修改PSW标志位为用户态,意味着内核主动让出CPU使用权;而如果需要从用户态切换回内核态,唯一途径是通过中断实现,内核会重新夺回CPU使用权。
内中断和外中断
内中断(异常中断)
内中断:与当前执行的指令有关,中断信号来自CPU内部;
典型的内中断:
1.
用户态植入非法特权指令:特权指令是一种只允许内核态访问的指令(访问对应特权寄存器),如果在应用程序中出现特权指令,会触发中断,内核会重新获取CPU使用权,内核程序会继续处理这个中断。
非法参数:用户程序除数为0,触发中断,程序不会继续执行,内核重新获取控制权处理中 ...
操作系统MIT 6.S081 xv6内核(番外):GDB调试
GDB是一个强大的代码调试工具,很多时候printf能帮助我们打印错误,但是如果栈调用复杂,或者遇到奇奇怪怪的其他错误,就没有办法了。对于xv6的gdb调试,资料可谓是参差不齐,而且很多地方只描述了一半的方法,也让我花了一晚上的时间去找答案,调试是一个积累的过程,该文章会持续更新。
运行
终端运行: 1make qemu-gdb
新建终端运行: 1riscv64-unknown-elf-gdb kernel/kernel 此时会出现一个警告: 12warning: File "/home/linux/Desktop/MIT_xv6/xv6-labs-2020/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".To enable execution of this file add
大概意思是你的gdb初始化被某个路径阻断了,因此需要在家目录新建一个.gitinit ...
操作系统MIT 6.S081 xv6内核(三):System calls实验
trace实验
trace目的
目的:完成一个trace功能 12345$ trace 32 grep hello README3: syscall read -> 10233: syscall read -> 9663: syscall read -> 703: syscall read -> 0
trace是一个追踪系统调用的功能,用于打印哪个进程号、调用什么系统调用函数、返回值是什么,trace
32 grep hello README的意思是在grep hello
README(在README中搜索hello),系统需要读入README文件,32代表追踪系统读文件调用情况。为什么32代表是追踪读呢,因为编号被定义在kernel/syscall.h中,每种系统调用对应一种编号,例如:
1#define SYS_read 5
而1<<SYS_read(1左移五位)正好就是32,如果追踪多个调用,就是把对应位置的二进制置1得到十进制。
具体实现
根据提示可以轻易完成前面部分:
- 在Makefile的UPROGS中添加$U/_ ...
操作系统MIT 6.S081 xv6内核(二):Util实验
sleep实验
123456789101112131415161718#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(int argc,const char *argv[]){ if(argc!=2){ printf("Please Input ./sleep <tiem>!\n"); exit(-1); } else{ int time = atoi(argv[1]); sleep(time); exit(0); }}
测试: 1./grade-lab-util sleep
pingpong实验
思路没什么问题,问题在于细节,例如pid_t pid =
fork()的位置要放在判断前,不要放前面初始化;此外%d: received pong。
123456789101112 ...
操作系统MIT 6.S081 xv6内核(一):环境搭建与Git使用
最近一直在寻找有关于系统的项目,偶然了解到了这个来自麻省理工大学2020年操作系统课程秋季项目,该项目虽然使用英文传授,但貌似很多前辈着手做了翻译和尝试,项目难度较大,lab设计也比较巧妙,总体评价还是不错的。以下是项目相关记录资料。
翻译课程链接:MIT
6.S081 2020 操作系统 [中英文字幕]
如果喜欢看文字,有大哥将课程所有内容整理出来了: github课程翻译
GitBook版本排版更加舒服:GitBook课程翻译
xv6 Book合实验手册:https://xv6.dgs.zone
环境配置
编程环境
Win10 SSH+虚拟机Ubuntu 18.04
虚拟机安装SSH服务: 1sudo apt-get install openssh-server 启用服务: 1sudo service ssh start 开机自启
1sudo systemctl enable ssh 关闭防火墙 1sudo ufw disable
使用Win终端工具XShell、mabaXterm、Vscode等进行SSH连接即可。
RISCV工具链环境
xv6是 ...
C/C++/Qt 修炼手册
C/C++是偏底层的高级程序涉及语言,有很多细节问题并不符合常规印象,该手册会用于持续记录C/C++各种奇形怪状的坑,也用于记录一些用到就被忘掉的接口函数,混杂一些业务八股。
C语言
C语言细节
char数组的初始化
12char ch[MAXSIZE]={0}; //这意味这每个字符都是'\0',而不是整数0//而不是char ch[MAXSIZE]={'0'} //这是0字符,ASCII码值为48,不是真正的初始化
%x和%p打印
%x用于打印十六进制数,一般接收unsigned int类型,输出没有0x,也不会补0;
%p也是打印16进制的(不是绝对),不过这里的16进制专门针对地址的16进制,也就是常说的指针,地址有多少位就输出多少位,高位补0,前缀带0x;
struct结构体
匿名结构体:即定义了结构体,也进行了实例化:
1234struct { struct buf buf[NBUF]; struct Hash_bcache[MAX_CBlock]; ...
解决Pjax导致Aplayer Js加载失败问题
Pjax是一款常用的插件,主要用于实现跳转不刷新网页实现某些事件的连续,例如本站使用了Pjax实现了音乐tag全站连续播放,其原理是通过不刷新网页的方式获取js资源,从而不会阻断连续事件的发生。但是pjax会引入比较大的问题,某些页面跳转时需要刷新加载的部件无法正常加载,例如评论模块、自建Aplayer等,只能手动刷新,导致每次在Music页选择完音乐,重新进入时无法获取正在播放的列表。
最常用的解决方法是:在每次pjax调用完成后,使用回调函数加载js资源,Aplayer列表确实不会丢失了,但是音乐却只能在当页播放,体验一般,本文提供了一种可行的方案,能够完美兼容Aplayer加载问题与Pjax调用问题,主要骨干是pjax回调函数初始化Aplayer,以及用于辅助记录Aplayer歌曲播放状态的函数。
建立一个Aplayer
Aplayer可以使用列表语法调用,也可以使用js调用,为了方便函数互调,使用了js语法,如:
1234567891011121314151617181920function BuildPlayer(){ globalPlayer ...
CDN加速
建站问题
部署小网站一般使用的是轻量级服务器,带宽和处理速度一般不高,所以加载时延比较高。如果是部署在平台上而非服务器,境外服务器(国外平台就是略为大方)的链接时延也会更高;另一方面,个人网站容易面临暴露ip的问题,尽管通过域名解析,但是信息交互都是本地的明文ip进行的,例如简单ping一下就可以得到,这也是CDN广为使用的原因。
CDN
内容分发网络(Content Delivery
Net,CDN)是一种网站常用的加速服务,利用距离用户最近、时延最低的服务器快速返回资源和响应,提高访问速度。其原理是在域名解析DNS————个人服务器ip之间插入了一个cdn套壳代理,访问目标网站时,DNS会首先将域名解析到cdn中,向cdn服务提供商服务器请求内容,如果这个内容早已以静态资源的方式存储于服务器,那么服务器就会返回该资源,而无需访问原始的低带宽服务器。
另一方面,CDN服务商尤其是大厂,通常有各种策略来提高CDN的返回效率,例如压缩静态资源、选取最优服务器路径、DNS解析路径等,因此能大大访问资源效率、同时也减小了原始服务器流量负载。
部署
采用的服务商是来自多吉云的融合 ...
数据结构算法题目(三):计算技巧方法
记录了一些原理简单、但是具体实现方式要想一想的问题。
手搓函数系列
不是所有设备都有C库函数,会手搓一部分C库是基本素养。
strlen:字符串长度
12345678int strlen(char *str){ int len = 0; while((*str)!='\0'){ //或(*str++)!='\0' len++; str++; } return len;}
strcpy:字符串复制函数
注意细节问题:
需要使用staddr保存起始地址,返回的也是该起始地址;
为什么要返回起始地址:其一是因为上述原因,需要起始地址,防止调用时没有保存起始地址;其二可以和其他函数嵌套使用,例如计算长度strlen(strcpy(dest,src));其三也方便进行错误检查。
1234567char* strcpy(char*dest,char*src){ if(src==NULL||dest==NULL) ...