技术改变世界 阅读塑造人生! - shaogx.com

This string was altered by TechBlog\Plugins\Example.; This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some responsive-range viewport sizes to see it in action.

Linux内核参数设定及内核编译

先来了解下/proc文件系统:        proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。        并不是所有这些目录在你的系统中都有,这取决于你的内核配置和装载的模块。另外,在/proc下还有三个很重要的目录:net,scsi和sys。Sys目录是可写的,可以通过它来访问或修改内核的参数,而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi目录不存在。 ... 全文

linux内核编译 Linux linux内核参数设定

零零散散整理的一些linux内核参数和说明

其实也不能算是原创,日常工作的时候经常和这些参数打交道,遇到不明白的就去网上找到并记录下来,零零散散的记录了这么多,呵呵,如果你遇到没见过的参数,不妨来我这里找找,如果有不准确的地方,还请大家回复指出,谢谢$ /proc/sys/net/core/wmem_max 最大socket写buffer,可参考的优化值:873200 $ /proc/sys/net/core/rmem_max 最大socket读buffer,可参考的优化值:873200 $ /proc/sys/net/ipv4/tcp_wmem TCP写buffer,可参考的优化值: 8192 436600 873200 $ /proc/sys/net/ipv4/tcp_rmem TCP读buffer,可参考的优化值: 32768 436600 873200 $ /proc/sys/net/ipv4/tcp_mem 同样有3个值,意思是: net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力. net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段. net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket. 上述内存单位是页,而不是字节.可参考的优化值是:786432 1048576 1572864 $ /proc/sys/net/core/netdev_max_backlog 进入包的最大设备队列.默认是300,对重负载服务器而言,该值太低,可调整到1000. $ /proc/sys/net/core/somaxconn listen()的默认参数,挂起请求的最大数量.默认是128.对繁忙的服务器,增加该值有助于网络性能.可调整到256. $ /proc/sys/net/core/optmem_max socket buffer的最大初始化值,默认10K. $ /proc/sys/net/ipv4/tcp_max_syn_backlog 进入SYN包的最大请求队列.默认1024.对重负载服务器,增加该值显然有好处.可调整到2048. $ /proc/sys/net/ipv4/tcp_retries2 TCP失败重传次数,默认值15,意味着重传15次才彻底放弃.可减少到5,以尽早释放内核资源. $ /proc/sys/net/ipv4/tcp_keepalive_time $ /proc/sys/net/ipv4/tcp_keepalive_intvl $ /proc/sys/net/ipv4/tcp_keepalive_probes 这3个参数与TCP KeepAlive有关.默认值是: tcp_keepalive_time = 7200 seconds (2 hours) tcp_keepalive_probes = 9 tcp_keepalive_intvl = 75 seconds 意思是如果某个TCP连接在idle 2个小时后,内核才发起probe.如果probe 9次(每次75秒)不成功,内核才彻底放弃,认为该连接已失效.对服务器而言,显然上述值太大. 可调整到: /proc/sys/net/ipv4/tcp_keepalive_time 1800 /proc/sys/net/ipv4/tcp_keepalive_intvl 30 /proc/sys/net/ipv4/tcp_keepalive_probes 3 $ proc/sys/net/ipv4/ip_local_port_range 指定端口范围的一个配置,默认是32768 61000,已够大.   net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。 net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。 net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。 net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。 net.ipv4.tcp_max_tw_buckets = 5000 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为 5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。 本文出自 “虚拟的现实” 博客,请务必保留此出处http://waringid.blog.51cto.com/65148/183496 kernel.hung_task_check_count The number of tasks checked:  */ unsigned long __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; 最大pid上限? ############################################### net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 每个消息队列的最大字节限制 kernel.msgmax = 65536 每个消息的最大size. kernel.shmmax = 68719476736 内核参数定义单个共享内存段的最大值 kernel.shmall = 4294967296 参数是控制共享内存页数 net.ipv4.tcp_max_syn_backlog = 65536 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数 net.core.netdev_max_backlog = 8192 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目 net.ipv4.tcp_max_tw_buckets = 20000 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死 net.core.somaxconn = 32768 定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为1024 net.core.wmem_default = 8388608 该文件指定了发送套接字缓冲区大小的缺省值(以字节为单位)。 net.core.rmem_default = 8388608 该文件指定了接收套接字缓冲区大小的默认值(以字节为单位)。 net.core.rmem_max = 16777216    指定了接收套接字缓冲区(接收窗口)大小的最大值(以字节为单位)          最大的TCP数据接收缓冲 net.core.wmem_max = 16777216      指定了发送套接字缓冲区(接收窗口)大小的最大值(以字节为单位)                    最大的TCP数据发送缓冲 net.ipv4.tcp_timestamps = 0                                                        以一种比重发超时更精确的方法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项,时间戳在(请参考RFC 1323)TCP的包头增加12个字节 net.ipv4.tcp_synack_retries = 2                     # syn-ack握手状态重试次数,默认5,遭受syn-flood攻击时改为1或2 net.ipv4.tcp_syn_retries = 2                          外向syn握手重试次数,默认4 net.ipv4.tcp_tw_recycle = 1                           # 默认0,tw快速回收 net.ipv4.tcp_tw_reuse = 1                                                       表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_mem = 94500000 915000000 927000000  确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。第一个值是内存使用的下限。第二个值是内存压力模式开始对缓冲区使用应用压力的上限。第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节) net.ipv4.tcp_max_orphans = 3276800  系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后) net.ipv4.tcp_fin_timeout = 30                    表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。 net.ipv4.tcp_keepalive_time = 600                                 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。 net.ipv4.tcp_keepalive_intvl = 30                当探测没有确认时,重新发送探测的频度。缺省是75秒 net.ipv4.tcp_keepalive_probes = 3                在认定连接失效之前,发送多少个TCP的keepalive探测包。缺省值是9。这个值乘以tcp_keepalive_intvl之后决定了,一个连接发送了keepalive之后可以有多少时间没有回应 net.ipv4.tcp_no_metrics_save = 1                 一个tcp连接关闭后,把这个连接曾经有的参数比如慢启动门限snd_sthresh,拥塞窗口snd_cwnd 还有srtt等信息保存到dst_entry中, 只要dst_entry 没有失效,下次新建立相同连接的时候就可以使用保存的参数来初始化这个连接.                                                  tcp_no_metrics_save 设置为1就是不保持这些参数(经验值),每次建立连接后都重新摸索一次. 我觉得没什么好处. 所以系统默认把它设为0. net.ipv4.ip_local_port_range = 1024  65535    指定端口范围的一个配置,默认是32768 61000 kernel.msgmni = 1024 这个参数决定了系统中同时运行的最大的message queue的个数 kernel.sem = 250 256000 32 2048 cat /proc/sys/kernel/sem 250 32000 100 128 4个数据分别对应 SEMMSL     250       表示每个信号集中的最大信号量数目 SEMMNS     32000  表示系统范围内的最大信号量总数目 SEMOPM     100      表示每个信号发生时的最大系统操作数目 SEMMNI       128      表示系统范围内的最大信号集总数目  ... 全文

