ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第七、八章学习笔记

2021-10-09 21:04:41  阅读:175  来源: 互联网

标签:count 文件 八章 第七 分区 fbuf 笔记 u32 size


7.1文件操作级别

文件操作分为五个级别:

(1)硬件级别:

  • fdisk:将硬件、U盘或SDC盘分区。
  • mkfs:格式化磁盘分区,为系统做好准备。
  • fsck:检查和维修系统。
  • 碎片整理:压缩文件系统中的文件

(2)操作系统中的文件系统函数:每个操作系统内核均可为基本文件操作提供支持。
(3)系统调用:用户模式程序使用系统调用来访问内核函数。
(4)I/O库函数:
(5)用户命令:mkdir、cd、rm、touch、cat等命令,用户使用命令进行文件操作
(6)sh脚本

 

7.2 文件I/O操作

(1)用户模式下的程序执行操作

FILE *fp = fopen("file","r");
or
FILE *fp = fopen("file","w")

 

(2) fopen()在用户( heap)空间中创建一个FILE结构体,包含一个文件描述符fd、一个fbuf [BLKSIZE]和一些控制变量。

(3) fread(ubuf, size, nitem, fp):将nitem个size字节读取到ubuf上,通过:·将数据从FILE结构体的fbuf上复制到ubuf上,若数据足够,则返回。·如果 fbuf没有更多数据,则执行(4a)。

(4a)发出read(fd,fbuf, BLKSIZE)系统调用,将文件数据块从内核读取到 fbuf上,然后将数据复制到ubuf上,直到数据足够或者文件无更多数据可复制。

(4b) fwrite(ubuf, size, nitem, fp):将数据从ubuf复制到fbuf。·若(fbuf有空间):将数据复制到fbuf 上,并返回。若(fbuf已满):发出 write(fd,fbuf,BLKSIZE)系统调用,将数据块写入内核,然后再次写入fbuf。这样,fread()/fwrite()会向内核发出read(/write)系统调用,但仅在必要时发出,而且它们会以块集大小来传输数据,提高效率。

(5)内核中的文件操作:假设非特殊文件的 read(fd, fbuf[ ], BLKSIZE)系统调用。

(6)在read()系统调用中,fd是一个打开的文件描述符,它是运行进程的f数组中的一个索引,指向一个表示打开文件的OpenTable。

(7)OpenTable包含文件的打开模式、一个指向内存中文件INODE的指针和读/写文件的当前字节偏移量。从 OpenTable的偏移量,计算逻辑块编号1bk。通过INODE.i_block[ ]数组将逻辑块编号转换为物理块编号blk。

(8) Minode包含文件的内存 INODE。EMODE.i_block[ ]数组包含指向物理磁盘块的指针。文件系统可使用物理块编号从磁盘块直接读取数据或将数据直接写入磁盘块,但将会导致过多的物理磁盘I/O。

(9)为提高磁盘IO效率,操作系统内核通常会使用一组IO缓冲区作为高速缓存,以减少物理I/O的数量。

(9a)对于read(fd, buf, BLKSIZE)系统调用,要确定所需的(dev,blk)编号,然后查询I/O缓冲区高速缓存。

 

.get a buffer = (dev,blk);
.if(buffer's data are invalid){
   start_io on buffer;
   wait for I/O completion;
}
.copy data from buffer to fbuf";
.release buffer to buffer cache;

 

(9b)对于write(fd, fbuf, BLKSIZE)系统调用,要确定需要的(dev,blk)编号,然后查询I/O缓冲区高速缓存。

 

.get a buffer =(dev, b1k) ;
 write data to the I/O buffer ;
. mark buffer as dataValid and DIRTY(for delay-write to disk);
. release the buffer to buffer cache;

 

(10)设备I/O:Io缓冲区上的物理IO最终会仔细检查设备驱动程序,设备驱动程序由上半部分的start_io()和下半部分的磁盘中断处理程序组成。

7.3低级别文件操作

7.3.1分区

一个块存储设备,如硬盘、U盘、SD卡等,可以分为几个逻辑单元,称为分区。各分区均可以格式化为特定的文件系统,也可以安装在不同的操作系统上。大多数引导程序,如GRUB、LILO等,都可以配置为从不同的分区引导不同的操作系统。表有4个条目,每个条目由一个16字节的分区结构体定义,可以分为几个逻辑单元,称为分区。表有4个条目,每个条目由一个16字节的分区结构体定义,即:

struct partition {
u8 drive; // 0x80 - active
u8 head; // starting head
u8 sector; // starting sector
u8 cylinder; // starting cylinder
u8 sys_type; // partition type
u8 end_head; // end head
u8 end_sector; // end sector

u8 end_cylinder; // end cylinder u32 start_sector; // starting sector counting from 0 u32 nr_sectors; // number of sectors in partition };

在Linux下进行的创建mydisk的虚拟磁盘映像文件

 

 

 

 

 

 

 

 

 7.3.2格式化分区

  • fdisk只将一个存储设备划分为多个分区。每个分区都有特定的文件系统类型,但是分区还不能使用。为了存储文件,必须先为特定的文件系统准备好分区。该操作习惯上称为格式化磁盘或磁盘分区。在Linux中,它被称为mkfs,表示Make文件系统。Linux支持多种不同类型的文件系统。每个文件系统都期望存储设备上有特定的格式。在Linux中,命令:
    mkfs -t TYPE [-b bsize] device nblocks

