当前位置:网站首页 > 微服务架构 > 正文

samba服务器实现共享时有一个前提(samba服务器共享目录)



52.在 Linux系统中,压缩文件后生成后缀为.gz文件的命令是 gzip
53. 在用vi编辑文件时,将文件内容存入test.txt文件中,应在命令模式下键入 :w test.txt
54 可以在标准输出上显示整年日历的命令及参数是 cal -y
55. 在shell编程时,使用方括号表示测试条件的规则是:方括号两边必须有 空格
56. 检查已安装的文件系统/dev/had5是否正常,若检查有错,则自动修复,其命令及参数是 fsck –a /dev/had5 。
57. 在Windows9.x环境下共享Unix/Linux中的用户目录的一个工具是 Samba服务器 。
58. 系统管理员的职责是进行系统资源管理、系统性能管理、设备管理、安全管理和 系统性能监测
59 在Linux系统中,测试DNS服务器是否能够正确解析域名的的客户端命令,使用命令 nslookup
60. 在Linux系统下,第二个IDE通道的硬盘(从盘)被标识为 hdb
61. 当系统管理员需升级内核版本和改变系统硬件配置时,应 重新编译内核
62. 如果只是要修改系统的IP地址,应修改 /etc/rc.d/rc.inet1 配置文件。
63. 当LAN内没有条件建立DNS服务器,但又想让局域网内的用户可以使用计算机名互相访问时,应配置 /etc/hosts 文件。
64. 在vi编辑环境下,使用 Esc键 进行模式转换。
65. Slackware Linux 9.0通常使用 ext3 文件系统,系统的全部磁盘块由 部分组成。
66. 将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现此任务的tar命令格式 tar zcvf /home/wang.tar.gz /home/stud1/wang
67. 管道就是将前一个命令的 标准输出 作为后一个命令的 标准输入
68. 在使用手工的方法配置网络时,可通过修改 /etc/HOSTNAME 文件来改变主机名,若要配置该计算机的域名解析客户端,需配置 /etc/resolv.conf 文件。
69. 启动进程有手动启动和调度启动两种方法,其中调度启动常用的命令为 at 、 batch 和 crontab 。
70. test.bns.com.cn的域名是 bns.com.cn ,如果要配置一域名服务器,应在 named.conf 文件中定义DNS数据库的工作目录。
71. Sendmail邮件系统使用的两个主要协议是: SMTP 和 POP ,前者用来发送邮件,后者用来接收邮件。
72. DHCP是动态主机配置协议的简称,其作用是:为网络中的主机分配IP地址
73. 目前代理服务器使用的软件包有很多种,教材中使用的是 squid
74. rm命令可删除文件或目录,其主要差别就是是否使用递归开关 -r或-R
75. mv 命令可以移动文件和目录,还可以为文件和目录重新命名。
76. 路由选择协议(RIP)的跳数表示到达目的地之前必须通过的 网关 数,RIP接受的最长距离是 15跳
77. ping命令用于测试网络的连通性,ping命令通过 ICMP 协议来实现。
78. nfs 协议用于实现Unix(/linux)主机之间的文件系统共享。
79. 在Linux操作系统中,设备都是通过特殊的 文件 来访问。
80. shell不仅是 用户命令的解释器 ,它同时也是一种功能强大的编程语言。 bash是Linux的缺省shell。
81. 用 >;>; 符号将输出重定向内容附加在原文的后面。
82. 增加一个用户的命令是:adduser 或useradd
83 进行字符串查找,使用grep命令。
84. 使用 * 每次匹配若干个字符。
85. /sbin 目录用来存放系统管理员使用的管理程序。

































































































五、多选题
1.关于硬链接的描述正确的(BE)。
A 跨文件系统 B不可以跨文件系统 D可以做目录的连接
C 为链接文件创建新的i节点 E链接文件的i节点同被链接文件的i节点
2.在网站发布用户wang的个人网页时,需要创建用户网页目录,假定用户网页目录设定为web
(用户目录在/home目录下),如下描述正确的是(BCE)
A 存放用户网页的绝对路径/wang/web B存放用户网页的目录~wang/
C 存放用户网页的绝对路径/home/wang/web D存放用户网页的绝对路径/home/web
E 在本机访问用户wang的个人网页的URL地址






















