-
open-cas-linux:打开CAS Linux-源码
2021-02-17 00:54:38Open CAS通过将活动(热)数据缓存到服务器内部的本地闪存设备来加速Linux应用程序。 Open CAS在服务器级别实现缓存,它利用本地高性能闪存介质作为应用服务器内尽可能靠近CPU的缓存驱动器介质,从而尽可能减少存储... -
列出所有内核_openEuler 内核系列 | Linux内核源码结构
2020-12-22 14:33:32作者:罗宇哲,中国科学院软件研究所智能软件研究中心原文链接:http://suo.im/60R7Mb在上一期中,我们介绍...我们将先根据 Linux 源码的目录结构进行分析,到本文章发布前,Linux 4.19 的最新版本为 Linux 4.19.94,...作者:罗宇哲,中国科学院软件研究所智能软件研究中心
原文链接:http://suo.im/60R7Mb
在上一期中,我们介绍了 Linux 内核发展的历史,也介绍了与其相关的 UNIX 和 GNU 的相关知识。从这一期开始,我们将介绍 Linux 内核的源码结构。我们将先根据 Linux 源码的目录结构进行分析,到本文章发布前,Linux 4.19 的最新版本为 Linux 4.19.94,我们将依据 openEuler 开源社区源码并参考 Linux 4.19.94 版内核源码进行分析。
Linux 内核源码的目录结构分析
下图列出了截至文章发表前 openEuler 开源社区 kernel 目录下的目录结构[1]:
其中各个文件夹中源代码的功能如下表所示[2]:
目录/文件名 源码功能简介 /Documentation
说明文档,对每个目录的具体作用进行说明。 /arch
不同 CPU 架构下的核心代码。其中的每一个子目录都代表 Linux 支持的 CPU 架构。 /block
块设备通用函数。 /certs
与证书相关。 /crypto
常见的加密算法的 C 语言实现代码,譬如 crc32、md5、sha1 等。 /drivers
内核中所有设备的驱动程序,其中的每一个子目录对应一种设备驱动。 /include
内核编译通用的头文件。 /init
内核初始化的核心代码。 /ipc
内核中进程间的通信代码。 /kernel
内核的核心代码,此目录下实现了大多数 Linux 系统的内核函数。与处理器架构相关的内核代码在 /kernel/$ARCH/kernel
。/lib
内核共用的函数库,与处理器架构相关的库在 /kernel/$ARCH/lib
。/mm
内存管理代码,譬如页式存储管理内存的分配和释放等。与具体处理器架构相关的内存管理代码位于 /arch/$ARCH/mm
目录下。/net
网络通信相关代码。 /samples
示例代码。 /scripts
用于内核配置的脚本文件,用于实现内核配置的图形界面。 /security
安全性相关的代码。 /sound
与音频有关的代码,包括与音频有关的驱动程序[3]。 /tools
Linux 中的常用工具。 /usr
该目录中的代码为内核尚未完全启动时执行用户空间代码提供了支持。 /virt
此文件夹包含了虚拟化代码,它允许用户一次运行多个操作系统。 COPYING
许可和授权信息。 CREDITS
贡献者列表。 Kbuild
内核设定脚本,可以对内核中的变量进行设定。 Kconfig
配置哪些文件编译,那些文件不用编译[4]。 Makefile
该文件将编译参数、编译所需的文件和必要的信息传给编译器。 二、结语
本期我们根据 openEuler 的目录,并参考 Linux 目录结构简要介绍了 openEuler kernel 中各个子目录的功能,下一期我们将结合 Linux 内核的 Kernel Map 介绍Linux 内核的基本功能和抽象层级。
参考资料
[1]目录结构: https://gitee.com/openeuler/kernel
[2]下表所示: https://www.cnblogs.com/CaesarTao/p/10600462.html
[3]驱动程序: http://blog.chinaunix.net/uid-30374564-id-5571674.html
[4]编译: https://blog.csdn.net/jianwen_hi/article/details/53398141
-
linux的open,write源码何在?
2013-12-29 22:45:24linux下面的open和write源码在哪来,当然这个源码就是glibc,glibc在编译器中直接以库形式面向用户。 那简单的open其实也会有一个执行过程,在glibc里面有他的源码,最终是做一个SWI软中断的汇编执行过程,调用...linux下面的open和write源码在哪来,当然这个源码就是glibc,glibc在编译器中直接以库形式面向用户。
那简单的open其实也会有一个执行过程,在glibc里面有他的源码,最终是做一个SWI软中断的汇编执行过程,调用寄存器。这个过程执行完后,就触发了内核进行系统调用sys_xxx的执行。故glibc里面为系统调用创建条件,一个SWI触发系统调用。
-
linux内核源码下载
2019-05-14 18:08:15linux kernel open source code download ftp: http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/ 官网: https://www.kernel.org/linux kernel open source code download
ftp:
http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/ -
Linux内核源码分析--打开块设备文件--open_bdev_excl函数
2016-10-13 16:17:02本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析内核文件子系统中的打开设备文件函数,梳理了关于内核块...3、源码摘自Linux内核2.6.11.1版 1、open_bdev_excl 函数功能: 打开设备名为path的本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析内核文件子系统中的打开设备文件函数,梳理了关于内核块设备文件打开的处理流程。
注意:
1、不描述内核同步、错误处理相关的内容
2、参考信息除具体说明外,包含在《深入理解Linux内核》第三版中
3、源码摘自Linux内核2.6.11.1版
1、open_bdev_excl
函数功能:
打开设备名为path的块设备,返回块设备描述符的地址
函数参数:
Path:块设备文件的路径名(如:/dev/sda1);
Flags:mount系统调用的的flag参数
Holder: 指向类型为file_system_type的文件系统类型对象的指针
函数源码及处理流程:
struct block_device*open_bdev_excl(const char *path, int flags, void *holder)
{
structblock_device *bdev;
mode_tmode = FMODE_READ;
interror = 0;
bdev= lookup_bdev(path);
if(IS_ERR(bdev))
returnbdev;
if(!(flags & MS_RDONLY))
mode|= FMODE_WRITE;
error= blkdev_get(bdev, mode, 0);
if(error)
returnERR_PTR(error);
error= -EACCES;
if(!(flags & MS_RDONLY) && bdev_read_only(bdev))
gotoblkdev_put;
error= bd_claim(bdev, holder);
if(error)
gotoblkdev_put;
returnbdev;
blkdev_put:
blkdev_put(bdev);
returnERR_PTR(error);
}
函数处理流程:
1、调用lookup_bdev函数,根据设备文件名path,查找或分配一个block_device对象,地址存入局部变量bdev中
2、根据flags参数设置文件系统权限为只读(FMODE_READ)或读写(FMODE_READ| FMODE_WRITE)
3、调用blkdev_get函数,初始化bdev中和分区、磁盘相关的数据,参见后面分析
4、调用bd_claim函数,更新bdev对象和其包含对象的持有者信息
2、lookup_bdev
函数功能:
打开或查找设备名为path的块设备。
函数参数:
略
函数源码:
/**
* lookup_bdev - lookup a struct block_device by name
*
* @path: specialfile representing the block device
*
* Get a reference to the blockdevice at @pathin the current
* namespace if possible and return it. Return ERR_PTR(error)
* otherwise.
*/
struct block_device *lookup_bdev(constchar *path)
{
structblock_device *bdev;
structinode *inode;
structnameidata nd;
interror;
if(!path || !*path)
returnERR_PTR(-EINVAL);
error= path_lookup(path, LOOKUP_FOLLOW, &nd);
if(error)
returnERR_PTR(error);
inode= nd.dentry->d_inode;
error= -ENOTBLK;
if(!S_ISBLK(inode->i_mode))
gotofail;
error= -EACCES;
if(nd.mnt->mnt_flags & MNT_NODEV)
gotofail;
error= -ENOMEM;
bdev= bd_acquire(inode);
if(!bdev)
gotofail;
out:
path_release(&nd);
returnbdev;
fail:
bdev= ERR_PTR(error);
gotoout;
}
函数处理流程:
1、调用path_lookup函数(参见p495“路径名查找”),查找块设备文件名对应的nameidata对象并存入nd局部变量中,设备文件对应的节点对象地址存入inode类型的inode局部变量中
2、调用bd_acquire函数,打开或查找设备文件名为path的块设备,返回块设备描述符
3、blkdev_get
函数功能:
初始化块设备描述符中和分区、磁盘相关的字段
函数参数:
略
函数源码:
int blkdev_get(struct block_device*bdev, mode_t mode, unsigned flags)
{
/*
* This crockload is due to bad choice of->open() type.
* It will go away.
* For now, block device ->open() routinemust _not_
* examine anything in 'inode' argument except->i_rdev.
*/
structfile fake_file = {};
structdentry fake_dentry = {};
fake_file.f_mode= mode;
fake_file.f_flags= flags;
fake_file.f_dentry= &fake_dentry;
fake_dentry.d_inode= bdev->bd_inode;
returndo_open(bdev, &fake_file);
}
static int do_open(struct block_device*bdev, struct file *file)
{
structmodule *owner = NULL;
structgendisk *disk;
intret = -ENXIO;
intpart;
file->f_mapping= bdev->bd_inode->i_mapping;
lock_kernel();
disk= get_gendisk(bdev->bd_dev, &part);
if(!disk) {
unlock_kernel();
bdput(bdev);
returnret;
}
owner= disk->fops->owner;
down(&bdev->bd_sem);
if(!bdev->bd_openers) { //第一次打开
bdev->bd_disk= disk;
bdev->bd_contains= bdev;
if(!part) { //如果不是分区,是磁盘
structbacking_dev_info *bdi;
if(disk->fops->open) {
ret= disk->fops->open(bdev->bd_inode, file);
if (ret)
gotoout_first;
}
if(!bdev->bd_openers) { //第一次打开
bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
bdi= blk_get_backing_dev_info(bdev); //磁盘的IO数据流量的信息,如预读和请求队列拥塞状态的信息
if(bdi == NULL)
bdi= &default_backing_dev_info;
bdev->bd_inode->i_data.backing_dev_info= bdi;
}
if(bdev->bd_invalidated)
rescan_partitions(disk,bdev);
}else { //如果是分区
structhd_struct *p;
structblock_device *whole;
whole= bdget_disk(disk, 0);
ret= -ENOMEM;
if(!whole)
gotoout_first;
ret= blkdev_get(whole, file->f_mode, file->f_flags);//对磁盘递归了
if(ret)
gotoout_first;
bdev->bd_contains= whole; //包含分区的块设备
down(&whole->bd_sem);
whole->bd_part_count++;//块设备中的打开的分区数
p= disk->part[part - 1];//分区表描述符
bdev->bd_inode->i_data.backing_dev_info=
whole->bd_inode->i_data.backing_dev_info;磁盘的IO数据流量的信息,如预读和请求队列拥塞状态的信息
if(!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) {//磁盘将被初始化、分区描述符为空、分区中的扇区数为0
whole->bd_part_count--;
up(&whole->bd_sem);
ret= -ENXIO;
gotoout_first;
}
kobject_get(&p->kobj);
bdev->bd_part= p;
bd_set_size(bdev,(loff_t) p->nr_sects << 9);
up(&whole->bd_sem);
}//endfor else { //如果是分区
}else { //if (!bdev->bd_openers)
put_disk(disk);
module_put(owner);
if(bdev->bd_contains == bdev) { //不是分区
if(bdev->bd_disk->fops->open) {
ret= bdev->bd_disk->fops->open(bdev->bd_inode, file);
if(ret)
gotoout;
}
if(bdev->bd_invalidated)
rescan_partitions(bdev->bd_disk,bdev);
}else { //是分区
down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++;
up(&bdev->bd_contains->bd_sem);
}
}
bdev->bd_openers++;
up(&bdev->bd_sem);
unlock_kernel();
return0;
out_first:
bdev->bd_disk= NULL;
bdev->bd_inode->i_data.backing_dev_info= &default_backing_dev_info;
if(bdev != bdev->bd_contains)
blkdev_put(bdev->bd_contains);
bdev->bd_contains= NULL;
put_disk(disk);
module_put(owner);
out:
up(&bdev->bd_sem);
unlock_kernel();
if(ret)
bdput(bdev);
returnret;
}
函数处理流程:
从源码可以看出,blkdev_get把相关参数放入file对象后,调用do_open函数完成具体的处理工作,do_open函数的处理流出如下:
1、把file的地址空间初始化为块设备在bdev文件系统中的索引节点的地址空间
2、根据块设备文件的标识符,调用函数get_gendisk返回类型为gendisk磁盘描述符和块设备对应的分区索引(从1开始,0表示打开的块设备是一个磁盘)
3、剩下的处理流出参见代码注释
4、bd_claim
函数功能:
更新bdev对象和其包含对象的持有者信息
函数参数:
略
函数源码:
int bd_claim(struct block_device *bdev,void *holder)
{
intres;
spin_lock(&bdev_lock);
/*first decide result */
if(bdev->bd_holder == holder)
res= 0; /* already a holder */
elseif (bdev->bd_holder != NULL)
res= -EBUSY; /* held by someone else */
elseif (bdev->bd_contains == bdev)
res= 0; /* is a whole device which isn't held */
elseif (bdev->bd_contains->bd_holder == bd_claim)
res= 0; /* is a partition of a device that is beingpartitioned */
elseif (bdev->bd_contains->bd_holder != NULL)
res= -EBUSY; /* is a partition of a helddevice */
else
res= 0; /* is a partition of an un-helddevice */
/*now impose change */
if(res==0) {
/*note that for a whole device bd_holders
* will be incremented twice, and bd_holderwill
* be set to bd_claim before being set toholder
*/
bdev->bd_contains->bd_holders++;
bdev->bd_contains->bd_holder= bd_claim;
bdev->bd_holders++;
bdev->bd_holder= holder;
}
spin_unlock(&bdev_lock);
returnres;
}
函数处理流程:
从代码可见,在两种情况下(1、bdev->bd_holder不等于holder且不为空时,即bdev 有其它持有者2、bdev->bd_contains->bd_holder不等于bd_claim且不为空时,即bdev->bd_contains的持有者不为bd_claim)返回错误;在三种情况下(1、bdev->bd_holder为holder,即bdev的持有者再次持有2、bdev->bd_contains等于bdev,即bdev是整个磁盘描述符且没有持有者3、bdev->bd_contains->bd_holder等于bd_claim)
5、bd_acquire
函数功能:
打开或查找设备文件名为path的块设备,返回块设备描述符。
函数参数:
inode:块设备文件的路径名的设备节点。
函数源码:
static struct block_device*bd_acquire(struct inode *inode)
{
structblock_device *bdev;
spin_lock(&bdev_lock);
bdev= inode->i_bdev;
if(bdev && igrab(bdev->bd_inode)) {
spin_unlock(&bdev_lock);
returnbdev;
}
spin_unlock(&bdev_lock);
bdev= bdget(inode->i_rdev);
if(bdev) {
spin_lock(&bdev_lock);
if(inode->i_bdev) //如果块设备文件对应的索引节点已与另外一个块设备描述符相关联,消除关联
__bd_forget(inode);
inode->i_bdev= bdev; //块设备描述符
inode->i_mapping= bdev->bd_inode->i_mapping; //块设备在bdev文件系统中的索引节点的地址空间对象的地址
list_add(&inode->i_devices,&bdev->bd_inodes); //把索引节点加入块设备描述符的索引节点链表
spin_unlock(&bdev_lock);
}
returnbdev;
}
函数处理流程:
1、把inode的i_bdev存放在类型为block_device的局部变量bdev中,如果bdev不为NULL(即块设备文件已经被打开),通过调用函数igrab增加bdev->bd_inode索引节点的引用计数器,并返回bdev
2、如果bdev等于NULL或该节点已被释放(igrab返回零值),调用bdget函数获取块设备描述符的地址,具体流程参见下面描述
3、如果成功获取块设备描述符(bdev不等于NULL),处理流出参见代码注释
6、bdget
函数功能:
根据块设备文件对应的设备标识符,在bdev文件系统中查找或新建一个索引节点、块设备描述符,返回块设备描述符的地址
函数参数:
dev:块设备文件对应的设备标识符(含主设备号和次设备号)
函数源码:
struct block_device *bdget(dev_t dev)
{
structblock_device *bdev;
structinode *inode;
inode= iget5_locked(bd_mnt->mnt_sb, hash(dev),
bdev_test,bdev_set, &dev);
if(!inode)
returnNULL;
bdev= &BDEV_I(inode)->bdev;
if(inode->i_state & I_NEW) {
bdev->bd_contains= NULL; // bdev是特殊块设备文件系统的超级块,所以该对象初始化为NULL
bdev->bd_inode= inode; //bdev文件系统中的索引节点
bdev->bd_block_size= (1 << inode->i_blkbits); //块的字节大小,默认是1024,参见函数get_sb_pseudo
bdev->bd_part_count= 0; //分区被打开的次数
bdev->bd_invalidated= 0; //需要读块设备的分区表时设置的标志
inode->i_mode= S_IFBLK; //文件类型与访问权限,块设备
inode->i_rdev= dev; //块设备文件标识符
inode->i_bdev= bdev; //块设备描述符
inode->i_data.a_ops= &def_blk_aops; //bdev块设备文件地址空间的默认操作函数
mapping_set_gfp_mask(&inode->i_data,GFP_USER);//设置bdev文件节点的页分配标志,参见p305
inode->i_data.backing_dev_info= &default_backing_dev_info;
spin_lock(&bdev_lock);
list_add(&bdev->bd_list,&all_bdevs); //把块设备描述符插入块设备描述符全局链表
spin_unlock(&bdev_lock);
unlock_new_inode(inode);
}
returnbdev;
}
函数处理流程:
1、vfsmount*类型的全局变量bd_mnt中,存放类型名为”bdev”的块设备文件系统类型的安装文件系统描述符的地址,调用函数iget5_locked获得与块设备文件标识符对应的在bd_mnt文件系统中的索引节点的地址,存入局部变量inode中,函数的具体分析参加下面具体描述
2、通过宏BDEV_I从inode导出块设备描述符的地址,存入bdev局部变量中
3、如果inode是调用iget5_locked时新分配的索引节点,初始化bdev和inode相关信息,具体信息参见代码注释
7、iget5_locked
函数功能:
函数参数:
sb:
函数源码:
struct inode *iget5_locked(structsuper_block *sb, unsigned long hashval,
int(*test)(struct inode *, void *),
int(*set)(struct inode *, void *), void *data)
{
structhlist_head *head = inode_hashtable + hash(sb, hashval);
structinode *inode;
inode= ifind(sb, head, test, data);
if(inode)
returninode;
/*
* get_new_inode() will do the right thing,re-trying the search
* in case it had to block at any point.
*/
returnget_new_inode(sb, head, test, set, data);
}
函数处理流程:
调用函数ifind从inode_hashtable中查找inode,找到则返回
未找到调用函数get_new_inode
8、get_new_inode
函数功能:
函数参数:
函数源码:
/*
* This is called without the inode lock held..Be careful.
*
* We no longer cache the sb_flags in i_flags -see fs.h
* --rmk@arm.uk.linux.org
*/
static struct inode *get_new_inode(struct super_block *sb, struct hlist_head *head, int(*test)(struct inode *, void *), int (*set)(struct inode *, void *), void*data)
{
structinode * inode;
inode= alloc_inode(sb);
if(inode) {
structinode * old;
spin_lock(&inode_lock);
/*We released the lock, so.. */
old= find_inode(sb, head, test, data);
if(!old) {
if(set(inode, data))
gotoset_failed;
inodes_stat.nr_inodes++;
list_add(&inode->i_list,&inode_in_use);
list_add(&inode->i_sb_list,&sb->s_inodes);
hlist_add_head(&inode->i_hash,head);
inode->i_state= I_LOCK|I_NEW;
spin_unlock(&inode_lock);
/*Return the locked inode with I_NEW set, the
* caller is responsible for filling in thecontents
*/
returninode;
}
/*
* Uhhuh, somebody else created the same inodeunder
* us. Use the old inode instead of the one wejust
* allocated.
*/
__iget(old);
spin_unlock(&inode_lock);
destroy_inode(inode);
inode= old;
wait_on_inode(inode);
}
returninode;
set_failed:
spin_unlock(&inode_lock);
destroy_inode(inode);
returnNULL;
}
函数处理流程:
1、调用alloc_inode函数分配一个新的索引节点,地址存入局部变量inode中
2、获取锁后,调用find_inode函数在inode_hashtable中搜索块设备文件对应的节点,如果未找到则没有其他进程打开该设备文件,调用set初始化块设备描述符的设备标识符字段,把该设备索引节点加入inode_in_use和超级块的索引节点链表,设置索引节点的I_LOCK和I_NEW标识并返回
3、如果已有其他进程打开了该设备文件,增加已打开的索引节点引用计数器,并释放新分配的索引节点,返回找到的索引节点地址
9、alloc_inode
函数功能:
函数参数:
sb:“bdev”块设备的超级块对象指针
函数源码:
static struct inode *alloc_inode(structsuper_block *sb)
{
staticstruct address_space_operations empty_aops;
staticstruct inode_operations empty_iops;
staticstruct file_operations empty_fops;
structinode *inode;
if(sb->s_op->alloc_inode)
inode= sb->s_op->alloc_inode(sb);
else
inode= (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL);
if(inode) {
structaddress_space * const mapping = &inode->i_data;
inode->i_sb= sb; //超级块
inode->i_blkbits= sb->s_blocksize_bits; //块的位数(以位为单位的块的大小)
inode->i_flags= 0; //文件系统安装标志
atomic_set(&inode->i_count,1); //引用计数器
inode->i_sock= 0; //文件是否为套接字,是则非零
inode->i_op= &empty_iops; //节点操作函数
inode->i_fop= &empty_fops; //文件操作函数
inode->i_nlink= 1; //硬链接的数目
atomic_set(&inode->i_writecount,0); //写进程的引用计数器
inode->i_size= 0; //文件字节数
inode->i_blocks= 0; //文件块数
inode->i_bytes= 0; //文件中最后一块的字节数
inode->i_generation= 0; //索引节点版本
#ifdef CONFIG_QUOTA
memset(&inode->i_dquot,0, sizeof(inode->i_dquot)); //索引节点磁盘限额
#endif
inode->i_pipe= NULL; //如果文件是一个管道则使用
inode->i_bdev= NULL; //指向块设备描述符的指针
inode->i_cdev= NULL;//指向字符设备描述符的指针
inode->i_rdev= 0; //设备标识符
inode->i_security= NULL; //指向索引节点安全结构的指针
inode->dirtied_when= 0; //索引节点的弄脏时间,以节拍为单位
if(security_inode_alloc(inode)) { //索引节点分配的安全钩子函数
if(inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
kmem_cache_free(inode_cachep,(inode));
returnNULL;
}
mapping->a_ops= &empty_aops; //文件地址空间操作函数
mapping->host = inode; //文件地址空间持有者
mapping->flags= 0; //错误位和内存分配器的标志
mapping_set_gfp_mask(mapping,GFP_HIGHUSER);//初始化分配器标志,参见p305
mapping->assoc_mapping= NULL;//指向间接块所在块设备的address_space对象的地址
mapping->backing_dev_info= &default_backing_dev_info;
/*
* If the block_device provides abacking_dev_info for client
*inodes then use that. Otherwise theinode share the bdev's
* backing_dev_info.
*/
if(sb->s_bdev) {
structbacking_dev_info *bdi;
bdi= sb->s_bdev->bd_inode_backing_dev_info;
if(!bdi)
bdi= sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
mapping->backing_dev_info= bdi;
}
memset(&inode->u,0, sizeof(inode->u));
inode->i_mapping= mapping;
}
returninode;
}
函数处理流程:
1、如果超级块的操作包含alloc_inode操作函数,调用该函数分配一个索引节点对象,对”bdev”文件系统来说,实现该指针的函数是bdev_alloc_inode,该函数从slab高速缓存bdev_cachep中分配一个bdev_inode对象,并返回其包含的inode对象的地址;如果不包含,从inode_cachep slab高速缓存中分配一个索引节点对象;把对象的地址存入局部变量inode中
2、初始化inode和其address_space对象,具体描述参见代码注释
-
Linux文件操作-open函数(源码解析)
2020-10-14 09:57:45近期在看Linux内核相关,且之前面试有遇到问**“open函数调用原理”**的问题,今天在这里做一下总结记录。 open函数 open函数主要包含以下两类: int open(const char *pathName, int flags); // 打开文件 int open... -
OVR_SLDO:OpenVR简单Linux桌面叠加层-源码
2021-02-12 12:32:26OVR_SLDO OpenVR简单Linux桌面叠加 -
Linux-0.12内核打开文件过程--sys_open源码分析
2014-05-25 20:34:20上图展示了进程打开文件使用的...int sys_open(const char *filename,int flag,int mode) { struct m_inode *inode; struct file *f; int i,fd; mode&=0777&~current->umask; //在filp数组中寻找“空闲位置” -
linux c源码之top源码
2015-02-03 18:16:59* Copyright (c) 2008, The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that -
SDN开发之Linux系统下OpenDaylight源码编译安装和调试
2015-12-27 08:02:44操作系统:Linux x64 / Ubuntu 14.04 研究领域:软件定义网络SDN (Software-defined Networking) 开发组件:OpenDaylight 本文原文链接:... -
linux top 源码分析
2019-10-08 15:42:42/* * Copyright (c) 2008, The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that ... -
Linux内核源码+电子书
2011-02-21 15:13:10电子书+源码 第一章 走进linux 1.1 GNU与Linux的成长 1.2 Linux的开发模式和运作机制 1.3走进Linux内核 1.3.1 Linux内核的特征 1.3.2 Linux内核版本的变化 1.4 分析Linux内核的意义 1.4.1 开发适合自己的... -
linux下安装openrestry_Linux下nginx的yum安装、源码安装、OpenResty的源码安装
2020-12-24 12:31:16Linux下nginx的安装安装环境:# cat /proc/versionLinux version 3.10.0-123.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP Mon Jun 30 12:09:22 ... -
【华为云技术分享】Linux内核源码结构(1)
2020-02-03 17:31:04我们将先根据Linux源码的目录结构进行分析,到本文章发布前,Linux 4.19的最新版本为Linux 4.19.94,我们将依据openEuler开源社区源码并参考Linux 4.19.94版内核源码进行分析。 一、Linux内核源码的目录结构分析 ..... -
阅读 Linux 内核源码——共享内存
2018-04-23 20:13:55现在linux中可以使用共享内存的方式有两种POSIX的shm_open()在/dev/shm/下打开一个文件,用mmap()映射到进程自己的内存地址System V的shmget()得到一个共享内存对象的id,用shmat()映射到进程自己的内存地址PO... -
mount 内核源码_Linux 内核源码分析 -- chroot
2020-12-23 12:54:25chroot 在 内核中的实现在 Linux 5.6 版本中 chroot 函数的系统调用对应的函数位于:./fs/open.c:539:SYSCALL_DEFINE1(chroot, const char __user *, filename)SYSCALL_DEFINE1(chroot, const char __user *, ... -
第五期-Linux内核源码结构(1)
2020-04-03 17:30:37作者:罗宇哲,中国科学院软件研究所智能软件...我们将先根据Linux源码的目录结构进行分析,到本文章发布前,Linux 4.19的最新版本为Linux 4.19.94,我们将依据openEuler开源社区源码并参考Linux 4.19.94版内核源码... -
Open vSwitch(OVS)源码编译Ubuntu16.04,Linux内核版本4.15
2018-12-08 09:02:18Open vSwitch(OVS)源码编译Ubuntu16.04,Linux内核版本4.15 -
This application is open source software for quick and easy installation of the operating system (OS) GNU/Linux on your Android device. The application creates a disk image or a directory on a flash ...
-
Zero issues indicated by Valgrind (Linux), DrMemory (Windows) and Clang AddressSanitizer / MemorySanitizer for the CTT tests, unit tests and fuzzing Documentation and Support A general introduction ...
-
嵌入式系统/ARM技术中的交叉编译qt-embedded-linux-opensource-src-4.5.1源码
2020-11-11 13:29:23软件资源:qt-embedded-linux-opensource-src-4.5.1.tar.gz qt-x11-opensource-src-4.5.1.tar.gz 因为一般嵌入式设备上都是在framebuffer的方式,在X11上就是用qvfb 来模拟framebuffer的,我们平时开发也都... -
OpenAny:用于在Linux上打开类型任意文件的bash脚本-源码
2021-02-23 18:07:52一个bash脚本,用于在Linux上打开任意类型的文件。 执照 用法 您可以获得以下帮助信息: [user@A ~ ]$ opan -h Usage: opan [-h] | [ file [options] ] [-h ]: print this help information. [file ]: name of ... -
虚拟文件系统源码解析之open(基于linux1.2.13)
2019-12-28 00:11:14我们操作一个文件之前都需要先open一下。我们看看open在虚拟文件系统中大致的执行过程。不会分析具体的过程。主要分析一下虚拟文件系统的实现原理。 asmlinkage int sys_open(const char * filename,int flags,int ... -
透明大页相关内核参数_第五期-Linux内核源码结构(1)
2021-01-02 16:25:21作者:罗宇哲,中国科学院软件研究所智能...我们将先根据Linux源码的目录结构进行分析,到本文章发布前,Linux 4.19的最新版本为Linux 4.19.94,我们将依据openEuler开源社区源码并参考Linux 4.19.94版内核源码进... -
第六期-Linux内核源码结构(2)
2020-04-03 17:42:00在上一期中,我们按照openEuler内核的目录结构简要介绍了openEuler内核目录中各个子目录的功能,这一期我们将简要介绍Linux内核的基本功能和抽象层级。 一、Linux内核Kernel Map简介 Linux内核的Kernel Map从功能... -
Linux内核源码阅读之打开文件篇
2013-08-05 10:04:06Linux中打开文件是通过open系统调用实现,其函数中调用了do_sys_open()函数完成打开功能,所以下面主要分析do_sys_open()函数,首先先看下open系统调用的入口函数,再具体看do_sys_open()函数: SYSCALL_DEFINE3... -
交叉编译qt-embedded-linux-opensource-src-4.5.1源码
2009-07-02 09:49:00首先要有配置好的环境,本文使用的编译环境如下: 主机系统:Ubuntu 8.10主机编译器:gcc 版本 4.3.2 交叉编译器:arm-softfloat-linux-gnu-gcc软件资源:qt-embedded-linux-opensource-src-4.5.1.tar.gz qt-x11-...
-
项目经理成长之路
-
libFuzzer视频教程
-
FunnyClips.zip
-
FTP 文件传输服务
-
actions_uart_programming_guide_ATS2851_C11_for_BTMP3_77743f_REL_V1.0.01.pdf
-
mingw-17.1-without-git.exe
-
ABB机器人CCLink 配置.pdf
-
city-picker.rar
-
java 获取目录文件大小
-
Notepad++中查找替换「换行符」
-
工程制图 AutoCAD 2012 从二维到三维
-
朱老师C++课程第3部分-3.6智能指针与STL查漏补缺
-
删除字符串中的字符.zip
-
NFS 网络文件系统
-
2021-02-27
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
Samba 服务配置与管理
-
for的使用例子代码
-
解决MySQL数据库登陆失败1045权限错误
-
用Go语言来写区块链(一)