Li Guangqiao
Li Guangqiao

一个正在转rust的ExtJs前端工程师。迷信rust的整体发展,十分相信rust在各个领域都能发光发热,至少目前rust在很多领域上验证了其安全性、易维护性。但说实话对于我这种菜鸡也是真的难上手哈哈哈~~。 思路总结:

  • 万物诞生都会有一个需求来源,每一个改变都是为了解决某个问题,最后应该考虑如何去做
  • 学会掌握一些宏观的知识和理论:系统论、还原论
  • 工程化思想,如何描述整体,从整体架构到模块关联等 故学习东西应该像看地图一样,先看整体了解整体的结构,然后再聚焦每一个模块,对于模块的学习,思考三个问题,“是什么?”、“为什么?”、“怎么做?”;那么设计一个东西时也应该去考虑整体性和关联性。

有关于未来的发展,以下是鄙人的粗浅的观点:

  • 编程语言未来应该是每个人必备的工具
  • 未来的交互方式应该会以语言交互为主流
  • 下一个去中心化的技术方案出来之前,区块链依然是web3建立价值体系的基础技术方案,如何将现实价值和虚拟价值联通是进入数字世界的一个大难题。
  • 未来注定是AI的世界。AI的进化会伴随绝大部分人的退化,届时除了尖端人才,人们学习的重心会放在何处?

走读Writing an OS in Rust实验(三)
走读Writing an OS in Rust实验(三)

Li Guangqiao - 05/12/2023