sysctl.conf linux内核调优 linux内核参数 linux sysctl.conf参数

每天分析一段linux内核代码

#ifndef _SCHED_H#define _SCHED_H#define NR_TASKS 64 // 系统中同时最多任务(进程)数。#define HZ 100 // 定义系统时钟滴答频率(1 百赫兹,每个滴答10ms)#define FIRST_TASK task[0] // 任务0 比较特殊,所以特意给它单独定义一个符号。#define LAST_TASK task[NR_TASKS-1] // 任务数组中的最后一项任务。#include <linux/head.h> // head 头文件,定义了段描述符的简单结构,和几个选择符常量。#include <linux/fs.h> // 文件系统头文件。定义文件表结构(file,buffer_head,m_inode 等)。#include <linux/mm.h> // 内存管理头文件。含有页面大小定义和一些页面释放函数原型。#include <signal.h> // 信号头文件。定义信号符号常量,信号结构以及信号操作函数原型。#if (NR_OPEN > 32)#error "Currently the close-on-exec-flags are in one word, max 32 files/proc"#endif// 这里定义了进程运行可能处的状态。#define TASK_RUNNING 0 // 进程正在运行或已准备就绪。#define TASK_INTERRUPTIBLE 1 // 进程处于可中断等待状态。#define TASK_UNINTERRUPTIBLE 2 // 进程处于不可中断等待状态,主要用于I/O 操作等待。#define TASK_ZOMBIE 3 // 进程处于僵死状态,已经停止运行,但父进程还没发信号。#define TASK_STOPPED 4 // 进程已停止。#ifndef NULL#define NULL ((void *) 0) // 定义NULL 为空指针。#endif// 复制进程的页目录页表。Linus 认为这是内核中最复杂的函数之一。( mm/memory.c, 105 )extern int copy_page_tables (unsigned long from, unsigned long to, long size);// 释放页表所指定的内存块及页表本身。( mm/memory.c, 150 )extern int free_page_tables (unsigned long from, unsigned long size);// 调度程序的初始化函数。( kernel/sched.c, 385 )extern void sched_init (void);// 进程调度函数。( kernel/sched.c, 104 )extern void schedule (void);// 异常(陷阱)中断处理初始化函数,设置中断调用门并允许中断请求信号。( kernel/traps.c, 181 )extern void trap_init (void);// 显示内核出错信息,然后进入死循环。( kernel/panic.c, 16 )。extern void panic (const char *str);// 往tty 上写指定长度的字符串。( kernel/chr_drv/tty_io.c, 290 )。extern int tty_write (unsigned minor, char *buf, int count);typedef int (*fn_ptr) (); // 定义函数指针类型。// 下面是数学协处理器使用的结构,主要用于保存进程切换时i387 的执行状态信息。struct i387_struct{  long cwd; // 控制字(Control word)。  long swd; // 状态字(Status word)。  long twd; // 标记字(Tag word)。  long fip; // 协处理器代码指针。  long fcs; // 协处理器代码段寄存器。  long foo;  long fos;  long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */};// 任务状态段数据结构(参见列表后的信息)。struct tss_struct{  long back_link; /* 16 high bits zero */  long esp0;  long ss0; /* 16 high bits zero */  long esp1;  long ss1; /* 16 high bits zero */  long esp2;  long ss2; /* 16 high bits zero */  long cr3;  long eip;  long eflags;  long eax, ecx, edx, ebx;  long esp;  long ebp;  long esi;  long edi;  long es; /* 16 high bits zero */  long cs; /* 16 high bits zero */  long ss; /* 16 high bits zero */  long ds; /* 16 high bits zero */  long fs; /* 16 high bits zero */  long gs; /* 16 high bits zero */  long ldt; /* 16 high bits zero */  long trace_bitmap; /* bits: trace 0, bitmap 16-31 */  struct i387_struct i387;};// 这里是任务(进程)数据结构,或称为进程描述符。// ==========================// long state 任务的运行状态(-1 不可运行,0 可运行(就绪),>0 已停止)。// long counter 任务运行时间计数(递减)(滴答数),运行时间片。// long priority 运行优先数。任务开始运行时counter = priority,越大运行越长。// long signal 信号。是位图,每个比特位代表一种信号,信号值=位偏移值+1。// struct sigaction sigaction[32] 信号执行属性结构,对应信号将要执行的操作和标志信息。// long blocked 进程信号屏蔽码(对应信号位图)。// --------------------------// int exit_code 任务执行停止的退出码,其父进程会取。// unsigned long start_code 代码段地址。// unsigned long end_code 代码长度(字节数)。// unsigned long end_data 代码长度 + 数据长度(字节数)。// unsigned long brk 总长度(字节数)。// unsigned long start_stack 堆栈段地址。// long pid 进程标识号(进程号)。// long father 父进程号。// long pgrp 父进程组号。// long session 会话号。// long leader 会话首领。// unsigned short uid 用户标识号(用户id)。// unsigned short euid 有效用户id。// unsigned short suid 保存的用户id。// unsigned short gid 组标识号(组id)。// unsigned short egid 有效组id。// unsigned short sgid 保存的组id。// long alarm 报警定时值(滴答数)。// long utime 用户态运行时间(滴答数)。// long stime 系统态运行时间(滴答数)。// long cutime 子进程用户态运行时间。// long cstime 子进程系统态运行时间。// long start_time 进程开始运行时刻。// unsigned short used_math 标志:是否使用了协处理器。// --------------------------// int tty 进程使用tty 的子设备号。-1 表示没有使用。// unsigned short umask 文件创建属性屏蔽位。// struct m_inode * pwd 当前工作目录i 节点结构。// struct m_inode * root 根目录i 节点结构。// struct m_inode * executable 执行文件i 节点结构。// unsigned long close_on_exec 执行时关闭文件句柄位图标志。(参见include/fcntl.h)// struct file * filp[NR_OPEN] 进程使用的文件表结构。// --------------------------// struct desc_struct ldt[3] 本任务的局部表描述符。0-空,1-代码段cs,2-数据和堆栈段ds&ss。// --------------------------// struct tss_struct tss 本进程的任务状态段信息结构。// ==========================struct task_struct{/* these are hardcoded - don't touch */  long state; /* -1 unrunnable, 0 runnable, >0 stopped */  long counter;  long priority;  long signal;  struct sigaction sigaction[32];  long blocked; /* bitmap of masked signals *//* various fields */  int exit_code;  unsigned long start_code, end_code, end_data, brk, start_stack;  long pid, father, pgrp, session, leader;  unsigned short uid, euid, suid;  unsigned short gid, egid, sgid;  long alarm;  long utime, stime, cutime, cstime, start_time;  unsigned short used_math;/* file system info */  int tty; /* -1 if no tty, so it must be signed */  unsigned short umask;  struct m_inode *pwd;  struct m_inode *root;  struct m_inode *executable;  unsigned long close_on_exec;  struct file *filp[NR_OPEN];/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */  struct desc_struct ldt[3];/* tss for this task */  struct tss_struct tss;};/** INIT_TASK is used to set up the first task table, touch at* your own risk!. Base=0, limit=0x9ffff (=640kB)*//** INIT_TASK 用于设置第1 个任务表,若想修改,责任自负?!* 基址Base = 0,段长limit = 0x9ffff(=640kB)。*/// 对应上面任务结构的第1 个任务的信息。#define INIT_TASK \/* state etc */ { 0,15,15, \ // state, counter, priority/* signals */ 0,{  {  },}, 0, \ // signal, sigaction[32], blocked                    /* ec,brk... */ 0, 0, 0, 0, 0, 0, \                    // exit_code,start_code,end_code,end_data,brk,start_stack                    /* pid etc.. */ 0, -1, 0, 0, 0, \                    // pid, father, pgrp, session, leader                    /* uid etc */ 0, 0, 0, 0, 0, 0, \                    // uid, euid, suid, gid, egid, sgid                    /* alarm */ 0, 0, 0, 0, 0, 0, \                    // alarm, utime, stime, cutime, cstime, start_time                /* math */ 0, \                // used_math                            /* fs info */ -1, 0022, NULL, NULL, NULL, 0, \                            // tty,umask,pwd,root,executable,close_on_exec/* filp */{NULL,}, \ // filp[20]{  \ // ldt[3]  {  0, 0}  ,/* ldt */  {  0x9f, 0xc0fa00}  , \ // 代码长640K,基址0x0,G=1,D=1,DPL=3,P=1 TYPE=0x0a  {  0x9f, 0xc0f200}  , \ // 数据长640K,基址0x0,G=1,D=1,DPL=3,P=1 TYPE=0x02},/*tss*/{  0, PAGE_SIZE + (long) &init_task, 0x10, 0, 0, 0, 0, (long) &pg_dir, \ // tss    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, _LDT (0), 0x80000000,  {  }},}extern struct task_struct *task[NR_TASKS]; // 任务数组。extern struct task_struct *last_task_used_math; // 上一个使用过协处理器的进程。extern struct task_struct *current; // 当前进程结构指针变量。extern long volatile jiffies; // 从开机开始算起的滴答数(10ms/滴答)。extern long startup_time; // 开机时间。从1970:0:0:0 开始计时的秒数。#define CURRENT_TIME (startup_time+jiffies/HZ) // 当前时间(秒数)。// 添加定时器函数(定时时间jiffies 滴答数,定时到时调用函数*fn())。( kernel/sched.c,272)extern void add_timer (long jiffies, void (*fn) (void));// 不可中断的等待睡眠。( kernel/sched.c, 151 )extern void sleep_on (struct task_struct **p);// 可中断的等待睡眠。( kernel/sched.c, 167 )extern void interruptible_sleep_on (struct task_struct **p);// 明确唤醒睡眠的进程。( kernel/sched.c, 188 )extern void wake_up (struct task_struct **p);/** Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall* 4-TSS0, 5-LDT0, 6-TSS1 etc ...*//** 寻找第1 个TSS 在全局表中的入口。0-没有用nul,1-代码段cs,2-数据段ds,3-系统段syscall* 4-任务状态段TSS0,5-局部表LTD0,6-任务状态段TSS1,等。*/// 全局表中第1 个任务状态段(TSS)描述符的选择符索引号。#define FIRST_TSS_ENTRY 4// 全局表中第1 个局部描述符表(LDT)描述符的选择符索引号。#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)// 宏定义,计算在全局表中第n 个任务的TSS 描述符的索引号(选择符)。#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))// 宏定义,计算在全局表中第n 个任务的LDT 描述符的索引号。#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))// 宏定义,加载第n 个任务的任务寄存器tr。#define ltr(n) __asm__( "ltr %%ax":: "a" (_TSS(n)))// 宏定义,加载第n 个任务的局部描述符表寄存器ldtr。#define lldt(n) __asm__( "lldt %%ax":: "a" (_LDT(n)))// 取当前运行任务的任务号(是任务数组中的索引值,与进程号pid 不同)。// 返回:n - 当前任务号。用于( kernel/traps.c, 79)。#define str(n) \__asm__( "str %%ax\n\t" \ // 将任务寄存器中TSS 段的有效地址??ax"subl %2,%%eax\n\t" \ // (eax - FIRST_TSS_ENTRY*8)??eax  "shrl $4,%%eax" \ // (eax/16)??eax = 当前任务号。: "=a" (n):"a" (0), "i" (FIRST_TSS_ENTRY << 3))/** switch_to(n) should switch tasks to task nr n, first* checking that n isn't the current task, in which case it does nothing.* This also clears the TS-flag if the task we switched to has used* tha math co-processor latest.*//** switch_to(n)将切换当前任务到任务nr,即n。首先检测任务n 不是当前任务,* 如果是则什么也不做退出。如果我们切换到的任务最近(上次运行)使用过数学* 协处理器的话,则还需复位控制寄存器cr0 中的TS 标志。*/// 输入:%0 - 新TSS 的偏移地址(*&__tmp.a); %1 - 存放新TSS 的选择符值(*&__tmp.b);// dx - 新任务n 的选择符;ecx - 新任务指针task[n]。// 其中临时数据结构__tmp 中,a 的值是32 位偏移值,b 为新TSS 的选择符。在任务切换时,a 值// 没有用(忽略)。在判断新任务上次执行是否使用过协处理器时,是通过将新任务状态段的地址与// 保存在last_task_used_math 变量中的使用过协处理器的任务状态段的地址进行比较而作出的。#define switch_to(n) {\struct {long a,b;} __tmp; \__asm__( "cmpl %%ecx,_current\n\t" \ // 任务n 是当前任务吗?(current ==task[n]?)  "je 1f\n\t" \ // 是,则什么都不做,退出。  "movw %%dx,%1\n\t" \ // 将新任务的选择符??*&__tmp.b。  "xchgl %%ecx,_current\n\t" \ // current = task[n];ecx = 被切换出的任务。  "ljmp %0\n\t" \ // 执行长跳转至*&__tmp,造成任务切换。// 在任务切换回来后才会继续执行下面的语句。  "cmpl %%ecx,_last_task_used_math\n\t" \ // 新任务上次使用过协处理器吗?  "jne 1f\n\t" \ // 没有则跳转,退出。  "clts\n" \ // 新任务上次使用过协处理器,则清cr0 的TS 标志。  "1:"::"m" (*&__tmp.a), "m" (*&__tmp.b),  "d" (_TSS (n)), "c" ((long) task[n]));}// 页面地址对准。(在内核代码中没有任何地方引用!!)#define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000)// 设置位于地址addr 处描述符中的各基地址字段(基地址是base),参见列表后说明。// %0 - 地址addr 偏移2;%1 - 地址addr 偏移4;%2 - 地址addr 偏移7;edx - 基地址base。#define _set_base(addr,base) \__asm__( "movw %%dx,%0\n\t" \ // 基址base 低16 位(位15-0)??[addr+2]。"rorl $16,%%edx\n\t" \ // edx 中基址高16 位(位31-16)??dx。  "movb %%dl,%1\n\t" \ // 基址高16 位中的低8 位(位23-16)??[addr+4]。  "movb %%dh,%2" \ // 基址高16 位中的高8 位(位31-24)??[addr+7]。::"m" (*((addr) + 2)), "m" (*((addr) + 4)), "m" (*((addr) + 7)), "d" (base):"dx")// 设置位于地址addr 处描述符中的段限长字段(段长是limit)。// %0 - 地址addr;%1 - 地址addr 偏移6 处;edx - 段长值limit。#define _set_limit(addr,limit) \__asm__( "movw %%dx,%0\n\t" \ // 段长limit 低16 位(位15-0)??[addr]。  "rorl $16,%%edx\n\t" \ // edx 中的段长高4 位(位19-16)??dl。  "movb %1,%%dh\n\t" \ // 取原[addr+6]字节??dh,其中高4 位是些标志。  "andb $0xf0,%%dh\n\t" \ // 清dh 的低4 位(将存放段长的位19-16)。  "orb %%dh,%%dl\n\t" \ // 将原高4 位标志和段长的高4 位(位19-16)合成1 字节,  "movb %%dl,%1" \ // 并放会[addr+6]处。::"m" (*(addr)), "m" (*((addr) + 6)), "d" (limit):"dx")// 设置局部描述符表中ldt 描述符的基地址字段。#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )// 设置局部描述符表中ldt 描述符的段长字段。#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )// 从地址addr 处描述符中取段基地址。功能与_set_base()正好相反。// edx - 存放基地址(__base);%1 - 地址addr 偏移2;%2 - 地址addr 偏移4;%3 - addr 偏移7。#define _get_base(addr) ({\unsigned long __base; \__asm__( "movb %3,%%dh\n\t" \ // 取[addr+7]处基址高16 位的高8 位(位31-24)??dh。  "movb %2,%%dl\n\t" \ // 取[addr+4]处基址高16 位的低8 位(位23-16)??dl。  "shll $16,%%edx\n\t" \ // 基地址高16 位移到edx 中高16 位处。  "movw %1,%%dx" \ // 取[addr+2]处基址低16 位(位15-0)??dx。:"=d" (__base) \ // 从而edx 中含有32 位的段基地址。:"m" (*((addr) + 2)), "m" (*((addr) + 4)), "m" (*((addr) + 7)));__base;})// 取局部描述符表中ldt 所指段描述符中的基地址。#define get_base(ldt) _get_base( ((char *)&(ldt)) )// 取段选择符segment 的段长值。// %0 - 存放段长值(字节数);%1 - 段选择符segment。#define get_limit(segment) ({ \unsigned long __limit; \__asm__( "lsll %1,%0\n\tincl %0": "=r" (__limit): "r" (segment)); \__limit;})... 全文

