第一阶段 - Rust学习
0 前言
Rust作为rCore操作系统的开发语言,学习并掌握它对于后面学习rCore OS是非常重要的(关于我Rust学了个大概就去硬啃rCore差点自闭这件事)。
这次训练营也是我二刷了,上次23秋季由于被学校抓去打互联网+等比赛了,🤦♂️实在是没有时间弄了,进了二阶段就没然后了。
一阶段时间过的好快,感觉还没学多少就过去了(时间都用去debug操作系统大赛的fatfs了🤦♂️)。所以总结的内容就比较普普通通了,各位大佬见谅🙏。
1 环境与工具软件等
由于本人并不是CS相关专业,过去主攻的是EE,所以CS里面的很多东西过去都没接触过。从23年秋季第一次接触训练营开始到现在,接触到了很多过去没有用过的工具软件以及一些开发环境,在此简单的列举了一些。
1.1 git和github
是的,你没有看错。我之前真没怎么用过git和github。一方面原因是,上大学后搞的都是嵌入式裸机的开发,远古单片机IDE(Keil)不支持高级的代码版本管理,加上我的学习路线上也没碰到过使用代码版本管理,索性代码直接放本地(别人要的话就u盘拷贝🤦♂️),就很少用git去把代码放仓库(之前实习时迫不得已去折腾了下)。另一方面是,git和github有些时候真的太卡了(之前不会挂代理也不敢挂梯子)。
不过,现在熟悉了git的各个命令后,配合上github去做项目的代码版本管理是真爽呀。
个人过去常用的git命令和个人理解如下:
1 | git clone // 将repo(仓库)克隆到本地 |
还有一些比如本地新建的分支需要推到远程、放弃某文件的修改等命令,就没去记了。我是做相关操作的时候,看一下报错建议的命令或在搜一下、问一下gpt,然后改一下。
另外初次使用可能需要配置用户信息:
1 | git config --global user.name "Your Name" |
1.2 Linux操作系统(Ubuntu、CentOS)
虽说之前玩jeston和个人博客的时候也用过,但是基本上就是靠readme+baidu+CtrlCV+GPT(而且用了就忘),这次也算是又学习并加深了了解吧。这里就简单的列一下这期间用到的还记得的命令吧(大佬们清点喷555)
1 | ls # 列出当前目录下的文件和文件夹 |
1.3 RustRover
强烈推荐,我刚开始是用的VSCode+RA插件或Vim+YouCompleteMe。后来换成rr后,感觉开发真的舒服了好多。一是因为二阶段写OS,在ubuntu里我用的VSCode写一会就会崩,比较卡。用Vim的话,代码文件一多切来切去麻烦的很;二是因为他的各个界面和PyCharm、IDEA是一样的,上手很快;三是多了很多有用的功能,比如你use了某个外部creat,rr会自动帮你在cargo.toml中加上依赖。
RustRover下载地址:https://www.jetbrains.com/zh-cn/rust/
Linux环境安装步骤:
1 | 1. 下载 |
在欢迎界面左下角点击设置图标,再点击(Create Desktop Entry)将rustrover添加到桌面目录。之后便可以使用了。
2 Rust知识
2.1 Rust学习资料
5.Rust 半小时学习
半小时看不完呀!
2.2 个人觉得Rust比较有意思的知识点
2.2.1 所有权(Ownership)和生命周期(Lifetimes):
- Rust的所有权和生命周期机制,可以防止诸如空悬指针、缓冲区溢出等内存安全问题。
- 在Rust中,每个值都有且只有一个所有者。
- 而在C语言中,并没有所有权概念,内存管理完全由程序员负责,这就可能导致内存泄漏和野指针等问题。
1
2
3
4
5
6// Rust
{
let s1 = String::from("hello");
let s2 = s1;
// 此时 s1 已经失效,不能被使用
}1
2
3
4// C
char *s1 = "hello";
char *s2 = s1;
// 此时 s1 和 s2 都指向相同的内存2.2.2 借用检查(Borrowing):
- Rust的数据借用可以允许多个读访问,但只要有一个可变借用,就不能有其他读或写访问。
- C语言没有这样的机制,因此需要手动管理指针和数据的共享。
1
2
3
4
5
6
7
8// Rust
{
let mut s = String::from("hello");
{
let r1 = &mut s;
// 在此作用域内,不能借用 s 的其他引用
} // r1 超出作用域,s 可以被再次借用
}1
2
3
4// C
char s[] = "hello";
char *p1 = s;
char *p2 = s; // p1 和 p2 都指向相同的内存2.2.3 模式匹配(Pattern Matching):
- Rust提供了强大的模式匹配功能,可以用于枚举、结构体、元组和字面量等。
- C语言没有内置的模式匹配功能,通常需要使用
switch
语句和多个if-else
链来实现。1
2
3
4
5
6
7
8
9
10
11
12
13
14// Rust
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
let coin = Coin::Penny;
match coin {
Coin::Penny => println!("Penny"),
Coin::Nickel => println!("Nickel"),
Coin::Dime => println!("Dime"),
Coin::Quarter => println!("Quarter"),
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// C
switch (coin) {
case PENNY:
printf("Penny");
break;
case NICKEL:
printf("Nickel");
break;
case DIME:
printf("Dime");
break;
case QUARTER:
printf("Quarter");
break;
}2.2.4 并发(Concurrency):
- Rust提供了安全并发的工具,如
std::thread
、Arc
(原子引用计数)和Mutex
(互斥锁)。 - C语言标准库没有内置的并发工具,通常需要使用操作系统提供的线程库(如POSIX线程)和同步原语。
1
2
3
4
5
6// Rust
use std::thread;
let handle = thread::spawn(|| {
// 在新线程中运行的代码
});
handle.join().unwrap();1
2
3
4
5
6
7// C
pthread_t thread;
int status = pthread_create(&thread, NULL, &thread_function, NULL);
if (status != 0) {
// 错误处理
}
pthread_join(thread, NULL);2.2.5 错误处理(Error Handling):
- Rust使用
Result
和Option
类型来处理可能的错误或空值,这鼓励开发人员进行显式的错误处理。 - C语言通常使用整数错误码和返回值,这可能导致错误被忽略或错误处理。
1
2
3
4// Rust
fn open_file(file_name: &str) -> Result<File, io::Error> {
File::open(file_name)
}1
2
3
4
5
6
7
8// C
int open_file(const char *file_name) {
FILE *file = fopen(file_name, "r");
if (!file) {
return -1; // 返回错误码
}
return 0; // 表示成功
}3 总结
说来惭愧,这次训练营第一阶段大部分时间花在折腾OS大赛上了。本来到rCore的ch7时都挺顺利的,结果尝试去运行OS大赛的FAT32镜像里的测例就碰壁了。先是easyfs和fat32不是一个东西,得把照着rCore写的OS的fs换成支持fat32的,瞎折腾了两周总算是能读取fat32里的文件了。然后又发现大赛OS的elf文件导入OS运行又有问题,瞎折腾也搞不出来了(基础不牢靠,不懂为啥会loadpage Fault),索性打算重新复习。
这次训练营又学到了很多新的知识,不过也能很清楚地感觉到掌握的不牢靠,后面还需不断加强巩固。同时我也知道了如果自己后面想往OS方向发展,还有很多需要去学习的。说实话,刚开始搞rCore的时候感觉还挺好的,而后到了ch4后,计组等知识的欠缺就很致命了,搞的差点放弃了(fat32那也是,不过好在搞出来了)。然后到了运行OS大赛的elf这就真搞不懂了,只能试着去好好复习下Rust、看看计组、CSAPP等后,再来看看了。
感激社区提供了这样一个学习平台,它为我打开了一扇探索操作系统奥秘的大门。希望后续的学习我还能够坚持下去吧!
4 图片记录
照着rCore写的FeatOS移植FAT32文件系统成功