    在一个nblocks设备上创建一个TYPE文件系统,每个块都是bsize字节。如果bsize未指定,则默认块大小为1KB。具体来说,假设是EXT2/3文件系统,它是Linux的默认文件系统。因此,
    mkfs -t ext2 vdisk 1440 or mke2fs vdisk 1440

挂载分区:man 8 losetup:显示用于系统管理的losetup 实用工具命令:
(1)用dd命令创建-一个虚拟磁盘映像:

dd if=/dev/zero of=vdisk bs=1024 count=32768 #32K (1KB) blocks

(2)在vdisk. 上运行fdisk来创建一一个分区P1:

fdisk vdisk

输人n(new)命令,使用默认的起始和最后扇区编号来创建一个分区Pl。然后,输人w命令将分区表写人vdisk并退出fdisko vdisk 应包含-个分区P1 [start=2048, end=65535]。该分区的大小是63488个扇区。
(3)使用以下扇区数在vdisk的分区1上创建一个循环设备 :

losetup -o $(expr 2048 * 512) --sizelimit $(expr 65535 * 512) /dev/1oop1vdisk

losetup需要分区的开始字节(start_ sector512) 和结束字节(end_ sector512)。 读者可手动计算这些数值,并在losetup命令中使用它们。可用类似方法设置其他分区的循环设备。循环设备创建完成后,读进程可以使用命令
losetup - a 将所有循环设备显示为/dev/loopN。
(4)格式化/dev/loop1,它是一个EXT2文件系统:

mke2fs -b 4096 /dev/loop1 7936 # mke2fs with 7936 4KB blocks

该分区的大小是63488个扇区。4KB块的扇区大小是63488 /8=7936
(5)挂载循环设备:

mount /dev/ 1oop1 /mnt # mount as loop device

(6)访问作为文件系统一部分的挂载设备:

(cd /mnt; mkdir bin boot dev etc user) # populate with DIRs

(7)设备使用完毕后,将其卸载。

umount /mnt

(8)循环设备使用完毕后,通过以下命令将其断开:

losetup -a /dev/loop1 # detach a loop device.

7.4.2超级快

struct ext2_super_block {
u32 s_inodes_count; // Inodes count
u32 s_blocks_count; // Blocks count
u32 s_r_blocks_count; // Reserved blocks count
u32 s_free_blocks_count; // Free blocks count
u32 s_free_inodes_count; // Free inodes count
u32 s_first_data_block; // First Data Block
u32 s_log_block_size; // Block size
u32 s_log_cluster_size; // Allocation cluster size
u32 s_blocks_per_group; // # Blocks per group
u32 s_clusters_per_group; // # Fragments per group
u32 s_inodes_per_group; // # Inodes per group
u32 s_mtime; // Mount time
u32 s_wtime; // Write time
u32 s_mnt_count; // Mount count
u16 s_max_mnt_count; // Maximal mount count
u16 s_magic; // Magic signature
// more non-essential fields
u16 s_inode_size; // size of inode structure
};

第八章 使用系统调用进行文件操作

链接文件分为硬链接文件和软链接文件(符号链接文件)。

硬链接文件:

 

ln oldpath newpath

创建从newpath到oldpath的硬链接,对应的系统调用为

link(char *oldpath,char *newpath)

软链接文件:

ln -s oldpath newpath #ln command with the -s flag

创建从newpath到oldpath的硬链接,对应的系统调用为

symlink(char *oldpath,char *newpath)

write系统调用
write,就是把缓冲区的数据写入文件中。注意,这里的文件时广泛意义的文件,比如写入磁盘、写入打印机等等。
Linux 中write()的函数原型:

size_t write(int fildes, const void *buf, size_t nbytes);

fildes:文件描述符,标识了要写入的目标文件。例如:fildes的值为1,就像标准输出写数据,也就是在显示屏上显示数据;如果为 2 ,则想标注错误写数据。
*buf:待写入的文件,是一个字符串指针。
nbytes:要写入的字符数。

函数返回值:size_t 返回成功写入文件的字符数。需要指出的是,write可能会报告说他写入的字节比你所要求的少。这并不一定是个错误。在程序中,你需要检查
error已发现错误,然后再次调用write写入剩余的数据。

 

read系统调用
系统调用read是从文件中读出数据。要读取的文件用文件描述符标识,数据读入一个事先定义好的缓冲区。他返回实际读入的字节数。
Linux中read的函数原型:

size_t read(int fildes, void *buf, size_t nbytes);

fildes:文件描述符,标识要读取的文件。如果为0,则从标准输入读数据。类似于scanf()的功能。
*buf:缓冲区,用来存储读入的数据。
nbytes:要读取的字符数。

返回值:size_t返回成功读取的字符数,它可能会小于请求的字节数。

 

 

系统调用open的作用是打开一个文件,并返回这个文件的描述符。
简单地说,open建立了一条到文件或设备的访问路径。如果操作成功,它将返回一个文件描述符,read和write等系统调用使用该文件描述符对文件或
设备进行操作。这个文件描述符是唯一的,他不会和任何其他运行中的进程共享。如果两个程序同时打开一个文件,会得到两个不同的问价描述符。

Linux中open的函数原型有两个:

int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode );

path:准备打开的文件或设备名字。
oflags:指出要打开文件的访问模式。

标签:count,文件,八章,第七,分区,fbuf,笔记,u32,size
来源: https://www.cnblogs.com/l993316381-/p/15379940.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有