从0开始的操作系统手搓教程33:挂载我们的文件系统
目录
代码实现
添加到初始化上
上电看现象
挂载分区可能是一些朋友不理解的——实际上挂载就是将我们的文件系统封装好了的设备(硬盘啊,SD卡啊,U盘啊等等),挂到我们的默认分区路径下。这样我们就能访问到了(嘿!想象你是一个蚂蚁,别人把葡萄挂到了树枝上,然后你就可以爬着访问到了)
文件系统的挂载和卸载在Linux中是非常重要的功能,它允许用户将一个分区的文件系统与另一个分区的目录树连接起来。通常情况下,Linux会将根分区作为默认分区,并通过mount命令将其他分区挂载到默认分区的某个目录上。在这个过程里,分区的根目录是固定存在的,其他分区尽管有自己的根目录,但它们的根目录并不直接与整个系统的文件结构挂钩。通过mount命令,其他分区可以在需要时被挂载到指定的目录下,而默认分区的根目录则作为所有分区的父目录,挂载后形成一个统一的路径树结构。
对于挂载操作系统到裸盘的情况,并没有现成的分区和文件系统。这时,为了实现文件操作,首先必须在裸盘上创建文件系统,至少要实现基本的文件写入功能。然后,操作系统可以通过文件系统进行安装。例如,在Windows或Linux系统安装过程中,首先会选择目标分区,格式化并安装操作系统到文件系统中。对于学习操作系统实现的场景,虽然也可以模仿这一过程,但为了简化操作,一开始可以避免复杂的分区挂载过程。
实现分区挂载的本质是通过读取硬盘上的元信息并将其加载到内存中,这样,所有硬盘资源的使用情况都能通过内存中的元信息进行管理。当执行写操作时,内存中的数据需要及时同步到硬盘,确保数据的一致性和持久性
代码实现
/* Finds the partition named 'part_name' in the partition list and assigns its * pointer to 'cur_part' */
static bool mount_partition(list_elem *pelem, int arg) {// Convert the argument to a partition name stringchar *part_name = (char *)arg;// Retrieve the DiskPartition structure from the list elementDiskPartition *part = elem2entry(DiskPartition, part_tag, pelem);
// If the partition name matches, mount this partitionif (!k_strcmp(part->name, part_name)) {cur_part = part; // Set the current partition to the found partitionDisk *hd = cur_part->my_disk; // Get the disk that contains this partition
// Allocate a buffer to temporarily store the superblock read from diskSuperBlock *sb_buf = (SuperBlock *)sys_malloc(SECTOR_SIZE);
// Allocate memory for the superblock of the current partitioncur_part->sb = (SuperBlock *)sys_malloc(sizeof(SuperBlock));if (!cur_part->sb) {KERNEL_PANIC_SPIN("alloc memory failed!"); // Kernel panic if allocation fails}
// Read the superblock from disk into the bufferk_memset(sb_buf, 0, SECTOR_SIZE);ide_read(hd, cur_part->start_lba + 1, sb_buf, 1);
// Copy the superblock information from the buffer to the partition's superblockk_memcpy(cur_part->sb, sb_buf, sizeof(SuperBlock));
/********** Load the block bitmap from disk into memory **********/// Allocate memory for the block bitmapcur_part->block_bitmap.bits = (uint8_t *)sys_malloc(sb_buf->block_bitmap_sects * SECTOR_SIZE);if (!(cur_part->block_bitmap.bits)) {KERNEL_PANIC_SPIN("alloc memory failed!"); // Kernel panic if allocation fails}// Set the length of the block bitmap in bytescur_part->block_bitmap.btmp_bytes_len = sb_buf->block_bitmap_sects * SECTOR_SIZE;// Read the block bitmap from disk into memoryide_read(hd, sb_buf->block_bitmap_lba, cur_part->block_bitmap.bits, sb_buf->block_bitmap_sects);/****************************************************************/
/********** Load the inode bitmap from disk into memory **********/// Allocate memory for the inode bitmapcur_part->inode_bitmap.bits = (uint8_t *)sys_malloc(sb_buf->inode_bitmap_sects * SECTOR_SIZE);if (!(cur_part->inode_bitmap.bits)) {KERNEL_PANIC_SPIN("alloc memory failed!"); // Kernel panic if allocation fails}// Set the length of the inode bitmap in bytescur_part->inode_bitmap.btmp_bytes_len = sb_buf->inode_bitmap_sects * SECTOR_SIZE;// Read the inode bitmap from disk into memoryide_read(hd, sb_buf->inode_bitmap_lba, cur_part->inode_bitmap.bits, sb_buf->inode_bitmap_sects);/****************************************************************/
// Initialize the list of open inodes in this partitionlist_init(&cur_part->open_inodes);verbose_printk("disk mount %s done!\n", part->name); // Print a message indicating successful mounting
// Return true to stop further traversal, as the partition has been found and mountedreturn true;}return false; // Continue traversing the list if the partition was not found
}
mount_filesystem函数就是完成了文件系统中挂载默认分区并加载其元信息的过程。默认分区的名称为 default_part,其值为 sdb1,表示默认操作的分区是 sdb1。分区挂载通过 list_traversal 函数完成,该函数遍历分区列表 partition_list,并对每个分区调用回调函数 mount_partition,传入的参数是 default_part 的地址转换为整型后的值。mount_partition 是 list_traversal 的回调函数,其功能是在分区链表中找到与传入的分区名匹配的分区,并将其指针赋值给全局变量 cur_part,用于记录当前操作的分区。
在 mount_partition 函数中,首先将传入的参数 arg 还原为字符指针 part_name,然后通过宏 elem2entry 将 pelem 还原为分区结构体 part。接着,通过 strcmp 比对 part->name 和 part_name,如果匹配则找到目标分区,并将其指针赋值给 cur_part。随后,获取该分区所在的硬盘 hd,作为后续硬盘操作的参数。
接下来,系统为超级块申请内存缓冲区 sb_buf,并从硬盘中读取超级块信息到 sb_buf,然后将有用的超级块信息复制到 cur_part->sb 中,忽略填充部分以节省内存。之后,为块位图申请内存,并根据超级块中的 block_bitmap_sects 初始化块位图的大小,最后将硬盘上的块位图读入内存。类似地,系统还会加载 inode 位图到内存中。整个过程确保了分区的元信息被正确加载,并为后续的文件系统操作做好准备。
添加到初始化上
.../* Determine the default partition for operations */char default_part[8] = "sdb1";/* Mount the partition */list_traversal(&partition_list, mount_partition, (int)default_part);
上电看现象