~wang/
3.在一台WWW服务器上将端口号设定为8000,默认的网页文件index.html,服务器网页的根目录/www。在本机访问服务器时,正确的用法是(BDE)
A 浏览器访问该服务器的URL地址





B 浏览器访问该服务器的URL地址
C 浏览器访问该服务器的用户li网页URL地址
D 浏览器访问该服务器的用户li网页URL地址
E 浏览器访问该服务器的URL地址localhost:8000/
4.在shell编程中关于$2的描述正确的是(CE)
A 程序后携带了两个位置参数 B 宏替换 C 程序后面携带的第二个位置参数
D 携带位置参数的个数 E 用$2引用第二个位置参数
5.某文件的权限是 - r w x r - - r- -,下面描述正确的是(CD)
A 文件的权限值是755 B 文件的所有者对文件只有读权 限
C 文件的权限值是 744 D 其他用户对文件只有读权限 E同组用户对文件只有写权限
6.关于OpenSSH的作用的描述正确的是(ACE)
A 开放源代码的安全加密程序 B OpenSSH常用于为http协议加密
C OpenSSH用于提高远程登录访问的安全性 D 它和telnet实用同样的端口号
E OpenSSH是免费下载的应程序
7.关于NFS服务器描述正确的是(BC)
A 网络中实现Windows系统之间文件系统共享的应用软件
B 网络中实现Linux系统之间文件系统共享的应用软件
C 网络中实现Unix系统之间文件系统共享的应用软件
D 网络中实现Windows系统和Unix之间文件系统共享的应用软件
E 网络中实现Windows系统和Linux之间文件系统共享的应用软件
8.关于sed描述正确的是(ABD)
A sed 是Linux系统中的流编辑器 B sed 是UNIX系统中的流编辑器
C sed 网络文件系统的类型


































































D 利用管道对标准输入/标准输入的数据进行编辑和组合
E sed是NFS的应用程序
9.关于限制磁盘限额,描述正确的是(ABD)
A 使用edquota可以监控系统所有用户使用的磁盘空间,并在接近极限时提示用户
B 用户组的磁盘限额是用户组内所有用户予设磁盘空间总和
C 单个用户的磁盘限额就是该用户所在用户组内所有磁盘限额的总合
D 在Linux系统下限制用户使用的磁盘空间可以使用edquota
E 用户组的磁盘限额就是该用户组内拥有最大磁盘限额值的用户的磁盘限额
10.关于建立系统用户的正确描述是()
A 在Linux系统下建立用户使用adduser命令
B 每个系统用户分别在/etc/passwd和/etc/shadow文件中有一条记录
C 访问每个用户的工作目录使用命令“cd /用户名”
D 每个系统用户在默认状态下的工作目录在/home/用户名
E 每个系统用户在/etc/fstab文件中有一条记录




































这是某个公司linux内核驱动笔试题目,希望对各位要参加面试的朋友提供一点帮助,同时又要对公司试题保密,唉,没办法,具体公司名字只能采用×××代替啦!^_^……     如果这样还是“那个”的话(^_^),请公司及时与偶联系,偶会第一时间将其删除,谢谢!

   (一)主要题型:

选择题(每题3分,约20题吧,具体什么题都有,包括网络、C以及其他硬件方面的基础知识);

简答题(总分约40分,主要包括读C程序给出结果同时给出适当的解释及其他一些硬件方面的问题);

(二)主要内容:

1、题目概述

1C方面:

这一部分比较简单,主要是类似指针空间分配、strcpy(主要是考第一个参数是否有空间,结合指针空间分配考)、二重指针、++及――(先加后加,先减后减)等,还有就是volatileregister修饰符的意思。

2)其他方面:

