xv6中创建syscall
xv6的启动过程大致可以分为BIOS->bootloader->kernel,三个环节,本小节主要讲述bootloader的相关内容。
BIOS的作用是将磁盘的第一个扇区的内容移入到地址为0x7c00的位置,然后把控制权交给这份内容。这一份内容就是bootloader。
bootloader由bootasm.S和bootmain.c组成,所以接下来主要分析这两个文件的代码。
bootasm.S
代码不算长,我们先贴上完整的代码:
bootasm.S
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687#include "asm.h"#include "memlayout.h"#include "mmu.h"# Start the firs ...
xv6系统启动——bootloader
我们以在xv6中添加一个date系统调用为例,介绍在xv6中添加系统调用的方法和原理。
date syscall介绍
date系统调用可以获取系统当前的UTC时间。
在我们完成date系统调用后,我们利用这个系统调用做一个小小的工具,可以打印当前的系统时间,工具代码如下:
date.c
123456789101112131415161718#include "types.h"#include "user.h"#include "date.h"intmain(int argc, char *argv[]){ struct rtcdate r; if (date(&r)) { printf(2, "date failed\n"); exit(); } // your code to print the time in any format you like... exit();}
变量r是我们获取到的时间,我们可以通过r打印我们想要的时间格 ...
ssh的原理
SSH是一种网络协议,用于计算机间的加密登录。
ssh保证安全的原理
SSH之所以能够保证安全,原因在于它采用了公钥加密。
整个过程是这样的:
远程主机收到用户的登录请求,把自己的公钥发给用户。
用户使用这个公钥,将登录密码加密后,发送回来。
远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
SSH协议是如何应对的呢?
如果你是第一次登录对方主机,系统会出现下面的提示:
$ ssh user@host
The authenticity of host ‘host ...
mapreduce简介
MapReduce是一个编程模型,用于处理和生成大数据。用户通过编写Map函数处理输入键值对生成中间键值对,通过编写Reduce函数来合并所有的中间键值对并生成结果。在我们的日常生活中,大部分的任务都可以被抽象成一个MapReduce模型,并通过这个模型解决问题。
MapReduce介绍
我们所遇到的大多数计算问题都很直观,但是当计算的数量十分庞大时,我们往往要借助于成百上千的机器共同计算来加速这个过程,但在从一个机器拓展到一个集群时我们会遇到比原来多得多的问题。比如我们该如何并行化计算,如何把数据分发到机器中,如何处理机器宕机带来的问题,毫无疑问,这是一个复杂的问题。
分布式的计算带来了各种各样复杂的问题,但MapReduce的出现给解决分布式计算带来了一个足够简洁的解决方案。
编程模型
整个计算过程接受一组输入键值对,并输出一组键值对。我们需要为这个计算过程提供两个函数,Map和Reduce。
Map函数接受一组键值对输入并生产一组中间键值对,然后按照一定的标准把这些键值对分组并传输给Reduce函数。
Reduce函数接受中间键值对作为输入,合并这些数据并产生一组键值对作为最 ...
C语言的内存模型
程序为什么要被编译器编译之后才可以运行
编译器在把C语言转换成机器码的过程中做了什么
最后编译出来的可执行文件里面是什么,除了机器码还有什么,是如何组织的
#include<stdio.h>是什么意思,这意味着什么,C语言库是如何实现的
不同编译器和不同硬件平台以及不同的操作系统,最终编译出来的结果相同吗,为什么
HelloWorld是如何运行起来的,操作系统如何装载它,它从哪开始,从哪结束
如果没有操作系统我们如何实现HelloWorld,我们需要什么,如何实现
printf是怎么实现的,它为什么可以有不定数量的参数,为什么最后可以在终端上输出字符串
HelloWorld程序运行时在内存中是怎么样的
C语言的编译过程
复习大一
https简述
在了解https之前,我们先来了解一下非对称加密。
非对称加密的数学原理
非对称加密,就是加密和解密用到的不是一个密钥,一般来说,我们用公钥加密,私钥解密。
下面我们来介绍非对称加密的数学原理,我们来举一个简单的例子:
15 ^ 2 mod 7 = 25 mod 7 = x
易知x = 4,然后,我们将x的位置切换
15 ^ x mod 7 = 4
我们通过枚举,似乎也可以得到答案,x = 2,但是如何模数字变得很大呢?
15 ^ x mod 56374677648 = 4
此时的计算量会变得非常巨大,即使是计算机也要花费数年的时间才能计算得出,我们可以认为这是无法计算的。
上面的计算我们可以认为就是将5(原文)加密成了4(密文),我们在已知x的情况下,很容易就可以加密,但是反之,我们在仅知道5(原文)和4(密文)的情况下,我们很难推出x的值,我们认为这是一个不可逆的过程。
那么,我们接下来把x分成p和q
15 ^ (p * q) mod 56374677648 = 4
也就是
1(原文) ^ (p * q) mod N = 密文
接下来,最重要的一步是结合欧拉公式,可以得到
12 ...
80386内存管理
80386转换逻辑地址到物理地址经过下面的两步:
段翻译,把一个逻辑地址(包含一个段选择子和段偏移量)转换成一个线性地址
页翻译,把一个线性地址准换成一个物理地址,这一步是可选的,取决于系统软件的设计者,在保护模式下段翻译是必须的而页翻译是可选的
这些转换对应用程序而言都是不可见的,下图描述了两种翻译的过程。
段翻译
下图展现了段翻译的细节,显示了处理器如何把一个逻辑地址转换成一个线性地址
为了执行段翻译,处理器需要使用下面这些数据结构
段描述符
段描述符表
段选择子
段寄存器
段描述符
段描述符提供了提供了段翻译所需要的数据,段段描述符由编译器,链接器,装载器或者操作系统创建,不能由应用程序编写者创建,下图是一个段段描述符的常见结构。
可以看到DPL之后的一位把段描述符分为了两种类型,第一种用于存放代码段和数据段,第二种用于系统段。
接下来解释一些比较重要的位:
BASE:由三个部分组成,表示4GB空间内段的位置。
LIMIT:指定了端的大小,由两部分组成了一个20位大小的数字。具体表示的大小还要根据G(granularity,粒度)位来决定。
G(granular ...
制作iso镜像文件
本教程会遵照El-Torito标准生成ISO文件。
编写内核文件
这里我们简单的写一个打印helloworld的汇编即可
12345678910111213141516171819202122#define print(x) movb $0x0E, %ah; \ movb $(x), %al; \ int $0x10.globl startstart: .code16 cli cld print('H') print('e') print('l') print('l') print('o') print(' ') print('W') print('o') print('r') print('l') print('d') ...
计算机网络笔记
1.2 因特网概述
网络,互联网和因特网
网络由若干节点和连接这些节点的链路组成
多个网络可以由路由器互连起来,这样就构成了范围更大的网络,即互联网
因特网是全球最大的计算机网络
因特网的组成
边缘部分
由所有连接在因特网上的主机组成
核心部分
由大量网络和连接这些网络的路由器组成
1.3 三种交换方式
lab-2(mit-6.828)
Exercise 1
要求完成的函数内容如下
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147static void *boot_alloc(uint32_t n){ static char *nextfree; // virtual address of next byte of free memory char *result; // Initialize nex ...