最小Rust内核 (参考原作者phil的官方博客) 启动进程 计算机开机时,它开始执行存储在主板 ROM 中的固件代码。 启动进程执行加电自检、检测可用 RAM 并预初始化 CPU 和硬件。 然后,它会查找可启动磁盘并开始启动操作系统内核。 在 x86 上,有两种固件标准:“基本输入/输出系统”(BIOS) 和较新的“统一可扩展固件接口”(UEFI)。 BIOS 标准陈旧且过时,但简单且自 20 世纪 80 年代以来的任何 x86 计算机都得到良好支持。 相比之下,UEFI 更现代,具有更多功能,但设置更复杂。目前UEFI,作者已经开始支持了,详细进度去看作者的github仓库或者相关新的博客。 启动进程的具体流程: 当您打开计算机时,它会从主板上的某些特殊闪存加载 BIOS。 BIOS 运行硬件的自检和初始化例程,然后查找可启动磁盘。 如果找到,控制权就会转移到其引导加载程序,这是存储在磁盘开头的 512 字节可执行代码部分。 大多数引导加载程序都大于 512 字节,因此引导加载程序通常分为较小的第一阶段(适合 512 字节)和第二阶段(随后由第一阶段加载)。 引导加载程序必须确定内核映像在磁盘上的位置并将其加载到内存中。 它还需要先将CPU从16位实模式切换到32位保护模式,然后再切换到64位长模式,其中64位寄存器和完整的主存储器都可用。 它的第三项工作是从 BIOS 查询某些信息(例如内存映射)并将其传递给操作系统内核。 编写引导加载程序有点麻烦,因为它需要汇编语言和许多非深入的步骤,例如“将这个神奇的值写入该处理器寄存器”。 因此,我们不会在本文中介绍引导加载程序的创建,而是提供一个名为 bootimage 的工具,该工具会自动将引导加载程序添加到内核中。 内核构建 主要包含4个部分 下载nightly版本的Rust 项目配置清单 编译内核 向屏幕打印字符 启动内核 项目配置清单 通过 --target 参数,cargo 支持不同的目标系统。这个目标系统可以使用一个目标三元组(target triple)来描述,它描述了 CPU 架构、平台供应者、操作系统和应用程序二进制接口(Application Binary...

走读Writing an OS in Rust实验(二)
走读Writing an OS in Rust实验(二)

Li Guangqiao - 02/12/2023

独立式可执行程序 (参考原作者phil的官方博客) 为了用 Rust 编写一个操作系统内核,我们需要创建一个独立于操作系统的可执行程序。这样的可执行程序常被称作独立式可执行程序(freestanding executable)或裸机程序(bare-metal executable)。 构建裸机程序主要需要五步: 禁用标准库 重新实现panic处理函数 禁用栈展开(事实上重写程序入口) 重写程序入口 编译成裸机目标 禁用标准库 目标:断开与标准库的链接,使用核心库脱离操作系统绑定 #![no_std]添加到程序可以断开与标准库的链接 #![no_std] fn main() { println!("Hello, world!"); } cargo build验证 发现println!宏已经找不到了。 error: cannot find macro `println` in this scope --> src/main.rs:4:5 | 4 | println!("Hello, world!"); | ^^^^^^^ error: `#[panic_handler]` function required, but not found error: language item required, but not found:...

走读Writing an OS in Rust实验(一)
走读Writing an OS in Rust实验(一)

Li Guangqiao - 02/12/2023

Blob Os 内容大纲 ![](writing _an_os_in_rust_arch.png) 移除Rust标准库 标准库需要底层操作系统的支撑,想要裸机运行代码,要求Rust可执行文件使用核心库而不是标准库。 基于X86架构的最小内核 基于X86架构和Rust语言编写最小化的64位内核。本章将构建一个向显示器打印字符串,并能被打包为一个能够引导启动的磁盘映像。 VGA字符模式 VGA 字符模式(VGA text mode)是打印字符到屏幕的一种简单方式。在这篇文章中,为了包装这个模式为一个安全而简单的接口,我们将包装 unsafe 代码到独立的模块。我们还将实现对 Rust 语言格式化宏(formatting macros)的支持。 内核测试 本文主要讲述了在no_std环境下进行单元测试和集成测试的方法。我们将通过Rust的自定义测试框架来在我们的内核中执行一些测试函数。为了将结果反馈到QEMU上,我们需要使用QEMU的一些其他的功能以及bootimage工具。 CPU异常处理 CPU异常在很多情况下都有可能发生,比如访问无效的内存地址,或者在除法运算里除以0。为了处理这些错误,我们需要设置一个 中断描述符表 来提供异常处理函数。在文章的最后,我们的内核将能够捕获 断点异常 并在处理后恢复正常执行。 双重故障 在这篇文章中,我们会探索 double fault 异常的细节,它的触发条件是调用错误处理函数失败。通过捕获该异常,我们可以阻止致命的 triple faults 异常导致系统重启。为了尽可能避免 triple faults ,我们会在一个独立的内核栈配置 中断栈表 来捕捉 double faults。 硬件中断 在本文中,我们会对可编程的中断控制器进行设置,以将硬件中断转发给CPU,而要处理这些中断,只需要像处理异常一样在中断描述符表中加入一个新条目即可,在这里我们会以获取周期计时器的中断和获取键盘输入为例进行讲解。 内存分页初探 本文主要讲解 内存分页 机制,一种我们将会应用到操作系统里的十分常见的内存模型。同时,也会展开说明为何需要进行内存隔离、分段机制 是如何运作的、虚拟内存 是什么,以及内存分页是如何解决内存碎片问题的,同时也会对x86_64的多级页表布局进行探索。 分页实现 这篇文章展示了如何在我们的内核中实现分页支持。它首先探讨了使物理页表帧能够被内核访问的不同技术,并讨论了它们各自的优点和缺点。然后,它实现了一个地址转换功能和一个创建新映射的功能。 栈分配 这篇文章为我们的内核增加了对堆分配的支持。首先,它介绍了动态内存,并展示了借用检查器如何防止常见的分配错误。然后,它实现了 Rust 的基本分配接口,创建了一个堆内存区域,并设置了一个分配器包。在这篇文章的最后,内置 alloc crate 的所有分配和收集类型都将可供我们的内核使用。 分配器设计 这篇文章解释了如何从头开始实现堆分配器。它介绍并讨论了不同的分配器设计,包括凸块分配、链表分配和固定大小块分配。对于这三种设计中的每一种,我们将创建一个可用于内核的基本实现。 异步和等待 在这篇文章中,我们将探讨 Rust 的协作多任务处理和 async/await 特性。我们详细介绍了 async/await 在 Rust 中是如何工作的,包括 Future 特性的设计、状态机转换和固定。然后,我们通过创建一个异步键盘任务和一个基本的执行器,将对 async/await 的基本支持添加到我们的内核中。 ...

Mega Quick Start Guide on Ubuntu 22.04
Mega Quick Start Guide on Ubuntu 22.04

Li Guangqiao - 28/11/2023

Quick Started for developing and testing on Ubuntu(22.04) Install Rust on your Ubuntu machine. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh // Configure the Environment Variable source $HOME/.cargo/env // check your version rustc --version Clone mega repository and build it. git clone https://github.com/web3infra-foundation/mega.git cd mega cargo build Install PostgreSQL and init database. install PostgreSQL create database,then find the dump file in the...

Git对象及其存储结构
Git对象及其存储结构

Li Guangqiao - 03/11/2023

Git对象及其存储结构 Git对象 Git是一个内容寻址文件系统。其核心思想就是键值对数据库(key-value data store),其核心行为包括: 通过向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键(key)。 通过该键可以在任意时刻再次取回该内容。 实验出真知 可以通过底层命令 git hash-object 来演示上述效果——该命令可将任意数据保存于 .git/objects 目录(即 对象数据库),并返回指向该数据对象的唯一的键。 初始化一个Git仓库 $ git init git_lab 检查一下git对象目录(.git/objects)生成了哪些文件夹,通过find命令查看所有文件夹(包含子文件夹) $ find .git/objects/ .git/objects/ .git/objects/info .git/objects/pack 检查一下.git/objects目录下生成了哪些文件,同样通过find+文件路径+类型参数-type f查看所有文件 $ find .git/objects/ -type f //无输出表示没有文件 接下来要开始创建并保存一个文件了,这里简单创建一个文本文件 echo "git testing" > git_test.txt 保存到git对象目录(.git/objects)。这里使用了git hash-object命令,根据文件git_test.txt的内容生成一串hash值 git hash-object -w git_test.txt 34e75148c0aeb4efb212f817606d386b15190525 注意:hash值仅与文件内容有关,与名称无关。 $ echo "git testing" | git hash-object -w --stdin 34e75148c0aeb4efb212f817606d386b15190525 再次查看git对象目录(.git/objects)下的所有文件 $ find .git/objects/ -type f .git/objects/34/e75148c0aeb4efb212f817606d386b15190525 其中hash值长度40,前两个字符用于子目录命名,后38个字符用于文件命名。hash算法参考SHA-1 文件git_test.txt内容已经存储到对象数据库中,如果需要从git中取回数据,则需要通过cat-file命令实现(个人理解cat实际就是catch的缩写),其中指定 -p 选项可指示该命令自动判断内容的类型,并为我们显示大致的内容 $ git cat-file -p 34e75148c0aeb4efb212f817606d386b15190525 git testing 版本变更实验:更新文件git_test.txt的内容并重新保存 $ echo "changing"...