这一部分比较杂,什么都可以考你,多半都是基础知识,尤其是硬件方面,华为的主要题目为:(主要列出C以外的题目,我认为C是非常简单的,^_^

2、具体题目

1)选择题部分:

1255.255.254.0网段最多能支持多少主机?(大概有5个备选项)

2 10M 网卡传输过程中物理层采用什么编码?(SNAP?)(大概有4个备选项)

3、栈与队列的特点?(备选大概只有两个,AFIFOBLIFO

4Cache的工作方式划分?(大概也有4个答案,大概是:write-nonewrite-allwrite-throughwrite-back)。

5、什么叫NMI中断?(四个备选项)

6RISC主要性能及特性?(大概有6个备选项)

7、在嵌入式系统中,所谓的北桥指的是什么?

2)简答题:

1、说说轮巡任务调度与抢占式任务调度的区别?(大概为8分吧,记不清了)

2、什么叫存储器高速缓存技术,其主要目的?(大概6分)

3、画出计算机组成的最小逻辑框图。(哼,这道题竟然10分)

4、谈谈VolatileRegister修饰符的作用?

select()函数的作用(转载)
   系统调用select和poll的后端实现,用这两个系统调用来查询设备是否可读写,或是否处于某种状态。如果poll为空,则驱动设备会被认为即可读又可写,返回值是一个状态掩码
如何使用select()函数?
   select()函数的接口主要是建立在一种叫'fd_set'类型的基础上。它('fd_set') 是一组文件描述符(fd)的集合。由于fd_set类型的长度在不同平台上不同,因此应该用一组标准的宏定义来处理此类变量:

fd_set set;
FD_ZERO(&set);    /* 将set清零 */
FD_SET(fd, &set); /* 将fd加入set */
FD_CLR(fd, &set); /* 将fd从set中清除 */
FD_ISSET(fd, &set);  /* 如果fd在set中则真 */
  
在过去,一个fd_set通常只能包含少于等于32个文件描述符,因为fd_set其实只用了一个int的比特矢量来实现,在大多数情况下,检查 fd_set能包括任意值的文件描述符是系统的责任,但确定你的fd_set到底能放多少有时你应该检查/修改宏FD_SETSIZE的值。*这个值是系统相关的*,同时检查你的系统中的select() 的man手册。有一些系统对多于1024个文件描述符的支持有问题。[译者注: Linux就是这样的系统!你会发现sizeof(fd_set)的结果是128(*8 = FD_SETSIZE=1024) 尽管很少你会遇到这种情况。]

select的基本接口十分简单:

int select(int nfds, fd_set *readset, fd_set *writeset,
            fd_set *exceptset, struct timeval *timeout);
  
其中:

nfds    
   需要检查的文件描述符个数,数值应该比是三组fd_set中最大数
   更大,而不是实际文件描述符的总数。
readset
   用来检查可读性的一组文件描述符。
writeset
   用来检查可写性的一组文件描述符。
exceptset
   用来检查意外状态的文件描述符。(注:错误并不是意外状态)
timeout
   NULL指针代表无限等待,否则是指向timeval结构的指针,代表最
   长等待时间。(如果其中tv_sec和tv_usec都等于0, 则文件描述符
   的状态不被影响,但函数并不挂起)
  
函数将返回响应操作的对应操作文件描述符的总数,且三组数据均在恰当位置被修改,只有响应操作的那一些没有修改。接着应该用FD_ISSET宏来查找返回的文件描述符组。

这里是一个简单的测试单个文件描述符可读性的例子:

   int isready(int fd)
   {
      int rc;
      fd_set fds;
      struct timeval tv;

      FD_ZERO(&fds);
      FD_SET(fd,&fds);
      // tv.tv_sec = tv.tv_usec = 0;

//rc = select(fd+1, &fds, NULL, NULL, &tv);
rc = select(fd+1, &fds, NULL, NULL, NULL);
      if (rc < 0)
         return -1;

      return FD_ISSET(fd,&fds) ? 1 : 0;
   }
  
