从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以其独…...
Exclusively Dark数据集:破解低光照视觉难题的7363张真实图像基准
Exclusively Dark数据集:破解低光照视觉难题的7363张真实图像基准 【免费下载链接】Exclusively-Dark-Image-Dataset Exclusively Dark (ExDARK) dataset which to the best of our knowledge, is the largest collection of low-light images taken in very low-li…...
5分钟精通VinXiangQi:免费AI象棋助手的完整使用教程
5分钟精通VinXiangQi:免费AI象棋助手的完整使用教程 【免费下载链接】VinXiangQi Xiangqi syncing tool based on Yolov5 / 基于Yolov5的中国象棋连线工具 项目地址: https://gitcode.com/gh_mirrors/vi/VinXiangQi VinXiangQi是一款基于YOLOv5深度学习技术的…...
YOLOv5锚框(anchor)自适应计算与实战调优指南
1. 为什么需要自定义YOLOv5锚框参数 第一次用YOLOv5跑自己的数据集时,我发现模型死活训不出好效果。明明用的是官方预训练权重,标注数据也检查过没问题,但AP值就是上不去。后来把预测结果可视化出来才发现问题——那些长条形物体(…...
【文件上传绕过】十六—十八:巧用文件幻数与内容伪装突破类型校验
1. 文件幻数:藏在二进制里的身份证 每次上传图片时,你有没有好奇过系统是怎么判断"这张图真的是JPG"的?这就像超市扫码器识别商品条形码一样,计算机其实是通过读取文件开头的几个特殊字节——我们称之为**幻数ÿ…...
如何让旧款iOS设备重获新生:Legacy-iOS-Kit终极指南
如何让旧款iOS设备重获新生:Legacy-iOS-Kit终极指南 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit Le…...
一天怎么完成论文初稿
写论文这件事,从选题到完稿,哪一步都能卡掉你半条命。我身边不少读研读博的同学,白天泡实验室做实验,晚上挤时间写论文,熬了一两个月出初稿,结果格式不对、文献零散,还要和同门改来改去…...
别再死记硬背了!Vivado伪双口RAM的wea/ena信号,这次用仿真波形给你讲透
深入解析Vivado伪双口RAM控制信号:从波形图看wea/ena关键设计 在FPGA开发中,存储器设计一直是性能优化的关键环节。Xilinx Vivado工具链提供的伪双口RAM IP核因其灵活性和高效性,成为许多高速数据处理系统的首选方案。然而,不少开…...
CANN/asc-devkit asc_copy_gm2l1 API
asc_copy_gm2l1 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode…...
JeecgBoot商业版源码深度解析:从下载到二次开发实战指南
1. JeecgBoot商业版源码获取与验证 作为一款企业级低代码开发平台,JeecgBoot商业版源码的获取需要特别注意官方渠道。与开源版不同,商业版通常需要联系官方商务获取授权文件和技术支持。我在实际项目中发现,很多团队容易混淆gitee上的开源仓库…...
3个理由告诉你:为什么这款轻量级内存管理工具Mem Reduct能让你的Windows电脑飞起来?
3个理由告诉你:为什么这款轻量级内存管理工具Mem Reduct能让你的Windows电脑飞起来? 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitc…...
