Linux下实现一个系统调用

环境: 环境: cenos7 kernel: 3.10.0-862.el7.x86_64 gcc: gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 新版内核: linux-5.2-rc2 准备: 安装相关软件: yum install make automake vim perl openssl* elfutils-libelf- curl gcc wget flex git build-essential ncurses-devel xz-utils libssl-dev bc flex libelf-dev bison elfutils-libelf-devel -y 下载内核源码并解压: tar -xf linux-5.2-rc2.tar.gz 编写系统调用: 新增系统调用表条目: cp syscall_64.tbl syscall_64.tbl.backup linux-5.2-rc2/arch/x86/entry/syscalls/syscall_64.tbl 新增下面一条 + 434 common iadd_test __x64_sys_iadd_test 其中434为新增的调用号 增加函数声明 linux-5.2-rc2/include/linux/syscalls.h:新增一行 asmlinkage long sys_iadd_test(int one, int two); 新增系统调用定义 kernel/linux-5.2-rc2/fs/iadd_test.c #include <linux/printk.h> #include <linux/syscalls.h> #include "internal.h" long do_iadd(const int one, const int two ) { long sum = 0L; sum = one + two; return sum; } SYSCALL_DEFINE2(iadd_test, const int, one, const int, two) { printk("call iaddtest..."); return do_iadd(one, two); } 修改Makfile 增加iadd_test.o ...

2019-06-02 · 2 min · 342 words

linux内核中的进程列表

Linux链表数据结构及相关操作 定义 /include/linux/types.hstruct list_head { struct list_head *next, *prev; };与响应的结构组成双向链表。 初始化 /include/linux/list.h#define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) 方法 插入 static inline void list_add(struct list_head *new, struct list_head *head)static inline void list_add_tail(struct list_head *new, struct list_head *head) 删除 static inline void list_del(struct list_head *entry) 替换 static inline void list_replace(struct list_head *old, struct list_head *new) 交换 static inline void list_swap(struct list_head *entry1, struct list_head *entry2) 删除 static inline void list_move(struct list_head *list, struct list_head *head) 遍历 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) 获取节点某一成员 #define list_entry(ptr, type, member) \ container_of(ptr, type, member) 以上是基于2.4内核版本的宏, 2.6版本后引入RCU新的锁机制,相关宏定义后新增_rcu. ...

2019-05-26 · 3 min · 535 words

grub2 配置centos7,ubuntu

 一 虚拟机安装centos7,ubuntu配置grub2启动 1. 环境准备及安装 1. VMWARE 安装centos7 , 参考鸟哥私房菜第三章 2. 下载了Ubuntu最新的server版本。 3. 虚拟机增加硬盘(选用默认SCSI类型),安装 Ubuntu19, Ubuntu镜像文件挂载到VMWARE的CDROM。 4. VMWARE重启后按F12,修改BIOS中的Boot菜单项的启动顺序, 将CDROM上移到Hard disk上。 5. 重启虚拟机安装提示安装, 将Ubuntu安装到新增加的硬盘上。我安装 Ubuntu 按照LVM方式进行分区。 2. 配置 boot loader 软件grub2: 下面使用两种方式配置下grub2: 1). 通过grub2-mkconfig 自动扫描: 先看下本地磁盘的信息使用 lsblk命令 [root@centosgpt grub.d]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk ├─sda1 8:1 0 2M 0 part ├─sda2 8:2 0 1G 0 part /boot ├─sda3 8:3 0 59G 0 part ...

2019-05-16 · 5 min · 972 words

gethostbyname函数实现分析