当然如果我们把NULL指针作为fd_set传入的话,这就表示我们对这种操作的发生不感兴趣,但select() 还是会等待直到其发生或者超过等待时间。

[译者注:在Linux中,timeout指的是程序在非sleep状态中度过的时间,而不是实际上过去的时间,这就会引起和非Linux平台移植上的时间不等问题。移植问题还包括在System V风格中select()在函数退出前会把timeout设为未定义的 NULL状态,而在BSD中则不是这样, Linux在这点上遵从System V,因此在重复利用timeout指针问题上也应该注意。]
Linux下select调用的过程:
1.用户层应用程序调用select(),底层调用poll())
2.核心层调用sys_select() ------> do_select()
最终调用文件描述符fd对应的struct file类型变量的struct file_operations *f_op的poll函数。
poll指向的函数返回当前可否读写的信息。
1)如果当前可读写,返回读写信息。
2)如果当前不可读写,则阻塞进程,并等待驱动程序唤醒,重新调用poll函数,或超时返回。
3.驱动需要实现poll函数。
当驱动发现有数据可以读写时,通知核心层,核心层重新调用poll指向的函数查询信息。
poll_wait(filp,&wait_q,wait) // 此处将当前进程加入到等待队列中,但并不阻塞
在中断中使用wake_up_interruptible(&wait_q)唤醒等待队列。
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn:


来源: http://yfydz.cublog.cn



1. 前言


使用ioctl系统调用是用户空间向内核交换数据的常用方法之一,从ioctl这个名称上看,本意是针对I/O设备进行的控制操作,但实际并不限制是真正的I/O设备,可以是任何一个内核设备即可。

2. 基本过程


在内核空间中ioctl是很多内核操作结构的一个成员函数,如文件操作结构struct file_operations(include/linux/fs.h)、协议操作结构struct proto_ops(include/linux/net.h)等、tty操作结构struct tty_driver(include/linux/tty_driver.h)等,而这些操作结构分别对应各种内核设备,只要在用户空间打开这些设备,如I/O设备可用open(2)打开,网络协议可用socket(2)打开等,获取一个文件描述符后,就可以在这个描述符上调用ioctl(2)来向内核交换数据。
3. ioctl(2)
ioctl(2)函数的基本使用格式为:
int ioctl(int fd, int cmd, void *data)
第一个参数是文件描述符;cmd是操作命令,一般分为GET、SET以及其他类型命令,GET是用户空间进程从内核读数据,SET是用户空间进程向内核写数据,cmd虽然是一个整数,但是有一定的参数格式的,下面再详细说明;第三个参数是数据起始位置指针,
cmd命令参数是个32位整数,分为四部分:
dir(2b) size(14b) type(8b) nr(8b)
详细定义cmd要包括这4个部分时可使用宏_IOC(dir,type,nr,size)来定义,而最简单情况下使用_IO(type, nr)来定义就可以了,这些宏都在include/asm/ioctl.h中定义
本文cmd定义为:
#define NEWCHAR_IOC_MAGIC   'M'
#define NEWCHAR_SET    _IO(NEWCHAR_IOC_MAGIC, 0)
#define NEWCHAR_GET    _IO(NEWCHAR_IOC_MAGIC, 1)
#define NEWCHAR_IOC_MAXNR   1











要定义自己的ioctl操作,可以有两个方式,一种是在现有的内核代码中直接添加相关代码进行支持,比如想通过socket描述符进行ioctl操作,可在net/ipv4/af_inet.c中的inet_ioctl()函数中添加自己定义的命令和相关的处理函数,重新编译内核即可,不过这种方法一般不推荐;第二种方法是定义自己的内核设备,通过设备的ioctl()来操作,可以编成模块,这样不影响原有的内核,这是最通常的做法。