kernel Linux linux内核 内核 数据结构

Linux 2.6.19.x 内核编译配置选项简介

转载自:http://www.douban.com/group/topic/15706557/ Code maturity level options  代码成熟度选项 Prompt for development and/or incomplete code/drivers  显示尚在开发中或尚未完成的代码与驱动.除非你是测试人员或者开发者,否则请勿选择 General setup  常规设置... 全文

Linux linux内核 kernel c语言 内核

Linux Kernel 内核个性化配置

这次更新内核的时候忘了先用3.13.1来进行通用配置安装,所以只能和3.13.0比较,分别是5.6MB和5.8MB,只减少了200kb左右,其实作为个人桌面用户,这一些修改都还太少,主要原因是我很多功能并不知道有什么用(而且貌似有几个选项没有选,下次吧,编译内核太费CPU太费时间太费电了),而且我对自己的电脑硬件也不甚了解,希望以后能逐步完善精简内核的选项:Linux内核配置选项简介... 全文

linux 内核 kernel 升级内核 内核简介

在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序

在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序。在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文件/dev/hello、proc系统文件/proc/hello和devfs系统属性文件/sys/class/hello/hello/val。进一步,还通过cat命令来直接访问/proc/hello和/sys/class/hello/hello/val文件来,以验证驱动程序的正确性。在这一篇文章里,我们将通过自己编写的C可执行程序来访问设备文件/dev/hello。可能读者会觉得奇怪,怎么能在Android系统中用C语言来编写应用程序呢?Android系统上的应用程序不都是Java应用程序吗?其实是可以的,读者不妨用adb shell命令连上Android模拟器,在/system/bin目录下可以看到很多C可执行程序,如cat命令。今天,我们就来学习一下怎么在Android系统中添加用C语言编写的可执行程序吧。      一. 参照在Ubuntu上为Android系统编写Linux内核驱动程序一文,准备好Linux驱动程序。使用Android模拟器加载包含这个Linux驱动程序的内核文件,并且使用adb shell命令连接上模拟,验证在/dev目录中存在设备文件hello。... 全文