DNS : DNS是一个分层级 (hierarchical ),分布式(decentralized)的网络数据库,完成主机名称和IP地址之间的相互映射。DNS名称空间包含一个树状结构,树根没有命名, 下面是树的最高层为顶级域名, 顶级域名包括: 顶级域名(gTLD),国家代码顶级域名(ccTLD), 国际化国家设施顶级域名(infrastructure TLD), 下面一层是权威域名服务器。其中权威域名服务器对DNS请求进行应答返回IP地址。 图片来自DNS wiki DNS协议: dns协议包含两部分: 1. 对DNS特定名称查询的查询、响应协议 2. 名称服务器用户交换数据库记录的协议(区域传输) 应用访问DNS通过地址解析器(resolver), 通常通过TCP,UDP协议通讯是需要将主机名转换为IPv4, IPv6地址。 gethostbname: 需要socket通过域名方式完成连接 , 可以通过API gethostbyname 函数完成。gethostbyname 函数是 glibc 库中提供一个域名解析的函数。 调用方法也相对简单,存在问题是范围结果是 static 类型变量,存在数据被覆盖的情况。 函数定义: #include <netdb.h> extern int h_errno; struct hostent *gethostbyname(const char *name); The hostent structure is defined in <netdb.h> as follows: struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ } #define h_addr h_addr_list[0] /* for backward compatibility */ DEMO程序: ...

2019-05-11 · 5 min · 969 words

编程规范问题导致SIGCLD 屏蔽失效

 进程出现状态进程,(zombie process )。对于创建多进程的场景, 子进程状态改变产生此信号, 对SIGCLD信号处理不当,会导致僵尸进程。 SIGCLD 是 System V(比较商业) 定义的一个信号 与SIGCHLD一样 。 一般处理方式: 1. 忽略SIGCLD信号; 2. 父进程调用wait等待所有子进程都终止。 应用属于多进程模式,父进程主要功能就是根据配置信息创建多个业务子进程, 我们选用了第一种方式。 在不同架构体系下, SIGCLD对应的数字是不一样的。 在LINUX-X86平台 , SIGCLD=17 ,应用屏蔽了小于20的信号量, 当迁移到AIX-SPARC SIGCLD(SIGHCLD)=20,原有应用屏蔽未生效。 目前采取了简单粗暴的方案, 调整上限为 SIGRTMAX. 编程不够规范导致,这一问题在: 皓哥推荐 的 C codeing stardard 中的 No Magic Numbersv , 中也提到了。 类似的一些代码规范, 如:代码大全 中12.7 提到了Named Constants 。 在实际编程中要避免使用文字量, 根据现有系统改造时, 要根据情况选用 const, enum, #define,在调用外部API也要使用具名变量方式,这样会使自己的代码更加规范整洁。 参考文档: signal(7)

2019-04-30 · 1 min · 56 words

关于鸟哥是如何解开 initramfs 的:)

1. 问题: 鸟哥解析 CentOS 7.x 的initramfs 档案内容 文章内容时, 主要疑问是为什么使用的是512bytes去算 “initramfs 档案的前置字元容量 ”的大小。 # 1.先取得initramfs前面应该要去除的容量有多少才对!使用下列方式取得 [root@study ~]# mkdir /dev/shm/initramfs [root@study ~]# cd /dev/shm/initramfs [root@study initramfs]# cpio -i -d --no-absolute- filenames \ > -I /boot/initramfs-3.10.0-229.el7.x86_64.img 22 blocks #这个重点就是在前面的字元占了几个block容量,每个block容量为512bytes, # 因此,前面的部份就总共占了: 22 * 512 = 11264 个bytes 的意思! # 每一个initramfs 档案的前置字元容量都不相同,所以需要先找出来去除才行! 2. 概念: initrd,initramfs的出现:硬件类型增多,要直接存储上的Linux kernel,需要硬件驱动, 而这些驱动由存放在文件系统根目录下, linux通过 虚拟档案系统(Initial RAM Disk或Initial RAM Filesystem) , 把这些启动引导需要的文档驱动加载到RAM中, 通过RAM上的init(systemd)加载我们实际存储上的(init)systemd, 完成后续的正常开机流程。 3. 处理过程: 1. 解析方法: 可以参考 上一篇文章。 2. initramfs格式: 根据解析方法看cenos不同版本cenos6 , cenos7, initramfs格式也是不同。以cenos7 为例,使用skipcpio工具可以实现解析: ...

2019-04-26 · 2 min · 369 words