4. 内核设备
为进行ioctl操作最通常是使用字符设备来进行,当然定义其他类型的设备也可以。在用户空间,可使用mknod命令建立一个字符类型设备文件,假设该设备的主设备号为123,次设备号为0:
mknode /dev/newchar c 123 0
如果是编程的话,可以用mknode(2)函数来建立设备文件。
建立设备文件后再将该设备的内核模块文件插入内核,就可以使用open(2)打开/dev/newchar文件,然后调用ioctl(2)来传递数据,最后用close(2)关闭设备。而如果内核中还没有插入该设备的模块,open(2)时就会失败。
由于内核内存空间和用户内存空间不同,要将内核数据拷贝到用户空间,要使用专用拷贝函数copy_to_user();要将用户空间数据拷贝到内核,要使用copy_from_user()。
要最简单实现以上功能,内核模块只需要实现设备的open, ioctl和release三个函数即可,
下面介绍程序片断:
static int newchar_ioctl(struct inode *inode, struct file *filep,
   unsigned int cmd, unsigned long arg);
static int newchar_open(struct inode *inode, struct file *filep);
static int newchar_release(struct inode *inode, struct file *filep);







// 定义文件操作结构,结构中其他元素为空
struct file_operations newchar_fops =
{
owner:  THIS_MODULE,
ioctl:  newchar_ioctl,
open:  newchar_open,
release: newchar_release,
};



















// 定义要传输的数据块结构
struct newchar{
int a;
int b;
};










#define MAJOR_DEV_NUM 123
#define DEVICE_NAME "newchar"

打开设备,非常简单,就是增加模块计数器,防止在打开设备的情况下删除模块,
当然想搞得复杂的话可进行各种限制检查,如只允许指定的用户打开等:

static int newchar_open(struct inode *inode, struct file *filep)
{
MOD_INC_USE_COUNT;




return 0;
}

关闭设备,也很简单,减模块计数器:
static int newchar_release(struct inode *inode, struct file *filep)
{
MOD_DEC_USE_COUNT;










return 0;
}

进行ioctl调用的基本处理函数
static int newchar_ioctl(struct inode *inode, struct file *filep,
      unsigned int cmd, unsigned long arg)
{
int  ret;













// 首先检查cmd是否合法
if (_IOC_TYPE(cmd) != NEWCHAR_IOC_MAGIC) return -EINVAL;
if (_IOC_NR(cmd) > NEWCHAR_IOC_MAXNR) return -EINVAL;




// 错误情况下的缺省返回值
ret = EINVAL;

switch(cmd)
{
case KNEWCHAR_SET:
// 设置操作,将数据从用户空间拷贝到内核空间
  {
   struct newchar nc;
   if(copy_from_user(&nc, (const char*)arg, sizeof(nc)) != 0)
    return -EFAULT;
   ret = do_set_newchar(&nc);
  }
  break;
case KNEWCHAR_GET:
// GET操作通常会在数据缓冲区中先传递部分初始值作为数据查找条件,获取全部
// 数据后重新写回缓冲区
// 当然也可以根据具体情况什么也不传入直接向内核获取数据
  {
   struct newchar nc;
   if(copy_from_user(&nc, (const char*)arg, sizeof(nc)) != 0)
    return -EFAULT;
   ret = do_get_newchar(&nc);
   if(ret == 0){
    if(copy_to_user((unsigned char *)arg, &nc, sizeof(nc))!=0)
     return -EFAULT;
   }



































































  }
  break;
}
return ret;
}










模块初始化函数,登记字符设备
static int __init _init(void)
{
int  result;
// 登记该字符设备,这是2.4以前的基本方法,到2.6后有了些变化,
// 是使用MKDEV和cdev_init()来进行,本文还是按老方法
result = register_chrdev(MAJOR_DEV_NUM, DEVICE_NAME, &newchar_fops);
if (result < 0) {
  printk(KERN_WARNING __FUNCTION__ ": failed register character device for /dev/newchar ");
  return result;
}
return 0;































}

模块退出函数,登出字符设备
static void __exit _cleanup(void)
{
int  result;










result = unregister_chrdev(MAJOR_DEV_NUM, DEVICE_NAME);
if (result < 0)
  printk(__FUNCTION__ ": failed unregister character device for /dev/newchar ");




return;
}
module_init(_init);
module_exit(_cleanup);