Ubuntu Linux内核驱动程序 Android 测试Linux内核驱动程序

linux内核模块编译及动态加载

一个简单的内核模块程序:#include <linux/module.h> /* Defines the license for this linux kernel module */ MODULE_LICENSE("GPL"); /* Init function called on module entry */ int my_module_init( void ) { printk(KERN_INFO "my_module_init called. Module is now loaded.\n"); return 0; } /* Cleanup function called on module exit */ void my_module_cleanup( void ) { printk(KERN_INFO "my_module_cleanup called. Module is now unloaded.\n"); return; } /* Declare entry and exit functions */ module_init( my_module_init ); module_exit( my_module_cleanup );函数printk() 会把日志打印到内核日志文件中(/var/log/message)... 全文

内核模块编译 内核模块加载及卸载 linux内核 源代码

关于学习Linux的经典书籍 (深入理解Linux内核、Linux设备驱动程序等)

成为一名精通 Linux 程序设计的高级程序员一直是不少朋友孜孜以求的目标。根据中华英才网统计数据,北京地区 Linux 程序员月薪平均为 Windows 程序员的 1.8 倍、Java 程序员的 2.6 倍, Linux 程序员年终奖金平均为 Windows 程序员的 2.9 倍。同时数据显示,随着工作经验的增长, Linux 程序员与 Windows 程序员的收入差距还有扩大的趋势。Denis 认为,要学好 Linux 环境下的编程,关键是要看对、选对、学会正确的书籍。可以说,如果你选对了 Linux编程的经典书籍,配合你在程序设计工作中的刻苦钻研,成为一名精通 Linux 程序设计的高级程序员并非一件可望不可及的事情。但如果各位程序员朋友没有选对正确的书籍,则你的职业生涯之路就可能面临坎坷。今天,水煮鱼向各位朋友推荐的这些书,有的是资深老前辈们当初向水煮鱼的推荐,还有的是 IBM 的内部培训指定参考书,它们都很值得各位朋友抽空认真一读。 为什么要学习 Linux 环境下的编程 Linux 是一个开放、灵活、跨平台的操作系统,上至庞大的数据中心,下至可放于掌心中的嵌入式设备,无处没有 Linux 的身影。更为重要的是, Linux 是一个与 Unix 既一脉相承又与时俱进的系统。可以说,上世纪70年代学习的 Unix 知识和技巧,在今天仍然大有用武之地,这与 Windows 平台的开发形成了鲜明的对比。程序员不用担心今天微软出一个 .net,明天又出一个 F#,使得自己过去学习的成果付之东流。 上个星期,水煮鱼与一位 Linux 项目经理聊天过程中,这位 Linux 项目经理告诉水煮鱼,他们项目的利润非常高,急需具备一定 Linux 编程知识的程序员。他说:“其实我们对程序员的编程技巧要求也并非很高,这是可以在工作中培训和提高的,关键是很多程序员连基本的 Linux 编程思想都不了解,我怎么聘用他们呢?我们去大学招聘的时候,给本科应届生开出 8000 元的月薪,但是就是很难招到人。我拿一些经典书籍中一些经典例子来考他们,他们基本上都是一问三不知。其实,如果他们能回答上一半的问题,我还是很愿意考虑是否聘用他们的。而对于项目相关部分的专业知识,我们有专业的内部培训,并不担心这个问题,关键是看应聘者是否具备 Linux 编程的基本思想。” 水煮鱼认为,这位项目经理朋友提到的问题还是很有代表性的。其实很多程序员朋友,只要能掌握这些书中的基础知识,是很容易脱颖而出的。事实上,项目经理他们也都很忙,并没有空去自己设计高难度的面试题目,而是直接采用经典书籍中的经典例子。 《UNIX环境高级编程》(第2版),史蒂文斯著 《UNIX 环境高级编程》,推荐指数:★★★★★ 在当当购买 | 在卓越购买 《UNIX环境高级编程》是 Unix/ Linux 程序员案头必备的一本书籍。可以说,Linux 程序员如果没有读过这本书,就好像基督教徒没有读过圣经一样,是很难让人理解的。这本书概括了 Linux 编程所需的一切理论框架、主要系统函数、多进程编程、乃至 Linux 网络通信。对于初学者,如果你能将《操作系统》这门课程结合着这本书来学习,试着用 Linux 程序实践《操作系统》这门书中讲的进程间通信、进程调度、进程同步等内容,相信这将是一个一举两得的事情。哦,忘了告诉大家,上次 CNN 采访 Google 总裁佩林的时候,水煮鱼看到佩林的书架上就有这本书的英文版,可见它真的是一本全球开发者必备的一本书。 《深入理解 Linux 内核》(第三版) ,博韦等著 《深入理解 Linux 内核》,推荐指数:★★★★ 在当当购买 | 在卓越购买 学习 Linux ,就要学习 Linux 的精华。而 Linux 的精华,则在于 Linux 的内核。《深入理解 Linux 内核》就是一本辅助学习 Linux 内核的经典书籍。有的初学者,在没有人指导的情况下,就钻入 Linux Kernel代码的海洋中埋头苦学,结果学了半天仍然是一头雾水。当然了,在大师指导下学习就不一样了。本书以最新的 Linux 2.6 版架构为基础,分门别类地向初学者介绍了 Linux 内核的架构、编程思想、以及功能模块。相信你在本书的指导下学习,对于你读懂 Linux 操作系统的精华部分,会取得事半功倍的效果。事实上,不少知名公司招聘的题目里面,很多就出自这本书,可见它真的是论述 Linux 内核的经典书籍。 《Linux 设备驱动程序》,科波特著 《Linux 设备驱动程序》,推荐指数:★★★ 在当当购买 | 在卓越购买 程序开发,高薪在 Linux ; Linux 程序员,高薪在驱动开发。可以说,水煮鱼见过的 Linux 驱动程序员,薪水在万元以下的,一个都没有。普遍观点认为, Linux 驱动开发很难学,这并不正确。初学者认为 Linux 驱动开发很难学,关键在于其没有选对正确的入门书籍。《 Linux 设备驱动程序》这本书,过去已经有多位 Linux 项目经理向水煮鱼推荐过,你要想学MOD编程,想挑战高薪职位,这本书读一读是很有必要的。当然,这本书不是一本针对初学者的书籍,初学者应首先学习前面提到的《UNIX环境高级编程》再看这本书,你才能真正的学懂学好 Linux 驱动开发。 《嵌入式 Linux 应用开发完全手册》,韦东山著 《嵌入式 Linux 应用开发完全手册》,推荐指数:★★★ 在当当购买 | 在卓越购买 要说 Linux 应用最广泛的地方,那一定是无处不在的嵌入式设备了,《嵌入式 Linux 应用开发完全手册》就是一本教会您怎样开发 Linux 嵌入式系统软件的一本好书。水煮鱼与本书作者韦东山老师曾有过一面之缘,当时韦老师正在写作这本书。这本书综合了常见的嵌入式开发经验技巧,以及常见的嵌入式系统应用,系统移植,调试及异常处理等,内容非常丰富,是中文 Linux 领域难得的一本好书。嵌入式处理器种类繁多,韦老师着重讲了目前国内最常用的ARM系统,实用性很强,是国内嵌入式程序员不容错过的一本工具书。 《人月神话》(32周年中文纪念版),布鲁克斯著 《人月神话》,推荐指数:★★★★★ 在当当购买 | 在卓越购买 水煮鱼上面为大家推荐了几本 Linux 编程经典书籍,但要问编程的最终目的是什么,那一定还是要应用到实际项目中。做项目,那就一定离不开《人月神话》这本书。《人月神话》的作者布鲁克斯,是水煮鱼所在公司的超级大牛人,也是图灵奖的获得者。去年,他到中国访问的时候曾经表示,《人月神话》这本书,浓缩了项目实践中的正反两方面经验,是项目经理和系统分析师必读的一本书。水煮鱼认为,各位年轻的朋友,最终还是会要管项目的,与其你临时再学习,还不如早点接触这方面的知识比较好。可以说,Linux 的项目,对开发者的要求都很高,大家不要去跟 Windows 程序员学一些不好的习惯,特别是项目实施方面的一些不好的习惯,而应该深入体会大师的书籍。目前,《人月神话》的32周年纪念版已经上市了,有志于成为项目经理和产品经理的人,不应该错过这本做项目的圣经。 总结 古人云:“生而知之者,上也;学而知之者,次也;困而学之,又其次也;困而不学,民斯为下矣。”水煮鱼认为,正如古人所言,对于成功的 Linux 程序员,勤奋苦读的结果,将为您的 Linux 学习之路锦上添花。对于还没有入门的投资者,尽快熟读一两本入门的 Linux 书籍,对于你少走弯路是很重要的。对于已经进入项目,但还不能熟练掌握 Linux 开发的程序员,越早补习自己缺乏的东西,您将越早受益。对于基础薄弱,又拒绝学习的程序员,或许“民斯为下矣”就将是您惨淡的结局。... 全文

