Unix/Linux系统编程[笔记]

2 编程背景

2.3 程序开发

2.3.1 C 语言变量

image-20210620220047647

  • 静态全局变量只对定义它们的文件可见,非静态全局变量对同一程序的所有文件可见。

2.3.2 程序开发步骤

预处理、编译(.s)、汇编(.o)、链接(.out)

.o 文件的组成
  • 文件头 + 代码段 + 数据段 + BSS + 重定位信息 + 符号表
链接的主要操作
  • 合成各段(代码段、数据段、BSS段)
  • 根据重定位信息调整各段偏移量
  • 用符号表解析各 .o 文件的交叉引用

2.3.2 静态与动态链接

  • 静态:所有库函数都加入 a.out
  • 动态:库函数不存入 a.out,a.out 存放调用指令,然后执行期间按需加载

2.3.3 可执行文件格式

  • 二进制可执行平面文件:仅包含可执行代码和初始化数据。(比如,可启动操作系统映像(简化了引导装载程序))
  • a.out 可执行文件
  • ELF 文件

2.3.4 a.out 的内容

  • 文件头(各段大小) + 代码段 + 数据段 + 符号表

注意:BSS 段不在 a.out 中,只有 BSS 段的大小记录在 a.out 文件头中

2.3.5 程序终止过程

a. 正常终止
  1. 清理工作 exit(value):刷新 stdout,关闭 I/O 流
  2. 系统调用 __exit(value)
    • 记录退出状态
    • 通知父进程,并使该进程称为僵尸进程
    • 父进程 wait 僵尸进程,清空僵尸子进程结构体
b. 异常终止
  1. 陷入操作系统内核
  2. 内核的陷入处理程序将陷入错误类型转换成一个幻数(信号)
  3. 将信号传递给进程,使进程终止

11 EXT2 文件系统

EXT3:增加日志

EXT4:主要变化是磁盘块的分配

11.1 简单的 EXT2 文件系统布局

0 1 2 3-7 8 9 10…32 33…1439
boot(引导块) super(超级块) GB(块组描述符) reserved(保留区) bmap(块位图) imap(索引节点位图) inodes blocks(索引节点块) data blocks(数据块)

11.2 超级块结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct ext2_super_block {
u32 s_inodes_count; /* Inodes count */
u32 s_blocks_ccount; /* 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; /* # Block per group */
u32 s_cluster_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 */
s16 s_max_mnt_count; /* Maximal mount count */
u16 s_magic; /* Magic signature */
// more non-essential fields
u16 s_inode_size; /* size of inode structure */
}
  • 索引节点数目
  • 块数目
  • 起始块地址
  • 文件块大小
  • 已挂载文件系统的次数
  • 幻数(标识文件系统类型)

11.3 块组描述符结构

1
2
3
4
5
6
7
8
9
10
struct ext2_group_desc {
u32 bg_block_bitmap; // 块位图起始块
u32 bg_inode_bitmap; // 索引节点位图起始块
u32 bg_inode_table; // 索引节点起始块
u16 bg_free_blocks_count;
u16 bg_free_inodes_count;
u16 bg_used_dirs_count;
u16 bg_pad;
u16 bg_reserved[3];
}

其中最重要的字段是前三个

11.4 块位图和索引节点位图

11.4.1 块位图 bg_block_bitmap

位图用于表示某种项的位序列,如磁盘块或索引节点。

位图的值 描述
0 对应项处于 FREE 状态
1 对应项处于 IN_USE 状态

11.4.2 索引节点位图 bg_inode_bitmap

索引节点位图是用来代表一个文件的数据结构。EXT2 文件系统是使用有限数量的索引节点创建的,各索引节点的状态用索引节点位图的一个位表示。

在 EXT2 文件系统中,前 10 个索引节点是预留的,所以空 EXT2 FS 的 Imap 以 10 个 1 开头,然后是 0。

11.5 索引节点 bg_inode_table

EXT2 每个文件都用一个 128 字节的唯一索引节点结构体表示(EXT4 是 256 字节)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct ext2_inode {
u16 i_mode; // 16 bits = | tttt | ugs | rwx | rwx | rwx |
u16 i_uid; // owner uid
u32 i_size; // file size in bytes
u32 i_atime; // time fields in seconds
u32 i_ctime; // since 00:00:00,1-1-1970
u32 i_mtime;
u32 i_dtime;
u16 i_gid; // group ID
u16 i_links_count; // hard-link count
u32 i_blocks; // number of 512-byte sectors
u32 i_flags; // IGNORE
u32 i_reserved1; // IGNORE
u32 i_block[15];
u32 i_pad[7]; // for inode size = 128 bytes
}

i_mode

是 16 位无符号数

i_mode 位 tttt ugs rwx rwx rwx
描述 表示文件类型
tttt=1000表示REG文件
0100表示DIR文件
表示文件的特殊用法 表示文件权限 表示文件权限 表示文件权限

各时间字段

这些字段都是用自 1970-1-1 00:00:00 开始经过的秒数表示的,所以每个字段都是极大的无符号整数,可以借助库函数char *ctime(&time_field);将其转为日历形式。

1
printf("%s", ctime(&inode.i_atime));

i_block[15]

包含指向文件磁盘块的指针,如

  • 直接块:i_block[0] 至 i_block[11],指向直接磁盘块
  • 间接块:i_block[12]
  • 双重间接块:i_block[13]
  • 三重间接块:i_block[14]

11.6 数据块

紧跟在索引节点块后面的是文件存储数据块,假设有 184 个索引节点,第一个实际数据块是 B33,它就是根目录 / 的i_block[0]。



----------- 本文结束 -----------




0%