5. 结论
用ioctl()在用户空间和内核空间传递数据是最常用方法之一,比较简单方便,而且可以在同一个ioctl中对不同的命令传送不同的数据结构,本文只是为描述方便而在不同命令中使用了相同的数据结构。
在编写ioctl代码之前,需要选择对应不同命令的编号。为了防止对错误的设备使用正确的命令,命令号应该在系统范围内唯一,这种错误匹配并不是不会发生,程序可能发现自己正在试图对FIFOaudio等这类非串行设备输入流修改波特率,如果每一个ioctl命令都是唯一的,应用程序进行这种操作时就会得到一个EINVAL错误,而不是无意间成功地完成了意想不到的操作。

   要按Linux内核的约定方法为驱动程序选择ioctl编号,应该首先看看include/asm/ioctl.hDoucumention/ioctl-number.txt这两个文件。头文件定义了要使用的位字段:类型(幻数)、序数、传送方向以及参数大小等。ioctl-number.txt文件中罗列了内核所使用的幻数,选择自己的幻数要避免和内核冲突。以下是对include/asm/ioctl.h中定义的宏的注释:

#define         _IOC_NRBITS          8                               //序数(number)字段的字位宽度,8bits

#define         _IOC_TYPEBITS      8                               //幻数(type)字段的字位宽度,8bits

#define         _IOC_SIZEBITS       14                              //大小(size)字段的字位宽度,14bits

#define         _IOC_DIRBITS         2                               //方向(direction)字段的字位宽度,2bits

#define         _IOC_NRMASK        ((1 << _IOC_NRBITS)-1)    //序数字段的掩码,0x000000FF

#define         _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)  //幻数字段的掩码,0x000000FF

#define         _IOC_SIZEMASK     ((1 << _IOC_SIZEBITS)-1)   //大小字段的掩码,0x00003FFF

#define         _IOC_DIRMASK      ((1 << _IOC_DIRBITS)-1)    //方向字段的掩码,0x00000003

#define        _IOC_NRSHIFT       0                                                         //序数字段在整个字段中的位移,0

#define        _IOC_TYPESHIFT   (_IOC_NRSHIFT+_IOC_NRBITS)         //幻数字段的位移,8

#define        _IOC_SIZESHIFT    (_IOC_TYPESHIFT+_IOC_TYPEBITS)  //大小字段的位移,16

#define        _IOC_DIRSHIFT      (_IOC_SIZESHIFT+_IOC_SIZEBITS)    //方向字段的位移,30

/*

* Direction bits.

*/

#define _IOC_NONE     0U     //没有数据传输

#define _IOC_WRITE   1U     //向设备写入数据,驱动程序必须从用户空间读入数据

#define _IOC_READ     2U     //从设备中读取数据,驱动程序必须向用户空间写入数据

/*

*_IOC 宏将dirtypenrsize四个参数组合成一个cmd参数,如下图:

*

*/

#define _IOC(dir,type,nr,size)

       (((dir)  << _IOC_DIRSHIFT) |

        ((type) << _IOC_TYPESHIFT) |

        ((nr)   << _IOC_NRSHIFT) |

        ((size) << _IOC_SIZESHIFT))

/*

* used to create numbers

*/

//构造无参数的命令编号

#define _IO(type,nr)             _IOC(_IOC_NONE,(type),(nr),0)

//构造从驱动程序中读取数据的命令编号

#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))

//用于向驱动程序写入数据命令

#define _IOW(type,nr,size)    _IOC(_IOC_WRITE,(type),(nr),sizeof(size))

//用于双向传输

#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))

/*

*used to decode ioctl numbers..

*/

//从命令参数中解析出数据方向,即写进还是读出

#define _IOC_DIR(nr)          (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)

//从命令参数中解析出幻数type

#define _IOC_TYPE(nr)              (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)

//从命令参数中解析出序数number