linux linux内核 嵌入式 编程 unix windows

处理Linux内核安全详解

对于电脑用户来说,Windows的强大功能服务了广大用户, 不过Windows安全问题还是让很多人头疼,所以很多人开始应用Linux,不过Linux内核安全也不知大疏忽,今天就讲讲Linux内核安全问题清理。Windows的安全问题比谷仓里的跳蚤还要多,但Linux也未必就对自身的安全漏洞免疫。最近有两个明显的bug被发现,不过很快就修好了。为了保证你不受困扰,你需要尽快地为你的内核打上补丁。... 全文

Linux内核 内核安全

Linux内核升级方法详解

Linux的内核是系统的核心,所以升级内核是Linux系统管理员的一项基本技能,所以我就分享了系统运维实务上的一篇文章,当然我对源文件稍做了一些内容的增加,就是把遇到的问题及解决方案也加上了,希望对各位Linux系统管理员有所帮助!1.下载内核... 全文

Linux内核 内核升级

Linux内核抢占实现机制分析

Linux内核抢占实现机制分析   【摘要】本文详解了Linux内核抢占实现机制。首先介绍了内核抢占和用户抢占的概念和区别,接着分析了不可抢占内核的特点及实时系统中实现内核抢占的必要性。然后分析了禁止内核抢占的情况和内核抢占的时机,最后介绍了实现抢占内核所做的改动以及何时需要重新调度。   【关键字】内核抢占,用户抢占,中断, 实时性,自旋锁,抢占时机,调度时机,schedule,preempt count    ... 全文

