哈工大李治军老师操作系统笔记【30】:目录解析代码实现(Learning OS Concepts By Coding Them !)

30 篇文章 21 订阅

0 回顾

  • 回顾了在磁盘上是怎么抽象成目录的
  • 让目录真的能落实到磁盘

在这里插入图片描述


1 目录解析

1.1 open

  • open就是根据FCB最后形成一条链,把一个文件对应的inode读进来,放在FCB的file数组里面,再和PCB里面的数组接起来,返回fd,fd就是FCB数组的下标
  • 核心就是读入inode,读入inode核心就是在磁盘上找到inode
  • 所以可以想象到,整个open的核心就是找到inode
  • 核心完之后再read,write,fd,inode发出去读写就行

在这里插入图片描述


  • open的内核实现就是sys_open
  • 下方的open_namei,根据名字就可以看出来,就是为了解析这个路径
  • 然后根据filename,把里面的inode拿出来,写到&inode当中进行存储,这和之前讲的知识都是一样的
  • 所以接下来的代码就是要形成这个量
  • 继续往下解析

1.2 get_dir


在这里插入图片描述


  • 首先传递的肯定是路径名
  • 如果路径名只是一个/,那么就代表从根目录开始,看current->root就是根目录的FCB
  • 为什么根目录的FCB直接就是找current->root
  • 首先主磁盘肯定会mount上去,根目录直接shell进去,其他进程都是shell进程的fork,所以其他进程自然会拷贝,所以current->root肯定都会一直有,这样省的每次读FCB第0号位置
  • 不是长成这样就从当前目录开始
  • inr表示目录项中的索引节点号,也就是编号
  • iget就是读下一层目录,这样下一层的inode就有了
  • while(1)一直循环,直到整个目录解析完成

1.3 根目录


在这里插入图片描述


  • init()及其下方的代码就是挂载硬盘
  • 挂载这个硬盘就会mount_root(),把根目录也挂载进来
  • 根目录怎么挂载进来呢?就是调用igetiget()就是得到root_ino根目录所对应的inode编号
  • 根据inode编号就可以把根目录读进来
  • 一旦把根目录读进来,也就是把根目录的FCB读进来,也就是inode
  • 读进来inode再赋值给root,剩下的通过fork继承
  • 每个进程FCB的root就都是根目录的FCB也就是inode
mi = iget(ROOT_DEV, ROOT_INO);
current->root = mi;
  • 以上代码就是刚刚文字描述的内容

1.4 iget


在这里插入图片描述


  • read_inode
  • 首先是get_super
  • 要想找到某一项,就得换算出前面有多长,参考之前的内容,比如说盘块号要知道起始盘块号,再相加
  • 一旦知道盘块号,就可以读磁盘了,读磁盘一定要知道盘块号
  • 为了知道长度就得知道i节点位图以及盘块位图(超级块)有多长,所以必须get_super
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num - 1) / INODES_PER_BLOCK;
  • 为什么加2呢?因为引导块占一块超级块占一块
  • 所以从2开始,往下走
  • s_imap_blocks就是inode的位图的block
  • 加上s_zmap_blocks就是盘块位图,就从引导块到盘块位图全部加上了
  • inode->i_num就是你要读的那个盘块号
  • 这样就算出来了当前的盘块号

1.5 find_entry


在这里插入图片描述


  • 找到目录项
  • 这就是读目录,找到var旁边的那个数字编号
  • 根据inode一项一项读进来
  • 首先找到直接索引块,这个数据块去读
  • 读完以后把bh->b_data给取出来
  • 然后挨个的去匹配,去看能不能匹配成var
  • 能匹配上直接返回,不能匹配就继续循环
  • 一旦匹配完成目录项就有了
  • 目录项有了就能找到inode编号,编号有了就用iget去读出inode,然后不断循环就行

1.6 while(i<entries)


在这里插入图片描述


  • 扫描全部的目录项,再去匹配var
  • 所以还要看bmap
  • 有的项可能在直接索引项上,有的可能在一阶/二阶间接索引上,所以循环不断扫描
  • 现在就知道目录怎么解析了

2 总结


在这里插入图片描述


  • 完结撒花,感谢自己一路坚持过来没有放弃,感谢李治军老师这么优秀的课程,勿在浮沙筑高台,与君共勉!

在这里插入图片描述


在这里插入图片描述


  • 感谢老师!!!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <rtthread.h> #include <rtdevice.h> #include "ft6236.h" #include "touch.h" #include "drv_common.h" #include <rttlogo.h> #include "drv_spi_ili9488.h" #define DBG_TAG "ft6236_example" #define DBG_LVL DBG_LOG #include <rtdbg.h> rt_thread_t ft6236_thread; rt_device_t touch; void ft6236_thread_entry(void *parameter) { struct rt_touch_data *read_data; rt_uint16_t touch_x,touch_y; rt_uint8_t i; read_data = (struct rt_touch_data *)rt_calloc(1, sizeof(struct rt_touch_data)); while(1) { rt_device_read(touch, 0, read_data, 1); if (read_data->event == RT_TOUCH_EVENT_DOWN) { rt_kprintf("down x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate); rt_kprintf(" t: %d\n", read_data->timestamp); for(i=0;i<13;i++)//计算落子的x坐标 { if(abs((read_data->y_coordinate)-(16+24*i))<12) { touch_x=16+24*i; break; } } for(i=0;i<13;i++)//计算落子的y坐标 { if(abs((320-(read_data->x_coordinate))-(16+24*i))<12) { touch_y=16+24*i; break; } } //落子 lcd_show_image(touch_x-12, touch_y-12, 24, 24, acwhite); } if (read_data->event == RT_TOUCH_EVENT_MOVE) { rt_kprintf("move x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate); rt_kprintf(" t: %d\n", read_data->timestamp); } if (read_data->event == RT_TOUCH_EVENT_UP) { rt_kprintf("up x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate); rt_kprintf(" t: %d\n\n", read_data->timestamp); } rt_thread_delay(10); } } #define REST_PIN GET_PIN(D, 3) int ft6236_example(void) { struct rt_touch_config cfg; cfg.dev_name = "i2c2"; rt_hw_ft6236_init("touch", &cfg, REST_PIN); touch = rt_device_find("touch"); rt_device_open(touch, RT_DEVICE_FLAG_RDONLY); struct rt_touch_info info; rt_device_control(touch, RT_TOUCH_CTRL_GET_INFO, &info); LOG_I("type :%d", info.type); LOG_I("vendor :%d", info.vendor); LOG_I("point_num :%d", info.point_num); LOG_I("range_x :%d", info.range_x); LOG_I("range_y :%d", info.range_y); ft6236_thread = rt_thread_create("touch", ft6236_thread_entry, RT_NULL, 800, 10, 20); if (ft6236_thread == RT_NULL) { LOG_D("create ft6236 thread err"); return -RT_ENOMEM; } rt_thread_startup(ft6236_thread); return RT_EOK; } INIT_APP_EXPORT(ft6236_example);
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值