#define _IOC_NR(nr)           (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)

//从命令参数中解析出用户数据大小

#define _IOC_SIZE(nr)         (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)

/* ...and for the drivers/sound files... */

#define IOC_IN            (_IOC_WRITE << _IOC_DIRSHIFT)

#define IOC_OUT         (_IOC_READ << _IOC_DIRSHIFT)

#define IOC_INOUT     ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)

#define IOCSIZE_MASK      (_IOC_SIZEMASK << _IOC_SIZESHIFT)

#define IOCSIZE_SHIFT      (_IOC_SIZESHIFT)

我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl,
所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混
了,这几天才弄明白它,于是在这里清理一下头脑。
一、 什么是ioctl。
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就
是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数
如下:
int ioctl(int fd, ind cmd, …);
其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设
备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和
cmd的意义相关的。
ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支
持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。
二、 ioctl的必要性
如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可
以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,
那么后面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会
导致代码分工不明,程序结构混乱,程序员自己也会头昏眼花的。
所以,我们就使用ioctl来实现控制的功能。要记住,用户程序所作的只是通过命令码告
诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要
做的事情。
三、 ioctl如何实现
这是一个很麻烦的问题,我是能省则省。要说清楚它,没有四五千字是不行的,所以我这
里是不可能把它说得非常清楚了,不过如果有读者对用户程序怎么和驱动程序联系起来感
兴趣的话,可以看我前一阵子写的《write的奥秘》。读者只要把write换成ioctl,就知
道用户程序的ioctl是怎么和驱动程序中的ioctl实现联系在一起的了。
我这里说一个大概思路,因为我觉得《Linux设备驱动程序》这本书已经说的非常清楚
了,但是得化一些时间来看。
在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对
应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事
情,因为设备都是特定的,这里也没法说。关键在于怎么样组织命令码,因为在ioctl中
命令码是唯一联系用户程序命令和驱动程序支持的途径。
命令码的组织是有一些讲究的,因为我们一定要做到命令和设备是一一对应的,这样才不
会将正确的命令发给错误的设备,或者是把错误的命令发给正确的设备,或者是把错误的
命令发给错误的设备。这些错误都会导致不可预料的事情发生,而当程序员发现了这些奇
怪的事情的时候,再来调试程序查找错误,那将是非常困难的事情。
所以在Linux核心中是这样定义一个命令码的:
____________________________________
| 设备类型 | 序列号 | 方向 |数据尺寸|
|----------|--------|------|--------|
| 8 bit | 8 bit |2 bit |8~14 bit|
|----------|--------|------|--------|
这样一来,一个命令就变成了一个整数形式的命令码。但是命令码非常的不直观,所以
Linux Kernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是从
命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数
据传送方向和数据传输尺寸。
这些宏我就不在这里解释了,具体的形式请读者察看Linux核心源代码中的和,文件里给
除了这些宏完整的定义。这里我只多说一个地方,那就是"幻数"。
幻数是一个字母,数据长度也是8,所以就用一个特定的字母来标明设备类型,这和用一
个数字是一样的,只是更加利于记忆和理解。就是这样,再没有更复杂的了。
更多的说了也没有,读者还是看一看源代码吧,推荐各位阅读《Linux 设备驱动程序》所
带源代码中的short一例,因为它比较短小,功能比较简单,可以看明白ioctl的功能和细
节。
四、 cmd参数如何得出
这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、
数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解
码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过
switch{case}结构进行相应的操作。
要透彻理解,只能是通过阅读源代码,我这篇文章实际上只是一个引子。Cmd参数的组织
还是比较复杂的,我认为要搞熟它还是得花不少时间的,但是这是值得的,驱动程序中最
难的是对中断的理解。
五、 小结
ioctl其实没有什么很难的东西需要理解,关键是理解cmd命令码是怎么在用户程序里生成
并在驱动程序里解析的,程序员最主要的工作量在switch{case}结构中,因为对设备的
I/O控制都是通过这一部分的代码实现的
文章出处:DIY部落() 像素数是指CCD上感光元件的数量。摄像机拍摄的画面可以理解为由很多个小的点组成,每个点就是一个像素。显然,像素数越多,画面就会越清晰,如果CCD没有足够的像素的话,拍摄出来的画面的清晰度就会大受影响,因此,理论上CCD的像素数量应该越多越好。但CCD像素数的增加会使制造成本以及成品率下降,而且在现行电视标准下,像素数增加到某一数量后,再增加对拍摄画面清晰度的提高效果变得不明显,一般而言八十万左右的像素数对拍摄动态画面已经足够了