linux kernel 内核 内核抢占机制

linux微内核

程序只能通过系统调用的界面(接口)访问内核结构。近年来,微内核结构逐渐流行起来,称为操作系统的主要潮流。 在微内核结构中,操作系统的内核只需要提供最基本,最核心的一部分操作(比如创建和删除任务,内存管理,中断管理)即可,而其他的管理程序(如文件系统,网络栈协议)则尽可能放在内核以外。只有在需要内核协助的时候,才通过一套接口对内核发出调用请求。 微内核结构的优点是是操作系统具有良好的灵活性。但这样的结构也有不足之处:首先,程序之间的相互隔离,使得整个系统失去了许多优化的机会;其次,部分资源在外部进程之间的通信,因为进程间通信的开销要比之间的函数调用大。但是总体来说,在当前的硬件条件下,微内核结构在效率上的损失小于其在结构上获得的效益,故选择微内核成为操作系统的一大潮流。 然而,linux系统却恰恰使用了单一内核结构。这是由于linux是一个实用主义的操作系统,以代码执行效率为第一要务,并没有进行过一个系统的设计工作,而是任由linux在使用中不断发展。比起结构的清晰,大家更注重功能的强大和高效率。... 全文

linux 操作系统 微内核 讲解 内核

如何在Linux上通过GRUB添加内核参数

