操作系统基础概念
操作系统(Operating System, OS)是计算机系统中最核心的系统软件,它充当硬件与用户之间的桥梁。操作系统的主要功能是管理计算机的硬件资源,并为应用程序提供运行环境。
操作系统的定义与作用
操作系统可以被定义为:
- 一组控制和管理计算机硬件与软件资源的程序
- 合理组织计算机工作流程的接口
- 为用户提供友好交互界面的软件系统
操作系统的作用主要体现在三个方面:
- 资源管理者:管理CPU、内存、磁盘、I/O设备等硬件资源
- 运行平台:为应用程序提供执行环境和系统调用接口
- 用户界面:提供命令行界面(CLI)或图形用户界面(GUI)
操作系统的发展历程
操作系统经历了几个重要发展阶段:
1. 手工操作阶段(1940s-1950s)
- 程序员直接在机器语言层面操作计算机
- 没有操作系统概念
- 资源利用率极低
2. 单道批处理系统(1950s-11960s)
- 引入作业控制语言(JCL)
- 自动依次处理作业队列
- 仍然存在CPU空闲问题
3. 多道批处理系统(1960s-1970s)
- 允许多个程序同时驻留在内存中
- CPU在程序间切换,提高利用率
- 代表性系统:IBM OS/360
4. 分时系统(1970s)
- 将CPU时间划分为时间片
- 多用户通过终端同时使用计算机
- 代表性系统:UNIX
5. 现代操作系统(1980s至今)
- 图形用户界面普及
- 网络功能集成
- 多核处理器支持
- 移动操作系统兴起
操作系统的基本特性
现代操作系统具有四个基本特性:
1. 并发性(Concurrency)
- 指两个或多个事件在同一时间间隔内发生
- 在多道程序环境下,宏观上同时运行,微观上交替执行
- 与并行(Parallelism)的区别:并行指在同一时刻发生
2. 共享性(Sharing)
- 系统资源被多个并发进程共同使用
- 互斥共享(如打印机)和同时访问(如磁盘文件)两种方式
3. 虚拟性(Virtualization)
- 通过技术手段将物理资源转化为逻辑资源
- 例如:虚拟内存、虚拟处理器
4. 异步性(Asynchronism)
- 进程执行顺序和执行时间不确定
- 但运行结果必须是可再现的
操作系统的体系结构
1. 宏内核(Monolithic Kernel)
- 所有核心功能都在内核空间实现
- 优点:性能高
- 缺点:代码复杂,难以维护
- 例子:Linux、UNIX
2. 微内核(Microkernel)
- 只保留最基本的功能(进程管理、内存管理、IPC)
- 其他功能作为用户态服务运行
- 优点:结构清晰,易于维护
- 缺点:性能开销较大
- 例子:MINIX、QNX
3. 混合内核(Hybrid Kernel)
- 结合宏内核和微内核的优点
- 例子:Windows NT
4. 外核(Exokernel)
- 提供最小化的抽象层
- 应用程序直接管理资源
- 主要用于研究领域
进程管理
进程是操作系统中最重要的概念之一,进程管理是操作系统的核心功能。
进程的基本概念
进程的定义:
- 进程是程序的一次执行实例
- 进程是资源分配和调度的基本单位
- 进程由程序段、数据段和进程控制块(PCB)组成
进程与程序的区别:
- 程序是静态的代码文件,进程是动态的执行实体
- 程序可以长期保存,进程有生命周期
- 一个程序可以对应多个进程(如多个浏览器窗口)
- 一个进程只能对应一个程序
进程的状态与转换
进程在其生命周期内会经历以下状态:
1. 就绪状态(Ready)
- 进程已获得除CPU之外的所有必要资源
- 只要获得CPU就可以立即执行
2. 执行状态(Running)
- 进程获得CPU,正在执行
- 单处理器系统中只有一个进程处于此状态
3. 阻塞状态(Blocked)
- 进程因等待某事件(如I/O完成)而暂停执行
- 即使CPU空闲,该进程也不能执行
4. 创建状态(New)
- 进程正在被创建,尚未完成初始化
5. 终止状态(Terminated)
- 进程执行完毕或被强制终止
状态转换图:
创建 → 就绪 ↔ 执行 → 终止
↓ ↑
阻塞
进程控制块(PCB)
PCB是操作系统用于管理进程的核心数据结构,包含以下信息:
1. 进程标识信息
- 进程ID(PID)
- 父进程ID(PPID)
- 用户ID(UID)
- 组ID(GID)
2. 处理器状态信息
- 通用寄存器值
- 程序计数器(PC)
- 然志寄存器(PSW)
- 栈指针
3. 进程调度信息
- 进程状态
- 优先级
- 调度队列指针
- 调度参数
4. 进程控制信息
- 程序和数据的内存地址
- 文件描述符表
- 进程间通信信息
- 资源使用情况
进程控制
操作系统通过系统调用提供进程控制功能:
1. 进程创建
#include <unistd.h>
pid_t fork(void);
// 示例:创建子进程
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid < 0) {
// 创建失败
perror("fork failed");
return 1;
} else if (pid == 0) {
// 子进程
printf("这是子进程,PID: %d\n", getpid());
return 0;
} else {
// 父进程
printf("这是父进程,PID: %d, 子进程PID: %d\n", getpid(), pid);
wait(NULL); // 等待子进程结束
return 0;
}
}
2. 进程终止
#include <stdlib.h>
void exit(int status);
// 正常终止
exit(0);
// 立即终止
_exit(0);
3. 进程等待
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
// 示例:等待特定子进程
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程
sleep(2);
printf("子进程完成\n");
exit(0);
} else {
// 父进程
int status;
pid_t child = waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("子进程%d正常退出,退出码:%d\n", child, WEXITSTATUS(status));
}
return 0;
}
}
4. 进程执行
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);
// 示例:执行外部程序
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程执行ls命令
execl("/bin/ls", "ls", "-l", NULL);
// 如果exec成功,下面代码不会执行
perror("exec failed");
exit(1);
} else {
wait(NULL);
return 0;
}
}
进程间通信(IPC)
进程间通信的主要方式:
1. 管道(Pipe)
#include <unistd.h>
int pipe(int pipefd[2]);
// 示例:父子进程通过管道通信
int main() {
int fd[2];
if (pipe(fd) == -1) {
perror("pipe");
return 1;
}
pid_t pid = fork();
if (pid == 0) {
// 子进程:写入数据
close(fd[0]); // 关闭读端
char msg[] = "Hello from child!";
write(fd[1], msg, sizeof(msg));
close(fd[1]);
} else {
// 父进程:读取数据
close(fd[1]); // 关闭写端
char buffer[128];
int n = read(fd[0], buffer, sizeof(buffer));
buffer[n] = '\0';
printf("父进程收到: %s\n", buffer);
close(fd[0]);
wait(NULL);
}
return 0;
}
2. 消息队列
#include <sys/msg.h>
#include <sys/ipc.h>
// 消息结构
struct msgbuf {
long mtype; // 消息类型
char mtext[100]; // 消息内容
};
// 创建/获取消息队列
int msgid = msgget(IPC_PRIVATE, 0666);
// 发送消息
struct msgbuf msg = {1, "Hello"};
msgsnd(msgid, &msg, sizeof(msg.mtext), 0);
// 接收消息
msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);
3. 共享内存
#include <sys/shm.h>
#include <sys/ipc.h>
// 创建共享内存
int shmid = shmget(IPC_PRIVATE, 1024, 0666);
char *shared = (char*)shmat(shmid, NULL, 0);
// 使用共享内存
strcpy(shared, "Shared data");
// 分离共享内存
shmdt(shared);
// 删除共享内存
shmctl(shmid, IPC_RMID, NULL);
4. 信号量
#include <sys/sem.h>
// 创建信号量集
int semid = semget(IPC_PRIVATE, 1, 0666);
// P操作(等待)
struct sembuf p = {0, -1, 0};
semop(semid, &p, 1);
// V操作(释放)
struct sembuf v = {0, 1, 0};
semop(semid, &v, 1);
5. 信号(Signal)
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handler(int signum) {
printf("捕获信号: %d\n", signum);
}
int main() {
// 注册信号处理函数
signal(SIGINT, handler);
printf("按Ctrl+C测试信号处理\n");
while(1) {
sleep(1);
}
return 0;
}
进程调度
进程调度算法的目标:
- CPU利用率最大化
- 公平性
- 响应时间最小化
- 周转时间最小化
- 吞吐量最大化
1. 先来先服务(FCFS)
# FCFS调度算法示例
def fcfs(processes):
# processes: [(到达时间, 执行时间, 进程名)]
processes.sort(key=lambda x: x[0]) # 按到达时间排序
current_time = 0
results = []
for arrival, burst, name in processes:
if current_time < arrival:
current_time = arrival
start_time = current_time
finish_time = start_time + burst
waiting_time = start_time - arrival
turnaround_time = finish_time - arrival
results.append({
'name': name,
'arrival': arrival,
'burst': burst,
'start': start_time,
'finish': finish_time,
'waiting': waiting_time,
'turnaround': turnaround_time
})
current_time = finish_time
return results
# 测试
processes = [(0, 7, 'P1'), (2, 4, 'P2'), (4, 1, 'P3')]
results = fcfs(processes)
for r in results:
print(f"{r['name']}: 等待={r['waiting']}, 周转={r['turnaround']}")
2. 短作业优先(SJF)
def sjf(processes):
# 非抢占式SJF
processes = sorted(processes, key=lambda x: x[0]) # 按到达时间排序
ready_queue = []
current_time = 0
results = []
completed = 0
while completed < len(processes):
# 添加到达的进程到就绪队列
for p in processes:
if p[0] <= current_time and p not in ready_queue and p not in [r[0] for r in results]:
ready_queue.append(p)
if not ready_queue:
current_time = min([p[0] for p in processes if p not in [r[0] for r in results]])
continue
# 选择最短作业
ready_queue.sort(key=lambda x: x[1])
current = ready_queue.pop(0)
start_time = current_time
finish_time = start_time + current[1]
waiting_time = start_time - current[0]
turnaround_time = finish_time - current[0]
results.append((current, {
'name': current[2],
'waiting': waiting_time,
'turnaround': turnaround_time
}))
current_time = finish_time
completed += 1
return results
3. 时间片轮转(RR)
def rr(processes, time_quantum):
# processes: [(到达时间, 执行时间, 进程名)]
from collections import deque
processes = sorted(processes, key=lambda x: x[0])
queue = deque()
current_time = 0
results = {}
remaining = {p[2]: p[1] for p in processes}
completed = 0
i = 0
while completed < len(processes):
# 添加新到达的进程
while i < len(processes) and processes[i][0] <= current_time:
queue.append(processes[i])
i += 1
if not queue:
current_time = processes[i][0]
continue
current = queue.popleft()
name = current[2]
if remaining[name] > time_quantum:
# 执行一个时间片
current_time += time_quantum
remaining[name] -= time_quantum
# 添加新到达的进程
while i < len(processes) and processes[i][0] <= current_time:
queue.append(processes[i])
i += 1
queue.append(current)
else:
# 完成执行
current_time += remaining[name]
remaining[name] = 0
results[name] = {
'finish': current_time,
'turnaround': current_time - current[0],
'waiting': current_time - current[0] - current[1]
}
completed += 1
return results
4. 优先级调度
def priority_scheduling(processes):
# 非抢占式优先级调度
# processes: [(到达时间, 执行时间, 优先级, 进程名)]
processes = sorted(processes, key=lambda x: x[0])
ready_queue = []
current_time = 0
results = []
completed = 0
while completed < len(processes):
# 添加到达的进程
for p in processes:
if p[0] <= current_time and p not in ready_queue and p not in [r[0] for r in results]:
ready_queue.append(p)
if not ready_queue:
current_time = min([p[0] for p in processes if p not in [r[0] for r in results]])
continue
# 选择优先级最高的(数值越小优先级越高)
ready_queue.sort(key=lambda x: x[2])
current = ready_queue.pop(0)
start_time = current_time
finish_time = start_time + current[1]
waiting_time = start_time - current[0]
turnaround_time = finish_time - current[0]
results.append((current, {
'name': current[3],
'waiting': waiting_time,
'turnaround': turnaround_time
}))
current_time = finish_time
completed += 1
return results
5. 多级反馈队列(MLFQ)
def mlfq(processes, time_quantums=[2, 4, 8]):
# 多级反馈队列
# processes: [(到达时间, 执行时间, 进程名)]
from collections import deque
queues = [deque() for _ in range(len(time_quantums))]
current_time = 0
results = {}
remaining = {p[2]: p[1] for p in processes}
current_queue = 0
completed = 0
i = 0
while completed < len(processes):
# 添加新到达的进程到最高优先级队列
while i < len(processes) and processes[i][0] <= current_time:
queues[0].append(processes[i])
i += 1
# 找到非空队列
current_queue = 0
while current_queue < len(queues) and not queues[current_queue]:
current_queue += 1
if current_queue >= len(queues):
if i < len(processes):
current_time = processes[i][0]
else:
break
continue
current = queues[current_queue].popleft()
name = current[2]
tq = time_quantums[current_queue]
if remaining[name] > tq:
# 执行一个时间片
current_time += tq
remaining[name] -= tq
# 添加新到达的进程
while i < len(processes) and processes[i][0] <= current_time:
queues[0].append(processes[i])
i += 1
# 降级到下一级队列
next_queue = min(current_queue + 1, len(queues) - 1)
queues[next_queue].append(current)
else:
# 完成执行
current_time += remaining[name]
remaining[name] = 0
results[name] = {
'finish': current_time,
'turnaround': current_time - current[0],
'waiting': current_time - current[0] - current[1]
}
completed += 1
return results
内存管理
内存管理是操作系统的核心功能之一,负责管理计算机的主存储器资源。
内存管理的基本概念
内存管理的目标:
- 内存分配与回收
- 地址转换与重定位
- 内存保护与共享
- 内存扩充
地址空间:
- 逻辑地址(虚拟地址):程序看到的地址空间
- 物理地址:内存硬件的实际地址
- 地址转换:将逻辑地址转换为物理地址
连续内存分配
1. 单一连续分配
- 内存分为系统区和用户区
- 仅支持单道程序
- 实现简单,但资源利用率低
2. 固定分区分配
- 将内存划分为若干固定大小的分区
- 每个分区只能装入一道作业
- 存在内部碎片(分区内部未使用的空间)
3. 动态分区分配
- 根据进程实际需求动态划分内存
- 常用算法:
- 首次适应(First Fit)
- 最佳适应(Best Fit)
- 最坏适应(Worst Fit)
// 动态分区分配的首次适应算法示例
#include <stdio.h>
#include <stdlib.h>
typedef struct Block {
int size;
int start;
int allocated;
struct Block *next;
} Block;
Block* create_memory(int size) {
Block *mem = (Block*)malloc(sizeof(Block));
mem->size = size;
mem->start = 0;
mem->allocated = 0;
mem->next = NULL;
return mem;
}
void* first_fit(Block *memory, int size) {
Block *current = memory;
while (current != NULL) {
if (!current->allocated && current->size >= size) {
// 分裂块
if (current->size > size) {
Block *new_block = (Block*)malloc(sizeof(Block));
new_block->size = current->size - size;
new_block->start = current->start + size;
new_block->allocated = 0;
new_block->next = current->next;
current->next = new_block;
}
current->size = size;
current->allocated = 1;
return (void*)(current->start);
}
current = current->next;
}
return NULL;
}
void deallocate(Block *memory, void *addr) {
int target_start = (int)addr;
Block *current = memory;
Block *prev = NULL;
while (current != NULL) {
if (current->start == target_start && current->allocated) {
current->allocated = 0;
// 合并相邻空闲块
if (current->next && !current->next->allocated) {
current->size += current->next->size;
Block *temp = current->next;
current->next = temp->next;
free(temp);
}
if (prev && !prev->allocated) {
prev->size += current->size;
prev->next = current->next;
free(current);
}
return;
}
prev = current;
current = current->next;
}
}
分页存储管理
基本概念:
- 将物理内存划分为固定大小的块,称为页框(Frame)
- 将逻辑地址空间划分为同样大小的块,称为页(Page)
- 通过页表实现逻辑地址到物理地址的映射
页表结构:
逻辑地址:[页号 | 页内偏移]
↓
页表:[页号 → 页框号]
↓
物理地址:[页框号 | 页内偏移]
多级页表:
// 二级页表示例
#define PAGE_SIZE 4096
#define PAGE_TABLE_SIZE 1024
#define OFFSET_BITS 12
#define PAGE_BITS 10
// 页表项结构
typedef struct {
unsigned int frame : 20; // 页框号
unsigned int valid : 1; // 有效位
unsigned int dirty : 1; // 脏位
unsigned int accessed : 1; // 访问位
} PageTableEntry;
// 二级页表
typedef struct {
PageTableEntry **entries; // 指向一级页表的指针数组
} PageDirectory;
// 地址转换函数
unsigned int translate_address(PageDirectory *dir, unsigned int virtual_addr) {
unsigned int page_dir_index = (virtual_addr >> (PAGE_BITS + OFFSET_BITS)) & 0x3FF;
unsigned int page_table_index = (virtual_addr >> OFFSET_BITS) & 0x3FF;
unsigned int offset = virtual_addr & 0xFFF;
if (!dir->entries[page_dir_index] ||
!dir->entries[page_dir_index][page_table_index].valid) {
return -1; // 页错误
}
unsigned int frame = dir->entries[page_dir_index][page_table_index].frame;
return (frame << OFFSET_BITS) | offset;
}
分段存储管理
基本概念:
- 按程序的逻辑结构划分内存
- 每个段有特定含义(代码段、数据段、栈段等)
- 支持共享和保护
段表结构:
逻辑地址:[段号 | 段内偏移]
↓
段表:[段号 → 段基址, 段限长]
↓
物理地址:[段基址 + 段内偏移](需检查是否越界)
段页式存储管理
结合分段和分页的优点:
- 先分段,段内再分页
- 逻辑地址:[段号 | 段内页号 | 页内偏移]
- 需要段表和页表两级映射
虚拟内存
基本概念:
- 逻辑地址空间远大于物理内存
- 程序运行时,只将当前需要的部分装入内存
- 其余部分保存在磁盘的交换区(Swap)
虚拟内存的实现:
- 请求调页:访问未装入内存的页时触发缺页中断
- 页面置换:当内存不足时,选择页面换出
- 页面共享:多个进程共享只读页面
缺页中断处理流程:
// 伪代码:缺页中断处理
void page_fault_handler(unsigned int virtual_addr) {
// 1. 获取页表项
PageTableEntry *pte = get_page_table_entry(virtual_addr);
if (!pte->valid) {
// 2. 检查访问权限
if (!check_permission(virtual_addr)) {
kill_process(); // 访问违规
return;
}
// 3. 分配物理页框
unsigned int frame = allocate_frame();
if (frame == -1) {
// 4. 页面置换
frame = swap_out();
}
// 5. 从磁盘读取页面
read_from_disk(pte->disk_location, frame);
// 6. 更新页表
pte->frame = frame;
pte->valid = 1;
pte->accessed = 1;
}
// 7. 重新执行指令
resume_execution();
}
页面置换算法
1. 最佳置换(OPT)
def opt(page_references, frame_count):
# 理想算法,实际无法实现
# 选择未来最长时间不会被访问的页面替换
frames = []
faults = 0
for i, page in enumerate(page_references):
if page not in frames:
if len(frames) < frame_count:
frames.append(page)
else:
# 找到未来最远使用的页面
future_use = {}
for f in frames:
try:
future_use[f] = page_references[i:].index(f)
except ValueError:
future_use[f] = float('inf')
to_replace = max(future_use, key=future_use.get)
frames[frames.index(to_replace)] = page
faults += 1
return faults
2. 先进先出(FIFO)
def fifo(page_references, frame_count):
from collections import deque
frames = deque(maxlen=frame_count)
faults = 0
for page in page_references:
if page not in frames:
frames.append(page)
faults += 1
return faults
3. 最近最少使用(LRU)
def lru(page_references, frame_count):
from collections import OrderedDict
frames = OrderedDict()
faults = 0
for page in page_references:
if page in frames:
# 访问过,移到末尾
frames.move_to_end(page)
else:
if len(frames) < frame_count:
frames[page] = True
else:
# 弹出最久未使用的(第一个)
frames.popitem(last=False)
frames[page] = True
faults += 1
return faults
4. 时钟算法(Clock)
def clock(page_references, frame_count):
frames = []
reference_bits = []
pointer = 0
faults = 0
for page in page_references:
if page in frames:
# 设置引用位
idx = frames.index(page)
reference_bits[idx] = 1
else:
if len(frames) < frame_count:
frames.append(page)
reference_bits.append(1)
else:
# 查找引用位为0的页面
while reference_bits[pointer] == 1:
reference_bits[pointer] = 0
pointer = (pointer + 1) % frame_count
frames[pointer] = page
reference_bits[pointer] = 1
pointer = (pointer + 1) % frame_count
faults += 1
return faults
内存保护与共享
内存保护机制:
// 页表项中的保护位示例
typedef struct {
unsigned int frame : 20;
unsigned int valid : 1;
unsigned int read : 1; // 读权限
unsigned int write : 1; // 写权限
unsigned int execute : 1; // 执行权限
unsigned int user : 1; // 用户/内核模式
} ProtectionEntry;
// 检查访问权限
int check_permission(unsigned int virtual_addr, int is_write, int is_user) {
PageTableEntry *pte = get_page_table_entry(virtual_addr);
if (!pte->valid) return 0;
if (is_user && !pte->user) return 0; // 用户不能访问内核空间
if (is_write && !pte->write) return 0; // 写保护
if (!pte->read) return 0; // 无读权限
return 1;
}
内存共享:
// 共享内存实现
struct SharedMemory {
int shmid;
void *addr;
int ref_count;
char key[256];
};
// 映射共享内存到进程地址空间
void* map_shared_memory(const char *key, size_t size) {
// 1. 创建或获取共享内存段
int shmid = shmget(ftok(key, 1), size, IPC_CREAT | 0666);
// 2. 附加到进程地址空间
void *addr = shmat(shmid, NULL, 0);
// 3. 更新引用计数
update_ref_count(key, 1);
return addr;
}
文件系统
文件系统是操作系统用于组织、存储和管理数据的机制。
文件的基本概念
文件的定义:
- 具有符号名的一组相关元素的有序序列
- 文件系统中的基本存储单位
- 包含数据、元数据和属性
文件属性:
- 文件名
- 文件类型(普通文件、目录文件、设备文件等)
- 文件大小
- 创建/修改/访问时间
- 权限(读、写、执行)
- 所有者信息
文件结构
1. 无结构文件(流式文件)
- 数据是一串字节流
- 例如:Unix/Linux中的文件
- 优点:灵活,用户自行解释结构
2. 记录式文件(结构文件)
- 由固定或可变长度的记录组成
- 例如:数据库文件
- 记录是存取的基本单位
文件目录结构
1. 单级目录
- 所有文件在同一目录下
- 简单但不允许重名
2. 两级目录
- 每个用户有自己的目录
- 解决了重名问题
3. 树形目录
- 层次化结构,支持嵌套
- 路径名:/usr/local/bin/ls
- 当前目录:工作目录
4. 无环图目录
- 支持链接(硬链接、软链接)
- 允许共享
文件系统层次结构
用户接口层
↓
文件系统接口层
↓
基本文件系统层(缓冲区管理)
↓
设备组织层(I/O调度)
↓
设备接口层
文件存储空间管理
1. 空闲表法
// 空闲表结构
struct FreeBlock {
int start_block;
int length;
struct FreeBlock *next;
};
// 分配连续空间
int allocate_contiguous(struct FreeBlock **free_list, int size) {
struct FreeBlock *current = *free_list;
struct FreeBlock *prev = NULL;
while (current) {
if (current->length >= size) {
int allocated_start = current->start_block;
current->start_block += size;
current->length -= size;
if (current->length == 0) {
if (prev) prev->next = current->next;
else *free_list = current->next;
free(current);
}
return allocated_start;
}
prev = current;
current = current->next;
}
return -1; // 空间不足
}
2. 位图法
// 位图表示例
#define BITMAP_SIZE 1024
unsigned char bitmap[BITMAP_SIZE]; // 每位表示一个块
// 查找连续的空闲块
int find_free_blocks(int count) {
for (int i = 0; i < BITMAP_SIZE; i++) {
if (bitmap[i] != 0xFF) { // 有空闲位
for (int bit = 0; bit < 8; bit++) {
if (!(bitmap[i] & (1 << bit))) {
// 检查后续块
int start = i * 8 + bit;
int free_count = 0;
for (int j = 0; j < count && start + j < BITMAP_SIZE * 8; j++) {
int byte = (start + j) / 8;
int b = (start + j) % 8;
if (!(bitmap[byte] & (1 << b))) free_count++;
else break;
}
if (free_count >= count) return start;
}
}
}
}
return -1;
}
// 分配块
void allocate_blocks(int start, int count) {
for (int i = 0; i < count; i++) {
int byte = (start + i) / 8;
int bit = (start + i) % 8;
bitmap[byte] |= (1 << bit);
}
}
3. 成组链接法(Unix)
// 超级块结构
struct SuperBlock {
int s_nfree; // 空闲块数量
int s_free[100]; // 空闲块索引表
// 其他元数据...
};
// 分配空闲块
int allocate_block(struct SuperBlock *sb, int device) {
if (sb->s_nfree <= 0) return -1;
int block = sb->s_free[--sb->s_nfree];
if (sb->s_nfree == 0) {
// 读取下一个索引块
read_block(device, sb->s_free[0], (char*)sb->s_free);
sb->s_nfree = sb->s_free[0];
}
return block;
}
文件分配方法
1. 连续分配
// 目录项结构
struct DirectoryEntry {
char name[256];
int start_block;
int length;
// 其他属性...
};
// 读取文件
void read_file_contiguous(struct DirectoryEntry *entry, char *buffer) {
read_blocks(entry->start_block, entry->length, buffer);
}
2. 链接分配
// 索引块结构
struct IndexBlock {
int pointers[128]; // 指向数据块
};
// 读取文件
void read_file_linked(int start_block, char *buffer) {
int current = start_block;
int offset = 0;
while (current != -1) {
read_block(current, buffer + offset);
offset += BLOCK_SIZE;
// 读取下一个块号
int next;
read_block(current, (char*)&next);
current = next;
}
}
3. 索引分配
// Unix inode结构
struct inode {
int i_mode; // 文件类型和权限
int i_nlink; // 硬链接数
int i_size; // 文件大小
int i_blocks; // 占用块数
int i_block[15]; // 直接/间接索引块
// 其他元数据...
};
// 读取文件数据块
int get_data_block(struct inode *inode, int logical_block) {
if (logical_block < 12) {
// 直接索引
return inode->i_block[logical_block];
} else if (logical_block < 12 + 128) {
// 一级间接索引
int indirect_block = inode->i_block[12];
int index = logical_block - 12;
int block;
read_block(indirect_block, (char*)&block + index * sizeof(int));
return block;
} else if (logical_block < 12 + 128 + 128 * 128) {
// 二级间接索引
int indirect_block = inode->i_block[13];
int index1 = (logical_block - 12 - 128) / 128;
int index2 = (logical_block - 12 - 128) % 128;
int block1;
read_block(indirect_block, (char*)&block1 + index1 * sizeof(int));
int block2;
read_block(block1, (char*)&block2 + index2 * sizeof(int));
return block2;
}
return -1;
}
文件系统实现
1. 文件系统层次结构
// 文件系统结构
struct FileSystem {
struct SuperBlock *superblock;
struct inode *inode_table;
struct FileDescriptor *fd_table;
// 其他组件...
};
// 打开文件
int open(const char *pathname, int flags) {
// 1. 路径解析
struct inode *dir_inode = resolve_path(pathname);
// 2. 查找文件
struct inode *file_inode = find_entry(dir_inode, basename(pathname));
if (!file_inode && (flags & O_CREAT)) {
// 创建文件
file_inode = create_file(dir_inode, basename(pathname));
}
if (!file_inode) return -1;
// 3. 检查权限
if (!check_permission(file_inode, flags)) return -1;
// 4. 分配文件描述符
int fd = allocate_fd();
file_table[fd].inode = file_inode;
file_table[fd].flags = flags;
file_table[fd].offset = 0;
return fd;
}
2. 缓冲区管理
// 缓冲区头
struct Buffer {
int block_number;
int device;
int dirty; // 是否被修改
int valid; // 数据是否有效
char data[512];
struct Buffer *next;
struct Buffer *prev;
};
// 缓冲区队列
struct Buffer *cache_head = NULL;
struct Buffer *cache_tail = NULL;
// 缓冲区查找
struct Buffer* get_block(int device, int block) {
// 查找缓存
struct Buffer *bp = cache_head;
while (bp) {
if (bp->device == device && bp->block_number == block) {
// 移到链表头部(LRU)
remove_from_list(bp);
add_to_head(bp);
return bp;
}
bp = bp->next;
}
// 缓存未命中,从磁盘读取
bp = allocate_buffer();
read_from_disk(device, block, bp->data);
bp->device = device;
bp->block_number = block;
bp->valid = 1;
// 添加到缓存
add_to_head(bp);
return bp;
}
文件系统操作
1. 文件读写
// 读取文件
ssize_t read(int fd, void *buf, size_t count) {
struct FileDescriptor *fildes = &file_table[fd];
struct inode *inode = fildes->inode;
if (!(fildes->flags & O_RDONLY)) return -1;
size_t bytes_read = 0;
size_t remaining = count;
while (remaining > 0 && fildes->offset < inode->i_size) {
// 计算逻辑块号和块内偏移
int logical_block = fildes->offset / BLOCK_SIZE;
int block_offset = fildes->offset % BLOCK_SIZE;
// 获取物理块号
int physical_block = get_data_block(inode, logical_block);
if (physical_block == -1) break;
// 读取块
struct Buffer *bp = get_block(inode->i_dev, physical_block);
// 复制数据
int to_copy = min(BLOCK_SIZE - block_offset, remaining);
to_copy = min(to_copy, inode->i_size - fildes->offset);
memcpy(buf + bytes_read, bp->data + block_offset, to_copy);
bytes_read += to_copy;
remaining -= to_copy;
fildes->offset += to_copy;
}
return bytes_read;
}
// 写入文件
ssize_t write(int fd, const void *buf, size_t count) {
struct FileDescriptor *fildes = &file_table[fd];
struct inode *inode = fildes->inode;
if (!(fildes->flags & O_WRONLY)) return -1;
size_t bytes_written = 0;
size_t remaining = count;
while (remaining > 0) {
int logical_block = fildes->offset / BLOCK_SIZE;
int block_offset = fildes->offset % BLOCK_SIZE;
// 获取或分配物理块
int physical_block = get_data_block(inode, logical_block);
if (physical_block == -1) {
physical_block = allocate_block(inode);
if (physical_block == -1) break;
}
struct Buffer *bp = get_block(inode->i_dev, physical_block);
int to_copy = min(BLOCK_SIZE - block_offset, remaining);
memcpy(bp->data + block_offset, buf + bytes_written, to_copy);
bp->dirty = 1;
bytes_written += to_copy;
remaining -= to_copy;
fildes->offset += to_copy;
if (fildes->offset > inode->i_size) {
inode->i_size = fildes->offset;
inode->i_dirty = 1;
}
}
return bytes_written;
}
2. 目录操作
// 目录项结构
struct dir_entry {
int inode;
char name[256];
};
// 创建目录
int mkdir(const char *pathname, mode_t mode) {
// 1. 解析父目录
char parent_path[PATH_MAX];
char dir_name[NAME_MAX];
split_path(pathname, parent_path, dir_name);
struct inode *parent = resolve_path(parent_path);
if (!parent) return -1;
// 2. 检查是否已存在
if (find_entry(parent, dir_name)) return -1;
// 3. 分配新inode
struct inode *new_inode = allocate_inode();
new_inode->i_mode = S_IFDIR | mode;
new_inode->i_nlink = 1;
// 4. 创建"."和".."条目
struct dir_entry dot = {new_inode->i_ino, "."};
struct dir_entry dotdot = {parent->i_ino, ".."};
write(new_inode, &dot, sizeof(dot));
write(new_inode, &dotdot, sizeof(dotdot));
// 5. 添加到父目录
struct dir_entry entry = {new_inode->i_ino, dir_name};
write(parent, &entry, sizeof(entry));
parent->i_nlink++; // 增加父目录链接计数
return 0;
}
3. 链接操作
// 创建硬链接
int link(const char *oldpath, const char *newpath) {
struct inode *old_inode = resolve_path(oldpath);
if (!old_inode) return -1;
// 不能链接目录(防止循环)
if (S_ISDIR(old_inode->i_mode)) return -1;
char parent_path[PATH_MAX];
char new_name[NAME_MAX];
split_path(newpath, parent_path, new_name);
struct inode *parent = resolve_path(parent_path);
if (!parent) return -1;
// 添加目录项
struct dir_entry entry = {old_inode->i_ino, new_name};
write(parent, &entry, sizeof(entry));
// 增加链接计数
old_inode->i_nlink++;
return 0;
}
// 创建符号链接
int symlink(const char *target, const char *linkpath) {
// 创建一个特殊文件,内容是目标路径
int fd = creat(linkpath, 0777);
if (fd < 0) return -1;
write(fd, target, strlen(target));
close(fd);
// 设置特殊类型
struct inode *inode = resolve_path(linkpath);
inode->i_mode = S_IFLNK | 0777;
return 0;
}
文件系统挂载
// 挂载表结构
struct Mount {
char device[256];
char mount_point[256];
struct FileSystem *fs;
struct Mount *next;
};
struct Mount *mount_table = NULL;
// 挂载文件系统
int mount(const char *device, const char *mount_point, const char *fs_type) {
// 1. 查找挂载点
struct inode *mp_inode = resolve_path(mount_point);
if (!mp_inode || !S_ISDIR(mp_inode->i_mode)) return -1;
// 2. 读取设备超级块
struct SuperBlock *sb = read_superblock(device);
if (!sb) return -1;
// 3. 创建挂载项
struct Mount *mnt = malloc(sizeof(struct Mount));
strcpy(mnt->device, device);
strcpy(mnt->mount_point, mount_point);
mnt->fs = init_filesystem(sb, device);
// 4. 添加到挂载表
mnt->next = mount_table;
mount_table = mnt;
return 0;
}
// 路径解析
struct inode* resolve_path(const char *pathname) {
if (pathname[0] == '/') {
// 绝对路径,从根目录开始
current = root_inode;
} else {
// 相对路径,从当前目录开始
current = current_inode;
}
char path[PATH_MAX];
strcpy(path, pathname);
char *token = strtok(path, "/");
while (token) {
// 检查是否挂载点
struct Mount *mnt = find_mount(token);
if (mnt) {
current = mnt->fs->root_inode;
} else {
current = find_entry(current, token);
}
if (!current) return NULL;
token = strtok(NULL, "/");
}
return current;
}
设备管理
设备管理负责管理计算机的外部设备,包括输入输出设备、存储设备等。
设备分类
1. 按传输速率分类
- 低速设备:键盘、鼠标(几B/s ~ 几KB/s)
- 中速设备:打印机、扫描仪(几KB/s ~ 几百KB/s)
- 高速设备:磁盘、光盘、网卡(几MB/s ~ 几GB/s)
2. 按信息组织分类
- 字符设备:以字符为单位(如终端、打印机)
- 块设备:以数据块为单位(如磁盘、光盘)
3. 按共享特性分类
- 独占设备:只能由一个进程使用(如打印机)
- 共享设备:可由多个进程同时使用(如磁盘)
- 虚拟设备:通过SPOOLing技术实现共享
I/O系统层次结构
用户进程
↓
设备无关OS软件
↓
设备驱动程序
↓
中断处理程序
↓
硬件
I/O控制方式
1. 程序I/O(轮询)
// 轮询方式读取键盘输入
char poll_keyboard() {
while (!keyboard_ready()) {
// 忙等待
;
}
return keyboard_data();
}
2. 中断驱动I/O
// 中断处理程序
void keyboard_isr() {
char ch = inb(KEYBOARD_DATA_PORT);
// 保存到缓冲区
kb_buffer[kb_head++] = ch;
kb_head %= KB_BUFFER_SIZE;
}
// 读取函数
char read_keyboard() {
while (kb_head == kb_tail) {
// 等待中断
sleep();
}
char ch = kb_buffer[kb_tail++];
kb_tail %= KB_BUFFER_SIZE;
return ch;
}
3. DMA方式
// DMA控制器结构
struct DMAController {
unsigned int channel;
unsigned int address;
unsigned int count;
unsigned int mode;
};
// 设置DMA传输
void setup_dma(void *buffer, int size, int direction) {
struct DMAController *dma = DMA_BASE;
outb(dma->channel | 0x04, DMA_CMD); // 禁用通道
outb(dma->channel | 0x00, DMA_MODE); // 设置模式
// 传输地址
outb((unsigned int)buffer & 0xFF, DMA_ADDR(dma->channel));
outb(((unsigned int)buffer >> 8) & 0xFF, DMA_ADDR(dma->channel));
outb(((unsigned int)buffer >> 16) & 0xFF, DMA_ADDR(dma->channel));
// 传输计数
outb((size - 1) & 0xFF, DMA_COUNT(dma->channel));
outb(((size - 1) >> 8) & 0xFF, DMA_COUNT(dma->channel));
outb(dma->channel, DMA_CMD); // 启用通道
}
I/O子系统
1. I/O调度
// I/O请求队列
struct IORequest {
int device;
int block;
void *buffer;
int direction; // 0=读, 1=写
int priority;
struct IORequest *next;
};
// 电梯算法(SCAN)
void schedule_io(struct IORequest **queue) {
if (!*queue) return;
// 按设备和块号排序
struct IORequest *current = *queue;
struct IORequest *sorted = NULL;
while (current) {
struct IORequest *next = current->next;
// 插入排序
if (!sorted || current->block < sorted->block) {
current->next = sorted;
sorted = current;
} else {
struct IORequest *temp = sorted;
while (temp->next && temp->next->block < current->block) {
temp = temp->next;
}
current->next = temp->next;
temp->next = current;
}
current = next;
}
*queue = sorted;
}
2. 缓冲区管理
// 双缓冲区
struct DoubleBuffer {
char buffer1[BLOCK_SIZE];
char buffer2[BLOCK_SIZE];
int active; // 当前活动缓冲区
int ready; // 就绪缓冲区
};
// 双缓冲读取
void read_with_double_buffer(struct DoubleBuffer *db, int device, int block) {
// 启动DMA到buffer1
setup_dma(db->buffer1, BLOCK_SIZE, READ);
start_device(device);
while (1) {
// 等待buffer1填满
wait_for_completion();
// 同时启动DMA到buffer2
setup_dma(db->buffer2, BLOCK_SIZE, READ);
start_device(device);
// 处理buffer1
process_data(db->buffer1);
// 等待buffer2填满
wait_for_completion();
// 同时启动DMA到buffer1
setup_dma(db->buffer1, BLOCK_SIZE, READ);
start_device(device);
// 处理buffer2
process_data(db->buffer2);
}
}
设备驱动程序
1. 设备驱动框架
// 设备驱动结构
struct DeviceDriver {
char name[32];
int (*init)(void);
int (*open)(int minor);
int (*read)(int minor, void *buf, int count);
int (*write)(int minor, const void *buf, int count);
int (*ioctl)(int minor, int cmd, void *arg);
int (*close)(int minor);
};
// 字符设备驱动示例:虚拟终端
struct tty_driver {
struct DeviceDriver base;
// 特定数据...
};
int tty_read(int minor, void *buf, int count) {
struct tty_struct *tty = &tty_table[minor];
// 从输入队列读取
while (tty->read_buf_count == 0) {
sleep_on(&tty->read_wait);
}
int n = min(count, tty->read_buf_count);
memcpy(buf, tty->read_buf, n);
// 移动剩余数据
memmove(tty->read_buf, tty->read_buf + n, tty->read_buf_count - n);
tty->read_buf_count -= n;
return n;
}
int tty_write(int minor, const void *buf, int count) {
struct tty_struct *tty = &tty_table[minor];
const char *p = buf;
for (int i = 0; i < count; i++) {
// 输出到硬件
outb(tty->io_base, *p++);
// 处理特殊字符
if (*p == '\n') outb(tty->io_base, '\r');
}
return count;
}
2. 块设备驱动
// 磁盘驱动示例
struct disk_device {
int io_base;
int irq;
int cylinders;
int heads;
int sectors;
};
// 磁盘读取
int disk_read(struct disk_device *disk, int sector, void *buffer, int count) {
// 等待磁盘就绪
while (inb(disk->io_base + 7) & 0x80);
// 选择驱动器和磁头
outb(disk->io_base + 6, 0xA0 | (disk->heads > 8 ? 0x10 : 0) | ((sector / disk->sectors) & 0x0F));
// 设置扇区数
outb(disk->io_base + 2, count);
// 设置LBA地址
outb(disk->io_base + 3, sector & 0xFF);
outb(disk->io_base + 4, (sector >> 8) & 0xFF);
outb(disk->io_base + 5, (sector >> 16) & 0xFF);
// 发送读命令
outb(disk->io_base + 7, 0x20);
// 读取数据
for (int i = 0; i < count * 256; i++) {
// 等待数据就绪
while (!(inb(disk->io_base + 7) & 0x08));
// 读取16位数据
unsigned short data = inw(disk->io_base);
((unsigned short*)buffer)[i] = data;
}
return count;
}
SPOOLing技术
假脱机系统:
// SPOOLing目录结构
struct SPOOL {
char device[32];
int active; // 是否激活
// 输入井和输出井
char input井[井大小];
char output井[井大小];
};
// 打印机SPOOLing
void spool_print(const char *data, int len) {
// 1. 将数据写入输出井
char filename[256];
sprintf(filename, "/spool/printer/%d", get_unique_id());
int fd = open(filename, O_CREAT | O_WRONLY);
write(fd, data, len);
close(fd);
// 2. 如果打印机空闲,启动打印进程
if (!printer_busy) {
pid_t pid = fork();
if (pid == 0) {
// 打印守护进程
print_daemon();
exit(0);
}
}
}
void print_daemon() {
while (1) {
// 扫描输出井
char *file = find_next_spool_file("/spool/printer");
if (!file) break;
// 读取并打印
int fd = open(file, O_RDONLY);
char buffer[4096];
int n;
while ((n = read(fd, buffer, sizeof(buffer))) > 0) {
// 发送到打印机
write_to_printer(buffer, n);
}
close(fd);
// 删除已完成的作业
unlink(file);
}
}
设备无关性
1. 设备文件
// 设备文件结构
struct dev_t {
unsigned int major; // 主设备号(驱动类型)
unsigned int minor; // 次设备号(具体设备)
};
// 设备文件操作
int device_open(const char *path, int flags) {
struct stat st;
if (stat(path, &st) < 0) return -1;
if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
return -1; // 不是设备文件
}
dev_t dev = st.st_rdev;
struct DeviceDriver *driver = get_driver(major(dev));
if (!driver) return -1;
return driver->open(minor(dev));
}
2. 缓冲区缓存
// 块设备缓存
struct buffer_cache {
int device;
int block;
int valid;
int dirty;
char data[BLOCK_SIZE];
struct buffer_cache *next;
struct buffer_cache *prev;
};
// 缓存查找
struct buffer_cache* get_buffer(int device, int block) {
// 查找缓存
struct buffer_cache *bp = find_in_cache(device, block);
if (bp) return bp;
// 缓存未命中
bp = allocate_buffer();
read_from_device(device, block, bp->data);
bp->device = device;
bp->block = block;
bp->valid = 1;
// 添加到缓存
add_to_cache(bp);
return bp;
}
电源管理
1. ACPI(高级配置和电源接口)
// 电源状态
typedef enum {
POWER_WORKING,
POWER_SLEEP,
POWER_HIBERNATE,
POWER_OFF
} PowerState;
// 电源管理函数
void enter_sleep_state() {
// 1. 保存所有进程状态
save_all_processes();
// 2. 将内存内容写入磁盘(Hibernate)
write_memory_to_disk();
// 3. 发送ACPI命令
outb(ACPI_PM1a_CNT, SLEEP_ENABLE);
// 4. 进入睡眠状态
asm("hlt");
}
// 设备电源管理
void set_device_power(struct device *dev, int power_state) {
if (power_state == POWER_OFF) {
// 关闭设备
dev->driver->shutdown(dev);
// 关闭时钟
disable_clock(dev);
} else if (power_state == POWER_WORKING) {
// 启用设备
enable_clock(dev);
dev->driver->init(dev);
}
}
系统安全与发展趋势
系统安全基础
安全目标(CIA三元组):
- 机密性(Confidentiality):防止未授权访问
- 完整性(Integrity):防止未授权修改
- 可用性(Availability):确保授权用户可访问
访问控制
1. 自主访问控制(DAC)
// Unix权限模型
struct file_permissions {
unsigned int owner_read : 1;
unsigned int owner_write : 1;
unsigned int owner_execute : 1;
unsigned int group_read : 1;
unsigned int group_write : 1;
unsigned int group_execute : 1;
unsigned int other_read : 1;
unsigned int other_write : 1;
unsigned int other_execute : 1;
};
// 权限检查
int check_permission(struct inode *inode, int mode, struct user *user) {
if (user->uid == 0) return 1; // root有所有权限
if (user->uid == inode->i_uid) {
// 所有者
if (mode == READ && !inode->perm.owner_read) return 0;
if (mode == WRITE && !inode->perm.owner_write) return 0;
if (mode == EXECUTE && !inode->perm.owner_execute) return 0;
} else if (user->gid == inode->i_gid) {
// 组
if (mode == READ && !inode->perm.group_read) return 0;
if (mode == WRITE && !inode->perm.group_write) return 0;
if (mode == EXECUTE && !inode->perm.group_execute) return 0;
} else {
// 其他
if (mode == READ && !inode->perm.other_read) return 0;
if (mode == WRITE && !inode->perm.other_write) return 0;
if (mode == EXECUTE && !inode->perm.other_execute) return 0;
}
return 1;
}
2. 强制访问控制(MAC)
// SELinux安全上下文
struct security_context {
char user[32];
char role[32];
char type[32]; // 类型
int level; // 敏感级别
};
// MAC策略检查
int mac_check(struct security_context *subject,
struct security_context *object,
int operation) {
// 读取策略规则
// 规则格式:允许 subject.type 操作 object.type
if (strcmp(subject->type, "trusted") == 0) {
return 1; // trusted类型有所有权限
}
if (strcmp(subject->type, "user") == 0 &&
strcmp(object->type, "user_data") == 0 &&
operation == READ) {
return 1; // 允许读取用户数据
}
return 0; // 默认拒绝
}
身份认证
1. 密码认证
// 密码哈希存储
struct passwd_entry {
char username[32];
char password_hash[64]; // 存储哈希值
int uid;
int gid;
};
// 验证密码
int verify_password(const char *username, const char *password) {
struct passwd_entry entry;
// 从/etc/shadow读取
if (get_user_entry(username, &entry) < 0) return 0;
// 计算输入密码的哈希
char *hash = crypt(password, entry.password_hash);
return strcmp(hash, entry.password_hash) == 0;
}
// 密码哈希示例(使用SHA-256)
void hash_password(const char *password, char *output) {
// 实际使用中应使用加盐哈希
// 这里简化演示
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx, password, strlen(password));
sha256_final(&ctx, output);
}
2. 多因素认证
// TOTP(基于时间的一次性密码)
int verify_totp(const char *secret, int user_code) {
// 获取当前时间戳(30秒时间窗)
uint64_t timestamp = time(NULL) / 30;
// 生成预期代码
int expected = generate_totp(secret, timestamp);
// 允许前后一个时间窗(容错)
int expected_prev = generate_totp(secret, timestamp - 1);
int expected_next = generate_totp(secret, timestamp + 1);
return (user_code == expected) ||
(user_code == expected_prev) ||
(user_code == expected_next);
}
内存保护
1. 地址空间布局随机化(ASLR)
// 进程创建时随机化内存布局
void setup_aslr(struct process *proc) {
// 随机化栈起始地址
proc->stack_start = STACK_BASE + (rand() % 0x10000000);
// 随机化堆起始地址
proc->heap_start = HEAP_BASE + (rand() % 0x10000000);
// 随机化共享库加载地址
proc->lib_start = LIB_BASE + (rand() % 0x10000000);
}
2. 数据执行保护(DEP/NX)
// 页表项中的NX位(不可执行位)
typedef struct {
unsigned int frame : 20;
unsigned int valid : 1;
unsigned int nx : 1; // No Execute
// 其他标志...
} PageTableEntry_DEP;
// 设置内存页为不可执行
void set_no_execute(void *addr) {
PageTableEntry_DEP *pte = get_page_table_entry(addr);
pte->nx = 1;
flush_tlb();
}
3. 栈保护
// 栈溢出保护(金丝雀值)
void vulnerable_function() {
int canary = generate_canary(); // 随机值
char buffer[64];
// 函数结束时检查
if (canary != expected_canary) {
// 栈溢出检测
abort();
}
}
加密与安全通信
1. 文件加密
// 文件加密结构
struct encrypted_file {
char iv[16]; // 初始化向量
char key[32]; // 加密密钥(应从用户密码派生)
char ciphertext[0]; // 加密数据
};
// 加密文件写入
void write_encrypted_file(const char *path, const void *data, int len, const char *password) {
// 1. 从密码派生密钥
char key[32];
derive_key(password, key);
// 2. 生成随机IV
char iv[16];
random_bytes(iv, 16);
// 3. 加密数据
char *encrypted = malloc(len + 16);
AES_CBC_encrypt(data, len, key, iv, encrypted);
// 4. 写入文件
int fd = open(path, O_CREAT | O_WRONLY, 0600);
write(fd, iv, 16);
write(fd, encrypted, len + 16);
close(fd);
free(encrypted);
}
2. 安全通信(TLS简化版)
// 安全连接结构
struct secure_connection {
int socket;
char session_key[32];
char iv[16];
// 公钥/私钥...
};
// 建立安全连接
int establish_secure_connection(struct secure_connection *conn, int sockfd) {
// 1. 生成临时密钥对
generate_keypair(&conn->public_key, &conn->private_key);
// 2. 交换公钥
send(sockfd, &conn->public_key, sizeof(conn->public_key), 0);
recv(sockfd, &conn->peer_public_key, sizeof(conn->peer_public_key), 0);
// 3. 计算共享密钥(Diffie-Hellman)
derive_shared_secret(&conn->private_key, &conn->peer_public_key, conn->session_key);
// 4. 生成IV
random_bytes(conn->iv, 16);
conn->socket = sockfd;
return 0;
}
// 安全发送
int secure_send(struct secure_connection *conn, const void *data, int len) {
char *encrypted = malloc(len + 16);
AES_CBC_encrypt(data, len, conn->session_key, conn->iv, encrypted);
int result = send(conn->socket, encrypted, len + 16, 0);
free(encrypted);
return result;
}
系统审计与日志
1. 审计日志
// 审计事件结构
struct audit_event {
time_t timestamp;
int event_type;
int uid;
int pid;
char summary[256];
char details[1024];
};
// 记录事件
void audit_log(int event_type, const char *format, ...) {
struct audit_event event;
event.timestamp = time(NULL);
event.event_type = event_type;
event.uid = getuid();
event.pid = getpid();
va_list args;
va_start(args, format);
vsnprintf(event.details, sizeof(event.details), format, args);
va_end(args);
// 写入审计日志文件
int fd = open("/var/log/audit.log", O_WRONLY | O_APPEND);
write(fd, &event, sizeof(event));
close(fd);
// 如果是高危事件,发送警报
if (event_type >= AUDIT_CRITICAL) {
send_security_alert(&event);
}
}
2. 入侵检测
// 简单的异常检测
void detect_anomalies() {
// 检测暴力破解
int failed_logins = count_failed_logins_last_minute();
if (failed_logins > 5) {
audit_log(AUDIT_ALERT, "可能的暴力破解攻击,失败登录次数:%d", failed_logins);
block_ip(get_attacker_ip());
}
// 检测异常进程
struct process *proc;
for_each_process(proc) {
if (proc->cpu_usage > 90 && proc->memory_usage > 500MB) {
audit_log(AUDIT_WARNING, "异常进程:PID=%d, CPU=%.1f%%, MEM=%.1fMB",
proc->pid, proc->cpu_usage, proc->memory_usage);
}
}
}
现代操作系统发展趋势
1. 云操作系统
特点:
- 资源池化与弹性伸缩
- 多租户隔离
- 微服务架构
- 容器化部署
关键技术:
- Docker容器技术
- Kubernetes编排
- Serverless计算
2. 分布式操作系统
// 分布式进程管理
struct distributed_process {
char process_id[64];
char node_id[32];
int state;
// 分布式锁
struct distributed_lock *lock;
// 一致性状态
struct consistency_state *consistency;
};
// 分布式一致性协议(简化版Paxos)
int paxos_propose(int proposal_id, int value) {
// 1. 准备阶段
send_prepare(proposal_id);
int promises = count_promises();
if (promises < majority) return -1;
// 2. 接受阶段
send_accept(proposal_id, value);
int accepts = count_accepts();
if (accepts < majority) return -1;
// 3. 学习阶段
broadcast_learn(value);
return 0;
}
3. 实时操作系统(RTOS)
// 实时任务调度
typedef struct {
int task_id;
void (*entry)(void);
int priority;
int period; // 周期(毫秒)
int deadline; // 截止时间
int wcet; // 最坏执行时间
} RealTimeTask;
// 速率单调调度(RMS)
void rms_schedule(RealTimeTask *tasks, int n) {
// 按周期排序(周期越短优先级越高)
qsort(tasks, n, sizeof(RealTimeTask), compare_period);
for (int i = 0; i < n; i++) {
// 检查可调度性
double utilization = 0;
for (int j = 0; j <= i; j++) {
utilization += (double)tasks[j].wcet / tasks[j].period;
}
double bound = i * (pow(2, 1.0/(i+1)) - 1);
if (utilization > bound) {
printf("任务%d不可调度\n", tasks[i].task_id);
return;
}
}
printf("所有任务可调度\n");
}
4. 嵌入式操作系统
特点:
- 资源受限
- 低功耗
- 高可靠性
- 实时性要求
代表系统:
- FreeRTOS
- Zephyr
- VxWorks
5. 物联网操作系统
// IoT设备管理
struct iot_device {
char device_id[32];
char protocol[16]; // MQTT, CoAP, HTTP
int power_level;
int connectivity;
void (*sensor_callback)(int value);
};
// 低功耗管理
void enter_low_power_mode(struct iot_device *dev) {
// 1. 关闭非必要外设
disable_peripherals();
// 2. 降低CPU频率
set_cpu_frequency(LOW_FREQ);
// 3. 配置唤醒源
enable_wakeup_timer(60); // 60秒后唤醒
enable_wakeup_interrupt(KEYPAD_PIN);
// 4. 进入深度睡眠
asm("WFI"); // Wait For Interrupt
}
6. 量子操作系统(前沿研究)
// 量子比特管理(概念性)
typedef struct {
int qubit_id;
double alpha; // 量子态系数
double beta;
int entangled_with; // 纠缠的量子比特
} QuantumBit;
// 量子任务调度
void schedule_quantum_task(struct quantum_program *prog) {
// 量子纠错
apply_error_correction(prog);
// 量子门序列编译
compile_quantum_gates(prog);
// 执行并测量
execute_and_measure(prog);
}
7. 生物启发操作系统
// 生物计算模型
struct neuron {
double potential;
double threshold;
struct neuron **connections;
int connection_count;
};
// 神经形态调度
void neural_schedule(struct process *proc) {
// 模拟神经网络决策
double priority = activate_neural_network(
proc->cpu_usage,
proc->memory_usage,
proc->io_wait,
proc->user_priority
);
proc->priority = (int)(priority * 100);
}
安全发展趋势
1. 零信任架构
// 零信任验证
int zero_trust_verify(struct request *req) {
// 1. 持续验证
if (!verify_identity(req->user)) return 0;
// 2. 设备健康检查
if (!check_device_health(req->device)) return 0;
// 3. 上下文分析
if (!analyze_context(req->location, req->time, req->behavior)) return 0;
// 4. 最小权限
if (!check_minimal_permission(req->action, req->resource)) return 0;
// 5. 持续监控
monitor_session(req->session);
return 1;
}
2. 可信执行环境(TEE)
// TEE安全世界
void trusted_execution(struct trusted_app *app) {
// 在安全世界执行
enter_secure_world();
// 访问安全存储
char *secret = read_secure_storage();
// 执行加密操作
char *result = secure_hash(secret);
// 返回结果
exit_secure_world(result);
}
3. 后量子密码学
// 格基密码学(Lattice-based)
struct lattice_key {
int dimension;
int *matrix;
int *vector;
};
// 后量子签名
int pq_sign(struct lattice_key *key, const char *message, char *signature) {
// 基于格问题的签名方案
// 如:Dilithium, Falcon
return 0;
}
总结
操作系统作为计算机系统的核心软件,其核心内容涵盖了从基础概念到高级特性的完整体系。通过深入理解进程管理、内存管理、文件系统、设备管理以及安全机制,我们能够构建高效、安全、可靠的计算环境。
现代操作系统正朝着更加智能化、分布式、安全化的方向发展,云计算、物联网、量子计算等新技术的出现,为操作系统设计带来了新的挑战和机遇。掌握这些核心概念和实现技术,对于理解计算机系统的工作原理和开发高质量软件具有重要意义。
在未来的发展中,操作系统将更加注重:
- 安全性:零信任、硬件级安全
- 可扩展性:支持异构计算、分布式架构
- 智能化:AI辅助的资源管理
- 绿色计算:能源效率优化
- 用户体验:无缝的多设备协同
这些趋势将推动操作系统技术持续演进,为数字世界提供更强大的基础支撑。
