全文分为三个部分:
- Linux 常用操作
- 黑书的实验题
- 操作系统的笔记 / 王道习题
书籍参考:
- 《操作系统概念/原书第10版》机械工业出版社
- 《操作系统 王道2025》
编程环境:
Ubuntu 22.04 LTS
gcc 11.4.0
源码参考:
编程题
2.24
C++ |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | // FileCopy.cpp
#include <fcntl.h> // open
#include <unistd.h> // read write
#include <string.h> // memset
#include <iostream> // std::cerr
int main(int argc, char *argv[]) {
if(argc != 3){
std::cerr << "请输入源文件和目标文件的名称" << std::endl;
return 1;
}
// 以只读的方式打开
int fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1){
std::cerr << "打开源文件失败" << std::endl;
return 1;
}
// 以只写的方式打开,如果不存在则创建,如果存在则清空,权限为 666
int fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
if(fd2 == -1){
std::cerr << "打开目标文件失败" << std::endl;
return 1;
}
char buffer[64];
while(true){
memset(buffer, '\0', sizeof buffer);
int len = read(fd1, buffer, sizeof buffer);
if(len == -1){
std::cerr << "读取文件失败" << std::endl;
return 1;
}
if(len == 0) break;
if(write(fd2, buffer, len) == -1){
std::cerr << "写入文件失败" << std::endl;
return 1;
}
};
return 0;
}
|
- 可以通过
man open
,man read
等命令查看函数的使用方法
运行:
- 编译源文件
g++ FileCopy.cpp -o FileCopy
- 运行
./FileCopy FileCopy.cpp FileCopy.cpp.bak
- 查看文件
cat FileCopy.cpp.bak
- 使用系统调用跟踪工具
strace ./FileCopy FileCopy.cpp FileCopy.cpp.bak
编程项目
2.17
加载与卸载内核模块
进入 ch2
目录
我将 simple.c
中的 printk
的输出分别改为 内核加载
,内核卸载
,以便区分
-
编译 make
-
加载内核模块 sudo insmod simple.ko
- 查看内核模块
lsmod
- 可以看到
simple
模块
-
查看内核日志缓冲区 sudo dmesg
- 可以看到
内核加载
- 删除内核日志缓冲区
sudo dmesg -c
-
卸载内核模块 sudo rmmod simple
-
查看内核日志缓冲区 dmesg
输出内核模块从加载到卸载的时间
C++ |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | // simple.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
unsigned long cnt=0;
/* This function is called when the module is loaded. */
static int simple_init(void)
{
cnt = jiffies;
printk(KERN_INFO "加载内核:%lu %d\n", cnt, HZ);
return 0;
}
/* This function is called when the module is removed. */
static void simple_exit(void) {
cnt = (jiffies-cnt)/HZ;
printk(KERN_INFO "卸载内核:%lu\n", cnt);
}
/* Macros for registering module entry and exit points. */
module_init( simple_init );
module_exit( simple_exit );
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");
|
2.17 - 1
2.17 - 2