我们可以在Linux内核启动时为其提供各种各样的参数。这些参数可以自定义内核默认的行为,或者通知内核关于硬件的配置信息。内核参数应在内核启动时通过引导装载程序,如GRUB或LILO传递给内核。在本教程中,我将会描述如何在Linux上通过GRUB添加内核参数。如果你在使用GRUB引导装载程序,想修改或添加内核参数,你可以编辑GRUB配置文件。下面是针对特定发行版在GRUB的配置文件中添加内核启动参数的方法。在Debian或Ubuntu上添加内核启动参数... 全文

Linux内核 GRUB 内核参数

Linux内核网络参数

 Linux系统内核中网络参数的意义及其应用     在Linux中,我们可以根据不同的需求来调整/proc/sys/net/ipv4/目录下的内核网络参数,通过合理的配置这里内核网络参数,从而达到提高网络的安全性和系统的稳定性的目的。 ... 全文

linux 内核 linux 休闲 职场

linux

移植I2C-EEPROM 驱动   编者:略。   1 在内核中配置I2C 驱动           Linux-2.6.32.2 对S2C2440 的I2C 接口提供了完善的驱动,因此我们只需在内核中配置一下即可使用。           在内核源代码目录执行:make menuconfig,进入内核配置主菜单,依次选择进入如下子菜单:           Device Drivers --->               <*> I2C support --->               I2C Hardware Bus support --->  如图,我们看到这里已经选择好了“<*> S3C2410 I2C Driver”,这里的S3C2410 也可以适用于S3C2440,因为它们的I2C 端口及寄存器定义都是完全相同的。   以上配置所对应的驱动源代码为:linux-2.6.32.2/drivers/i2c/busses/i2c-s3c2410.c       2 测试I2C-EEPROM         Mini2440 为了方便用户测试,基于I2C 总线挂接了一个EEPROM 芯片,它是AT24C08,通过写入和读取该芯片,我们就可以测试I2C 总线驱动了。在内核根目录下执行:make zImage,把生成的新内核烧写到开发板中,依然使用友善之臂提供的root_qtopoia,因为里面已经包含了I2C-EEPROM测试程序   在命令行种输入:i2c –w 可以向板子的24C08 器件中写入数据(0x00-0xff)... 全文