分辨率(resalution)就是屏幕图像的精密度,是指显示器所能显示的点数的多少。由于屏幕上的点、线和面都是由点组成的,显示器可显示的点数越多,画面就越精细,同样的屏幕区域内能显示的信息也越多,所以分辨率是个非常重要的性能指标之一。可以把整个图像想象成是一个大型的棋盘,而分辨率的表示方式就是所有经线和纬线交叉点的数目。




以分辨率为1024×768的屏幕来说,即每一条水平线上包含有1024个像素点,共有768条线,即扫描列数为1024列,行数为768行。分辨率不仅与显示尺寸有关,还受显像管点距、视频带宽等因素的影响。其中,它和刷新频率的关系比较密切,严格地说,只有当刷新频率为无闪烁刷新频率,显示器能达到最高多少分辨率,才能称这个显示器的最高分辨率为多少。





按照水平和垂直像素数目来区分,则可以分:320×200640×480800×6001024×7681280×10241600×1200等几种。一般来讲,17英寸CRT显示器的最佳分辨率还是1024×76819英寸CRT显示器则为1280×1024。对于CRT显示器,它支持的分辨率越多和越大,它的应用范围也就越广,价格也就相应要高一些。

用于量度位图图像内数据量多少的一个参数。通常表示成ppi(每英寸像素)。包含的数据越多,图形文件的长度就越大,也能表现更丰富的细节。但更大的文件也需要耗用更多的计算机资源,更多的ram,更大的硬盘空间等等。在另一方面,假如图像包含的数据不够充分(图形分辨率较低),就会显得相当粗糙,特别是把图像放大为一个较大尺寸观看的时候。所以在图片创建期间,我们必须根据图像最终的用途决定正确的分辨率。这里的技巧是要首先保证图像包含足够多的数据,能满足最终输出的需要。同时也要适量,尽量少占用一些计算机的资源。

通常,分辨率被表示成每一个方向上的像素数量,比如640x480等。而在某些情况下,它也可以同时表示成每英寸像素ppi)以及图形的长度和宽度。比如72ppi,和8x6英寸。

  ppidpi(每英寸点数)经常都会出现混用现象。从技术角度说,像素p)只存在于计算机显示领域,而d)只出现于打印或印刷领域。请读者注意分辨。

到此这篇samba服务器实现共享时有一个前提(samba服务器共享目录)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

































































































































































































































































































































































































版权声明


相关文章:

  • 个人服务器怎么出租的(个人服务器怎么出租的啊)2026-04-04 22:09:06
  • 好玩的代码游戏微信(微信代码小游戏)2026-04-04 22:09:06
  • 微信linux uos(微信Linux官网)2026-04-04 22:09:06
  • 个人服务器搭建(个人服务器搭建硬件推荐)2026-04-04 22:09:06
  • samba共享服务(samba共享服务配置)2026-04-04 22:09:06
  • 免费的服务器平台(免费服务器平台国内)2026-04-04 22:09:06
  • 个人服务器怎么挣钱(个人服务器怎么赚钱)2026-04-04 22:09:06
  • linux系统微信聊天记录(linux系统微信聊天记录保存多久)2026-04-04 22:09:06
  • linux 微信 代理(linux怎么走代理)2026-04-04 22:09:06
  • 乔拓云网微信小程序制作模板单独(乔托云网微信小程序制作)2026-04-04 22:09:06
  • 全屏图片