下一篇
从0开始的操作系统手搓教程34:说说文件描述符与常见的操作和文件基本操作-CSDN博客文章浏览阅读614次,点赞4次,收藏13次。我们还需要打开根目录并初始化文件表// filesystem_init函数下追加:*/return ret;函数将本地文件描述符转换为全局文件表索引。首先,它获取当前任务的文件描述符表,然后根据传入的本地文件描述符返回对应的全局文件描述符索引。sys_close函数用于关闭文件。首先,它检查文件描述符是否大于2(标准输入、输出和错误文件描述符不处理)。然后,调用将本地文件描述符转换为全局文件描述符,并尝试关闭文件。如果成功,更新任务的文件描述符表并返回0;否则,返回-1。https://blog.csdn.net/charlie114514191/article/details/146143441
相关文章:
从0开始的操作系统手搓教程33:挂载我们的文件系统
目录 代码实现 添加到初始化上 上电看现象 挂载分区可能是一些朋友不理解的——实际上挂载就是将我们的文件系统封装好了的设备(硬盘啊,SD卡啊,U盘啊等等),挂到我们的默认分区路径下。这样我们就能访问到了ÿ…...
【Linux】36.简单的TCP网络程序
文章目录 1. TCP socket API 详解1.1 socket():打开一个网络通讯端口1.2 bind():绑定一个固定的网络地址和端口号1.3 listen():声明sockfd处于监听状态1.4 accept():接受连接1.5 connect():连接服务器 2. 实现一个TCP网络服务器2.1 Log.hpp - "多级日志系统"2.2 Daem…...
时序分析
1、基本概念介绍 1.1、 建立时间 T(su) 建立时间:setup time,它是指有效的边沿信号到来之前,输入端口数据保持稳定的时间。 1.1.1、 建立时间要求: 建立时间要求指的是 想要寄存器如期的工作,在有效时…...
doris:ClickHouse
Doris JDBC Catalog 支持通过标准 JDBC 接口连接 ClickHouse 数据库。本文档介绍如何配置 ClickHouse 数据库连接。 使用须知 要连接到 ClickHouse 数据库,您需要 ClickHouse 23.x 或更高版本 (低于此版本未经充分测试)。 ClickHouse 数据库的 JDBC 驱动程序&a…...
NLP常见任务专题介绍(1)-关系抽取(Relation Extraction, RE)任务训练模板
📌 关系抽取(Relation Extraction, RE)任务训练示例 本示例展示如何训练一个关系抽取模型,以识别两个实体之间的关系。 1️⃣ 任务描述 目标:从文本中提取两个实体之间的语义关系,例如 “人物 - 组织”、“药物 - 疾病”、“公司 - 创始人” 等。输入:句子 + 标注的实…...
大模型Transformer的MOE架构介绍及方案整理
前言:DeepSeek模型最近引起了NLP领域的极大关注,也让大家进一步对MOE(混合专家网络)架构提起了信心,借此机会整理下MOE的简单知识和对应的大模型。本文的思路是MOE的起源介绍、原理解释、再到现有MOE大模型的整理。 一…...
零基础掌握Linux SCP命令:5分钟实现高效文件传输,小白必看!
引言 “为什么我传个文件到服务器要折腾半小时?” 如果你也曾在Linux系统中为文件传输抓狂,今天这篇保姆级教程就是你的救星!SCP命令——一个基于SSH协议的高效传输工具,只需5分钟,彻底告别FTP客户端和繁琐操作&#…...
分类评价指标
基础概念解释 TP、TN、FP、FN 这里T是True,F是False,P为Positive,N为Negative TP:被模型正确地预测为正样本(原本为正样本,预测为正样本) TN:被模型正确地预测为负样本࿰…...
Python项目-基于Django的在线教育平台开发
1. 项目概述 在线教育平台已成为现代教育的重要组成部分,特别是在后疫情时代,远程学习的需求显著增加。本文将详细介绍如何使用Python的Django框架开发一个功能完善的在线教育平台,包括系统设计、核心功能实现以及部署上线等关键环节。 本项…...
子数组问题——动态规划
个人主页:敲上瘾-CSDN博客 动态规划 基础dp:基础dp——动态规划-CSDN博客多状态dp:多状态dp——动态规划-CSDN博客 目录 一、解题技巧 二、最大子数组和 三、乘积最大子数组 四、最长湍流子数组 五、单词拆分 一、解题技巧 区分子数组&…...
linux设置pem免密登录和密码登录
其实现在chatgpt 上面很多东西问题都可以找到比较好答案了,最近换了一个服务器,记录一下。 如果设置root用户,就直接切换到cd .ssh目录下生成ssh key即可,不需要创建用户创建用户的ssh文件夹了 比如说我要让danny这个用户可以用p…...
什么是Flask
Flask是Python中一个简单、灵活和易用的Web框架,适合初学者使用。它提供了丰富的功能和扩展性,可以帮助开发者快速构建功能完善的Web应用程序。 以下是Python Flask框架的一些特点和功能: Flask 是一个使用 Python 编写的轻量级 WSGI 微 Web…...
Spark(8)配置Hadoop集群环境-使用脚本命令实现集群文件同步
一.hadoop的运行模式 二.scp命令————基本使用 三.scp命令———拓展使用 四.rsync远程同步 五.xsync脚本集群之间的同步 一.hadoop的运行模式 hadoop一共有如下三种运行方式: 1. 本地运行。数据存储在linux本地,测试偶尔用一下。我们上一节课使用…...
【cocos creator】热更新
一、介绍 试了官方的热更新功能,总结一下 主要用于安卓包热更新 参考: Cocos Creator 2.2.2 热更新简易教程 基于cocos creator2.4.x的热更笔记 二、使用软件 1、cocos creator v2.4.10 2、creator热更新插件:热更新manifest生成工具&…...
黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!
调色教程 针对人像、静物以及户外旅拍照片,运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具,如基本参数调整、HSL(色相、饱和度、明亮度)调整、曲线工具等改变照片原本的色彩、明度、对比度等属性,将…...
部署vue+django项目(初版)
1.准备 vscode 插件Remote SSH,连接远程,打开远程中home文件夹。 镜像和容器的一些常用命令 docker images docker ps 查看所有正在运行的容器 docker ps -a docker rmi -f tk-django-app 删除镜像 docker rm xxx 删除容器 docker start xxxx …...
Redis7系列:设置开机自启
前面的文章讲了Redis和Redis Stack的安装,随着服务器的重启,导致Redis 客户端无法连接。原来的是Redis没有配置开机自启。此文记录一下如何配置开机自启。 1、修改配置文件 前面的Redis和Redis Stack的安装的文章中已经讲了redis.config的配置…...
HarmonyOS学习第18天:多媒体功能全解析
一、开篇引入 在当今数字化时代,多媒体已经深度融入我们的日常生活。无论是在工作中通过视频会议进行沟通协作,还是在学习时借助在线课程的音频讲解加深理解,亦或是在休闲时光用手机播放音乐放松身心、观看视频打发时间,多媒体功…...
在rocklinux里面批量部署安装rocklinx9
部署三台Rockylinux9服务器 实验要求 1. 自动安装ubuntu server20以上版本 2. 自动部署三台Rockylinux9服务器,最小化安装,安装基础包,并设定国内源,设静态IP 实验步骤 安装软件 # yum源必须有epel源 # dnf install -y epel-re…...
Manus:成为AI Agent领域的标杆
一、引言 官网:Manus 随着人工智能技术的飞速发展,AI Agent(智能体)作为人工智能领域的重要分支,正逐渐从概念走向现实,并在各行各业展现出巨大的应用潜力。在众多AI Agent产品中,Manus以其独…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