Linux 内核 linux内核 驱动开发 嵌入式系统

FS2410自带光盘Linux内核编译问题

1.问题:编译fs2410 嵌入linux_2.6.8.1内核按照fs2410的用户使用手册3.5.2编译linux-2.6.8.1,在输入make menuconfig时遇到如下问题:[root@localhost linux-2.6.8.1-zzm]# make menuconfig HOSTCC  scripts/kconfig/mconf.oscripts/kconfig/mconf.c:91: 错误:对 ‘current_menu’ 的静态声明出现在非静态声明之后scripts/kconfig/lkc.h:63: 错误:‘current_menu’ 的上一个声明在此make[1]: *** [scripts/kconfig/mconf.o] 错误 1make: *** [menuconfig] 错误 2无法进入linux kernel v2.6.8.1 configuration的界面! 2.解决办法修改scripts/kconfig/mconf.c文件中的current_menu定义,把它的static属性去掉后可以进入linux kernel v2.6.8.1 configuration的界面了 。3.原因分析静态全局变量的作用域为定义它的源文件,其他文件不能引用。... 全文

linux内核 menu linux

Linux内核驱动fsync机制实现图解

在Linux内核中的IO模型基本分为4类:1、同步阻塞I/O2、同步非阻塞I/O3、异步阻塞I/O4、异步非阻塞I/O同步:应用显式地通过函数访问数据,在此函数返回时就会得到结果(成功或失败)。异步:应用会显示地通过函数提出访问或关注申请。数据到达时,硬件和驱动会通知应用,此时代码一般不在读写访问函数中,而是得到通知了再去有目的的访问数据。阻塞:在等待数据的过程中会休眠在此处,而非阻塞即函数不休眠立即返回,可执行接下来的代码。... 全文

linux Linux内核驱动 fsync机制

linux内核启动的优化

linux内核启动需要时间,并且需要很多的时间,这是逃避不了的,了解linuxbios的朋友可能知道,linuxbios作为bios和别的bios相比启动的特别快,因为它把硬件检测的任务交给了linux内核而不是bios,毕竟bios检测完了内核再检测是一种浪费,为了bios的性能,把工作推给内核是不负责任的行为吗?其实不是,实际上启动时最耗时的操作就是硬件检测和初始化,正是因为如此,linuxbios才把如此艰巨的任务避开,一并给了操作系统内核。... 全文

linux内核 任务 linux 工作 优化

Linux内核源码学习之 slab 分配器剖析

全文转自:https://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/ 动态内存管理 内存管理的目标是提供一种方法,为实现各种目的而在各个用户之间实现内存共享。内存管理方法应该实现以下两个功能: 最小化管理内存所需的时间 最大化用于一般应用的可用内存(最小化管理开销) 内存管理实际上是一种关于权衡的零和游戏。您可以开发一种使用少量内存进行管理的算法,但是要花费更多时间来管理可用内存。也可以开发一个算法来有效地管理内存,但却要使用更多的内存。最终,特定应用程序的需求将促使对这种权衡作出选择。... 全文

内存分配 linux linux内核

2 3 4 5 6 7 8 9 10 11