搜档网
当前位置:搜档网 › Linux内核网络协议栈笔记

Linux内核网络协议栈笔记

Linux内核网络协议栈笔记

2011-08-11 15:54:https://www.sodocs.net/doc/ab2211091.html,-微型葡萄-点击数:1641

Linux内核网络协议栈笔记0:序言(附参考书籍)

自己是研究网络的,但实际上对Linux中网络协议栈的实现知之甚少。最近看完《深入理解Linux内核》前几章之后(特别是与网络子系统密切相关的软中断),觉得可以而且应该看一下网络协议栈了。这部分网上的文章大部分都没有什么结构和思路,很少有能够条分缕析的把协议栈讲述明白的。当然,个人水平有限,还是希望朋友们能够批评指正。

参考书籍《Understanding Linux Network Internals》以及《The Linux Networking Architecture Design and Implementation of Network Protocols in the Linux Kernel》,在我的Skydrive里(点这里)可以下到英文chm版。

先大体说说这两本巨著吧。前者确实是一本关于internals的书,前三个part:General

Background/System Initialization/Transmission and Reception以及第5个part:IPv4比较有用,而且思路

也与本文所采用的吻合:从系统初始化到数据包的发送与接收。而后者也确实是一本architecture的书,采用了与TCP/IP协议栈(不是OSI 7层)一样的5层架构自底向上讲述了Linux内核的相关内容。

全系列文章都基于Linux内核2.6.11版本,如果最新版本(当前是2.6.30)有较大变化,也会给与标出。

Linux内核网络协议栈笔记1:协议栈分层/层次结构

大家都知道TCP/IP协议栈现在是世界上最流行的网络协议栈,恐怕它的普及的最重要的原因就是其清晰的层次结构以及清晰定义的原语和接口。不仅使得上层应用开发者可以无需关心下层架构或者内部

机制,从而相对透明的操作网络。这个明显的层次结构也可以在Linux内核的网络协议栈中观察到。

主要的参考文献是:Linux网络栈剖析(中文版)/Anatomy of Linux networking stack(英文原版)by Tim Jones.

以及:Linux内核2.4.x的网络接口结构

另外一些参考资料可以从这个页面找到:https://www.sodocs.net/doc/ab2211091.html,/elibrary/linux/network/(纽约州

立大学石溪分校的页面)

Linux内核网络协议栈采用了如下的层次结构:

内核中的五层分别是(从上到下):

系统调用接口(详见Jones的另一篇文章:使用Linux系统调用的内核命令)

协议无关接口(BSD socket层)

网络协议(或者简称网络层。这是一个协议的集合,从链路层到传输层的协议都包括在内。不同的协议在/net文件夹下除core以外的子目录下,例如基于IP的协议簇都在/net/ipv4目录下,以太网协议在/net/ethernet目录下)

驱动无关接口(又称通用设备层--generic device layer/驱动接口层/设备操作层--device handling layer。属于网络协议栈最核心的部分,文件位于内核/net/core文件夹下,所以又叫网络核心层。其中包括了核心的数据结构skbuff文件中的sk_buff/dev.c文件中net_device,这些数据结构将在下篇文章中介绍)

设备驱动程序(在/driver/net文件夹内)

不像OSI或者TCP/IP协议栈,事实上并没有一个命名标准,因此在这里,这些层次的名称并不是通用的,但是其语义是清晰的,而且在大多数其他的文章里只是个别字上的差别。分层详细介绍可以参考Jones的文章。

Linux内核网络协议栈笔记2:初始化

参考文献《Understanding Linux Network Internals》中用了整整一章(part II)来介绍system initialization。本文只提供一个简单的概述,如果需要详细信息,还请看参考文献。

我们这里所说的初始化过程指的是从硬件加电启动,到可以从网络接收或发送数据包之前的过程。在Linux系统中,网卡拥有双重身份:struct pci_dev和struct net_device。pci_dev对象代表通用硬件的性质,是作为一个标准的PCI的设备插入了PCI的卡槽,由驱动程序进行管理;另一方面,net_device对象代表网络传输的性质,与内核的网络协议栈交互,进行数据传输。因此我们也必须通过两个方面来进行初始化,但是后者是我们的重点。而且我们并不关心内核与硬件的交互细节,例如寄存器读写与I/O映射等。

内核在初始化时,也会初始化一些与网络相关的数据结构;而且对应我们前面的日志所提及的内核网络协议栈层次结构(点这里),内核也需要一定的初始化工作来建立这种层次结构。

笔者认为初始化最重要的就是重要数据结构(通常用粗体标注)。因此也希望读者能够记住重要的数据结构的作用。

下面我们将分层,自底向上的分析整个初始化过程:

(一)驱动程序层

本文中以一个realtek 8139系列网卡作为例子,因为其驱动只有一个c文件(/drivers/net/8139too.c),比较容易分析。读者也可以参考e1000网卡的另一篇文章(点这里)。内核版本基于2.6.11。

驱动程序加载/注册主要包括以下的步骤:

(a)将设备驱动程序(pci_driver)添加到内核驱动程序链表中;

(b)调用每个驱动中的probe函数(其中重要一步就是初始化net_device对象)。

下面进行详细分解。

通常,在Linux中使用insmod命令加载一个驱动程序模块,例如8139too.o目标文件。加载之后,Linux会默认执行模块中的module_init(rtl8139_init_module)宏函数,其中的参数rtl8139_init_module是一个函数指针,指向在具体的驱动程序8139too.o中声明的rtl8139_init_module函数。这个函数定义如下:

static int __init rtl8139_init_module (void)

{ return pci_module_init (&rtl8139_pci_driver); }

pci_module_init是一个宏定义,实际上就等于pci_register_driver函数。(在2.6.30内核版本中,直接

变成了return pci_register_driver(&rtl8139_pci_driver) )。pci_register_driver函数的注释说明了它的作用:register a new pcidriver.Adds the driver structure to the list of registered drivers。也就是把如下的这样一个

驱动程序(pci_driver类型)挂到系统的驱动程序链表中:

static struct pci_driver rtl8139_pci_driver = {

.name = DRV_NAME,

.id_table = rtl8139_pci_tbl,

.probe = rtl8139_init_one,

.remove = __devexit_p(rtl8139_remove_one),

#ifdef CONFIG_PM

.suspend = rtl8139_suspend,

.resume = rtl8139_resume,

#endif

};

这一步我们应该这样理解(熟悉面向对象编程的读者):所有的pci_driver应该提供一致的接口(比如remove卸载/suspend挂起);但是这些接口的每个具体实现是不同的(pci声卡和pci显卡的挂起应该

是不同的),所以采用了这样的函数指针结构。这个pci_driver结构其中最重要的就是probe函数指针,指向rtl8139_init_one,具体后面会解释。

但是pci_register_driver并不仅仅完成了注册驱动这个任务,它内部调用了driver_register函数

(/drivers/base/driver.c中):

int driver_register(struct device_driver * drv)

{

INIT_LIST_HEAD(&drv->devices);

init_MUTEX_LOCKED(&drv->unload_sem);

return bus_add_driver(drv);

}

前两个就是实现了添加到链表的功能,bus_add_driver才是主要的函数(/drivers/base/bus.c中),内部

又调用了driver_attach函数,这个函数的主体是一个list_for_each循环,对链表中的每一个成员调用driver_probe_device函数(哈哈,出现了probe!),这个函数就调用了drv->probe(dev)(drv就是

pci_driver类型的对象)!这样也就调用了驱动程序中的probe函数指针,也就是调用了

rtl8139_init_one函数。

函数rtl8139_init_one的主要作用就是给net_device对象分配空间(分配空间由函数rtl8139_init_board

完成)并初始化。分配空间主要是内存空间。分配的资源包括I/O端口,内存映射(操作系统基本概

念,请自行google)的地址范围以及IRQ中断号等。而初始化主要是设置net_device对象中的各个成员变量及成员函数,其中比较重要的是hard_start_xmit(通过硬件发送数据)/poll(轮训)/open(启动)等函数(粗体标注),代码如下:

static int __devinit rtl8139_init_one

(struct pci_dev *pdev, conststruct pci_device_id *ent)

{

struct net_device *dev = NULL;

rtl8139_init_board (pdev, &dev);

dev->open = rtl8139_open;

dev->hard_start_xmit = rtl8139_start_xmit;

dev->poll = rtl8139_poll;

dev->stop = rtl8139_close;

dev->do_ioctl = netdev_ioctl;

}

整个的调用链如下:pci_register_driver ==>driver_register ==>bus_add_driver ==>driver_attach

==>driver_probe_device ==>drv->probe ==> rtl8139_init_one(生成net_device)。

一个简单的net_device生命周期示意图如下(左边为初始化,右边为卸载):

这个net_device数据结构的生成,标志着网络硬件和驱动程序层初始化完毕。也意味着,网络协议栈与硬件之间的纽带已经建立起来。

(二)设备无关层/网络协议层/协议无关接口socket层

Linux内核在启动后所执行的一些内核函数如下图所示:

系统初始化的过程中会调用do_basic_setup函数进行一些初始化操作。其中2.6.11内核中就直接包括了driver_init()驱动程序初始化,以及sock_init函数初始化socket层。然后do_initcalls()函数调用一组前

缀为__init类型(这个宏就表示为需要在系统初始化时执行)的函数。与网络相关的以__init宏标记的

函数有:net_dev_init初始化设备无关层;inet_init初始化网络协议层。

(fs_initcall和module_init这两个宏也具有类似的作用。由于这一阶段处于系统初始化,宏定义比较多,欲详细了解各种宏的使用的读者请参阅参考文献《Understanding Linux Network Internals》Part II Chapter 7)

我们下面详细介绍一下这三个初始化函数都进行了哪些工作。

(a)net_dev_init(在文件/net/core/dev.c中):设备操作层

static int __initnet_dev_init(void)

{

if (dev_proc_init())

if (netdev_sysfs_init())

INIT_LIST_HEAD(&ptype_all);

for (i = 0; i < 16; i++)

INIT_LIST_HEAD(&ptype_base[i]);

for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)

INIT_HLIST_HEAD(&dev_name_head[i]);

for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)

INIT_HLIST_HEAD(&dev_index_head[i]);

//Initialise the packet receive queues.

for (i = 0; i < NR_CPUS; i++) {

struct softnet_data *queue;

queue = &per_cpu(softnet_data, i);

skb_queue_head_init(&queue->input_pkt_queue);

queue->throttle = 0;

queue->cng_level = 0;

queue->avg_blog = 10;

queue->completion_queue = NULL;

INIT_LIST_HEAD(&queue->poll_list);

set_bit(__LINK_STATE_START, &queue->backlog_dev.state);

queue->backlog_dev.weight = weight_p;

queue->backlog_dev.poll = process_backlog;

atomic_set(&queue->backlog_dev.refcnt, 1);

}

open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);

open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);

}

这个函数所做的具体工作主要包括:初始化softnet_data这个数据结构(每个CPU都有一个这样的队列,表示要交给此CPU处理的数据包);注册网络相关软中断(参见我关于软中断的文章,点这里)。

(b)inet_init(在文件/net/ipv4/af_inet.c中):网络层

由于各种网络协议是按照协议族(protocol family,PF或者address family,AF)为单位组织起来的。

我们在这里仅以Internet协议族(AF_INET或者PF_INET,在内核中这二者是等价的)为例。

有时候这一层又被称为INET socket层(对应的数据结构为struct sock),请注意与BSD socket层区别(对应数据结构为struct socket):BSD socket层提供一组统一的接口,与协议无关;但具体到网络层

就必须与协议相关了,因此操作也会有一些不同。

代码如下(有删节):

static int __initinet_init(void)

{

struct sk_buff *dummy_skb;

struct inet_protosw *q;

struct list_head *r;

rc = sk_alloc_slab(&tcp_prot, "tcp_sock");

rc = sk_alloc_slab(&udp_prot, "udp_sock");

rc = sk_alloc_slab(&raw_prot, "raw_sock");

//Tell SOCKET that we are alive

(void)sock_register(&inet_family_ops);

//Add all the base protocols.

if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0);

if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0);

for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)

INIT_LIST_HEAD(r);

for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q) inet_register_protosw(q);

//Set the ARP module up

arp_init();

//Set the IP module up

ip_init();

tcp_v4_init(&inet_family_ops);

tcp_init();

//dev_add_pack(&ip_packet_type);

}

module_init(inet_init);

这个函数中包括的主要函数包括:

sock_register:在以前的文章中说过,Linux内核网络协议栈采用了分层结构,所以层与层之间肯定是

松耦合的。上层的socket层并不知道下面的网络协议层都具体包括哪些协议。因此本函数有两个作用:(a)周知INET协议族;(b)注册到socket模块上。

inet_add_protocol:在协议族中添加具体的协议。

inet_register_protosw:各种inet协议族中的协议在内核中是保存在inetsw_array[]数组,其中元素为

inet_protosw类型(/include/net/protocol.h文件中),每一个元素对应一个协议。每一个协议又有两个

数据结构:struct proto/structproto_ops。这两个结构中都是一些函数操作,但proto表示每个协议独特

的操作,而proto_ops是通用的socket操作(包含在struct socket中);这种区别就类似于INET socket

和BSD socket的区别。

(c)sock_init(在文件/net/socket.c中):BSD socket层

定义如下(代码有删节):

void __initsock_init(void)

{

//Initialize sock SLAB cache.

sk_init();

//Initialize skbuff SLAB cache

skb_init();

//Initialize the protocols module.

init_inodecache();

register_filesystem(&sock_fs_type);

sock_mnt = kern_mount(&sock_fs_type);

//The real protocol initialization is performed when do_initcalls is run.

netfilter_init();

}

此函数主要执行的工作是:初始化sock和sk_buff数据结构(这些重要的数据结构在后面的文章中还

会涉及);由于sock属于linux文件系统的一部分,因此要注册成为文件系统;以及如果使用netfilter,也要进行初始化。

Linux内核网络协议栈笔记3:重要数据结构sk_buff

sk_buff,全称socket buffers,简称skb,中文名字叫套接字缓存。它可以称得上是Linux内核网络协议栈中最重要的数据结构,没有之一。它作为网络数据包的存放地点,使得协议栈中每个层都可以对数据进行操作,从而实现了数据包自底向上的传递。

主要参考资料是《Understanding Linux Network Internals》Part I--Chapter 2.1中关于sk_buff的介绍。由于这个结构比较庞大,笔者主要选择比较重要的部分进行介绍,其余的还请看参考资料。

(1)一些重要字段

struct sock *sk;

指向拥有这个缓存的那个sock(注意,这里是sock,不是socket,缓存是由具体协议拥有的)。

structnet_device *dev;

接收或者发送这个数据包队列的网络设备。参见笔者前面所写的文章(点这里)。

(2)sk_buff的创建和销毁

dev_alloc_skb/dev_kfree_skb函数负责sk_buff的创建和销毁,其内部分别调用了alloc_skb/kfree_skb。其内部实现就不再介绍了,但关于销毁和资源释放有一点需要注意:由于同一个sk_buff有可能被很多对象使用,所以使用了引用计数(reference count),当没有人使用之后,才能释放其资源。

(3)布局(Layout)

sk_buff的实现方式是双向链表。不仅每个节点有next指针指向下一元素,prev指针指向前一元素,又包含一个指向头结点的指针;同时链表的头结点比较特殊,包括了链表长度和一个自旋锁用于同步,因此形成了如下的结构:

关于布局,sk_buff实现的另一个重要功能就是:当数据包从最底层的数据链路层向上传递到传输层时,进行一些处理。例如,IP层把数据包交给传输层时,就需要把IP头去掉。下面的图演示了一个UDP

的数据包在发送时添加UDP报头和IP报头的过程:

这个功能还需要另外三个成员变量,分别指向了传输层的头部(h),网络层的头部(nh=network header),数据链路层的头部(mac):

union {...} h

union {...} nh

union {...} mac

在2.6.30内核中这三个字段改为了:

sk_buff_data_t transport_header;

sk_buff_data_t network_header;

sk_buff_data_t mac_header;

下面的例子表示了在经过mac层的传输过程中data字段的变化,被mac层接收之后,data指向了IP包头开始的地方(请回忆相关的网络知识):

(4)管理函数

skb_reserve, skb_put, skb_push, and skb_pull等函数可以用于缓存的空间管理。例如,在数据包从上层向下传输时,因为要添加下层协议的报头,这个时候就可以根据最大可能添加的长度预留空间,这样就无需每经过一层分配一次空间,降低了系统开销。

还有另外一些以skb_queue开头的函数,表示对双向链表操作的函数。

Linux内核网络协议栈笔记4:接收网络数据包详细过程

网络数据接收过程,从数据包到达网卡的物理接口开始,然后由网卡的驱动程序交给网络协议栈,最后经过协议栈的一层层处理之后交给应用程序。大致上是这样的过程,但实际上有更多的细节。本文中主要介绍第一个和第二个步骤。

我们本文中依然以一个Realtek 8139网卡为例(驱动程序为/drivers/net/8139too.c)。请注意在内核代码中receive都是用rx简写的。

(1)注册与激活软中断

在生成net_device对象及初始化的函数rtl8139_init_one中已经初始化dev->open方法为rtl8139_open函数(在本系列文章2:初始化中的net_device对象中已经介绍,点这里查看)。在rtl8139_open函数(这个函数在网卡启动时被调用)中注册了一个中断函数rtl8139_interrupt:

retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);

所以只要当网卡开启后(状态为up),当网络数据包到达时,都会产生一个硬件中断(这不同于后面的软中断)。这个硬件中断由内核调用中断处理程序rtl8139_interrupt函数处理。这个函数比较重要,网卡发送或者接收数据时内核都会调用这个函数处理中断,而中断的类型是根据网卡状态寄存器的不同而确定的。本文中仅涉及接收数据的中断,因此只给出了接收的代码:

static irqreturn_t rtl8139_interrupt

(int irq, void *dev_instance,struct pt_regs *regs)

{

if (status & RxAckBits){

if (netif_rx_schedule_prep(dev))

__netif_rx_schedule (dev);

}

}

主要函数为__netif_rx_schedule(函数名意为:network interface receive schedule,即网络接口接收调度),因为当网卡接收到数据包之后,马上告知CPU在合适的时间去启动调度程序,轮询(poll)网卡。

请注意:Linux接收网络数据实际上有两种方式。

(a)中断。每个数据包到达都会产生一个中断,然后由内核调用中断处理程序处理。

(b)NAPI(New API)。Linux内核2.6版本之后加入的新机制,核心方法是:不采用中断的方式读

取数据,而代之以首先采用中断唤醒数据接收的服务程序,然后以POLL的方法来轮询数据。

因此本文中只介绍NAPI的接收方式。我们不再详细介绍这种机制,网上可找到比较多的资料,可以参考IBM的技术文章:NAPI 技术在 Linux 网络驱动上的应用和完善。

__netif_rx_schedule函数的定义如下:

static inline void __netif_rx_schedule(struct net_device *dev)

{

local_irq_save(flags);//disable interrupt

//Add interface to tail of rx poll list

list_add_tail(&dev-

>poll_list,&__get_cpu_var(softnet_data).poll_list);

//activate network rxsoftirq

__raise_softirq_irqoff(NET_RX_SOFTIRQ);

local_irq_restore(flags);

}

这个函数最核心的就是三步:

(a)local_irq_save:禁用中断

(b)list_add_tail:将设备添加到softnet_data的poll_list中。

(c)激活一个软中断NET_RX_SOFTIRQ。

======================================

说到这里我们必须介绍一个关键数据结构softnet_data,每个CPU都拥有一个这样的网络数据队列(所以函数中使用了__get_cpu_var函数取得),定义如下:

struct softnet_data

{

int throttle;

int cng_level;

int avg_blog;

struct sk_buff_head input_pkt_queue;

struct list_head poll_list;

struct net_device output_queue;

struct sk_buff completion_queue;

struct net_device backlog_dev;

};

大致说明一下这个数据结构的意义。某个网卡产生中断之后,内核就把这个网卡挂载到轮询列表(poll_list)中。一个CPU会轮询自己的列表中的每一个网卡,看看它们是不是有新的数据包可以处理。我们需要先用一个比喻说明这个数据结构与轮询的关系:网卡就是佃户,CPU就是地主。佃户有自己种的粮食(网络数据包),但地主家也有粮仓(softnet_data)。地主要收粮的时候,就会挨家挨户的去催佃户交粮,放到自己的粮仓里。

=======================================

(2)软中断处理

我们知道:激活软中断之后,并不是马上会被处理的。只有当遇到软中断的检查点时,系统才会调用相应的软中断处理函数。

所有的网络接收数据包的软中断处理函数都是net_rx_action。这个函数的详细注释可以看IBM的那篇技术文章。其核心语句就是一个轮询的函数:

dev->poll

就调用了相应设备的poll函数。也就是说,当CPU处理软中断时,才去轮询网卡,把数据放入softnet_data中。

下面是整个中断和轮询过程的一个示意图:

下面我们解释一下poll函数具体干了什么事情。

而我们知道,在Realtek 8139网卡的net_device对象中我们已经注册了一个poll函数:

dev->poll = rtl8139_poll

那么一次poll就表示从网卡缓冲区取出一定量的数据。而rtl8139_poll函数中调用的主要函数就是

rtl8139_rx函数。这个函数是完成从网卡取数据,分配skb缓冲区的核心函数。其核心代码如下:static int rtl8139_rx(struct net_device *dev, struct rtl8139_private*tp, i nt budget)

{

skb = dev_alloc_skb (pkt_size + 2);

eth_copy_and_sum (skb, &rx_ring[ring_offset + 4],

pkt_size,0);//memcpy

skb->protocol = eth_type_trans (skb, dev);

netif_receive_skb (skb);

}

工作主要分为4部分:

(a)给sk_buff数据结构(skb)分配空间。

(b)从网卡的环形缓冲区rx_ring中拷贝出网络数据包放到sk_buff对象skb中。这个函数实质上就是一个memcpy函数。

(c)在skb中标识其协议为以太网帧。

(d)调用netif_receice_skb函数。

netif_receive_skb函数相对比较重要。函数主体是两个循环:

list_for_each_entry_rcu(ptype, &ptype_all, list)

{

if (!ptype->dev || ptype->dev == skb->dev)

{

if (pt_prev)

ret = deliver_skb(skb, pt_prev);

pt_prev = ptype;

}

}

list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) { if (ptype->type == type && (!ptype->dev || ptype->dev == skb->dev))

{

if (pt_prev)

ret = deliver_skb(skb, pt_prev);

pt_prev = ptype;

}

}

两个循环分别遍历了两个链表:ptype_all和ptype_base。前者是内核中注册的sniffer,后者则是注册到内核协议栈中的网络协议类型。如果skb中的协议类型type与ptype_base中的类型一致,那么使用deliver_skb函数发送给这个协议一份,定义如下:

static __inline__ int deliver_skb(struct sk_buff *skb, struct packet_type * pt_prev)

{

atomic_inc(&skb->users);

return pt_prev->func(skb, skb->dev, pt_prev);

}

这个函数只是一个封装函数,实际上调用了每个packet type结构中注册的处理函数func。

struct packet_type {

unsigned short type;

struct net_device *dev;

int (*func) (struct sk_buff *,

struct net_device *, struct packet_type *);

void *af_packet_priv;

struct list_head list;

};

例如:IP包类型的处理函数就是ip_rcv(定义在/net/ipv4/ip_output.c文件中),定义如下:static struct packet_typeip_packet_type = {

.type = __constant_htons(ETH_P_IP),

.func = ip_rcv,

};

这个包的类型是在ip_init协议初始化时添加到全局的ptype_base哈希数组中的:

void __initip_init(void)

{

dev_add_pack(&ip_packet_type);

}

Linux系统与网络管理试题09(试卷)

Linux系统与网络管理试卷 考试科目:Linux系统与网络管理试卷代号: B 适用对象:使用学期:2013-2014-1 共4道题总分100分共3页 考生须知: 1)姓名必须写在装订线左侧,其它位置一律作废。 2)请先检查是否缺页,如缺页应向监考教师声明,否则后果由考生负责。 3)答案一律写在答题纸上,可不抄题,但要标清题号。 监考须知:请将两份题签放在上层随答题纸一起装订。 一、填空题(20空,每空2分,共40分) 1.Linux与其他操作系统的最大区别是()。 2.swap交换空间,相当于Windows上的()如果计算机的内存为2GB,则一般需要将交换分区容量设置为()至()。 3.Linux的GNOME菜单的应用程序子菜单位相当于Windows的()菜单中的()。 4.group文件用于保存Linux中组的信息,每一行代表一个组的()数据。 5.Linux系统中文件的属性可以使用( )查看。 6.创建逻辑卷有多种方法,可以在系统安装时创建;也可以在系统安装好后用指令创建与管理,或者在桌面环境中,用()创建与管理。 7.httpd.conf文件中MinSpareThreads表示最小空闲线程数,默认值是()。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的()线程。 8.执行( )命令查看nfs服务器可挂载的目录。 9.邮件服务器在工作时,发件人使用()撰写邮件,完成邮件编辑后进行提交。提交后()使用()协议,将邮件传给发件人所在域的()。 10.一台标准的SendMail服务器,需要安装包括()、()

Linux系统与网络管理 和()等服务器端软件,及()或其他MUA服务程序。 二、选择题(10小题,每小题2分,共20分) 1.UNIX是()操作系统。 A.单用户单任务B.多用户单任务 C.单用户多任务D.多用户多任务 2.()目录是定义Apache服务器站点存放目录; A./var B./var/www C./lib D./www 3.()不是Linux的GNOME桌面环境中“外观首选项”工具提供的配置桌面的各个外观的功能的选项卡。 A.主题B.背景 C.字体D.屏幕保护 4.如果不想退出普通用户,重新用root用户登录,就必须使用()命令切换到root。 A.su B.id C.who D.lastb 5.()命令是linux系统标准的进程查看工具,通过它可查看系统中进程的详细信息 A.ls B.Pstree C.ps D.Top 6.在使用物理RAID5方式工作时,至少需要()块硬盘。 A. 1 B. 2 C. 3 D. 4 7. 用于文件系统直接修改文件权限管理命令为:()。 A. chown B. chgrp C. chmod D. umask 8.Samba的主配置文件是(),默认位于/etc/samba/目录下。 A.smb.conf B.samba.conf C.smb.con D.samba.con

实验四Linux内核移植实验

合肥学院 嵌入式系统设计实验报告 (2013- 2014第二学期) 专业: 实验项目:实验四 Linux内核移植实验 实验时间: 2014 年 5 月 12 实验成员: _____ 指导老师:干开峰 电子信息与电气工程系 2014年4月制

一、实验目的 1、熟悉嵌入式Linux的内核相关代码分布情况。 2、掌握Linux内核移植过程。 3、学会编译和测试Linux内核。 二、实验内容 本实验了解Linux2.6.32代码结构,基于S3C2440处理器,完成Linux2.6.32内核移植,并完成编译和在目标开发板上测试通过。 三、实验步骤 1、使用光盘自带源码默认配置Linux内核 ⑴在光盘linux文件夹中找到linux-2.6.32.2-mini2440.tar.gz源码文件。 输入命令:#tar –jxvf linux-2.6.32.2-mini2440-20110413.tar对其进行解压。 ⑵执行以下命令来使用缺省配置文件config_x35 输入命令#cp config_mini2440_x35 .config;(注意:x35后面有个空格,然后有个“.”开头的 config ) 然后执行“make menuconfig”命令,但是会出现出现缺少ncurses libraries的错误,如下图所示: 解决办法:输入sudo apt-get install libncurses5-dev 命令进行在线安装ncurses libraries服务。

安装好之后在make menuconfig一下就会出现如下图所示。 ⑶配置内核界面,不用做任何更改,在主菜单里选择退出,并选“Yes”保存设置返回到刚命令行界面,生成相应配置的头文件。 编译内核: #make clean #make zImage 在执行#make zImage命令时会出现如下错误: 错误:arch/arm/mach-s3c2440/mach-mini2440.c:156: error: unknown field 'sets' specified in initializer 通过网上查找资料 于是在自己的mach-mini2440.c中加入 #include

Linux设备驱动程序学习(5)-高级字符驱动程序操作[(2)阻塞型IO和休眠]

Linux设备驱动程序学习(5)-高级字符驱动程序操作[(2)阻 塞型I/O和休眠] Linux设备驱动程序学习(5) -高级字符驱动程序操作[(2)阻塞型I/O和休眠]这一部分主要讨论:如果驱动程序无法立即满足请求,该如何响应?(65865346) 一、休眠 进程被置为休眠,意味着它被标识为处于一个特殊的状态并且从调度器的运行队列中移走。这个进程将不被在任何CPU 上调度,即将不会运行。直到发生某 些事情改变了那个状态。安全地进入休眠的两条规则: (1)永远不要在原子上下文中进入休眠,即当驱动在持有一个自旋锁、seqlock或者RCU 锁时不能睡眠;关闭中断也不能睡眠。持有一个信号量时休眠是 合法的,但你应当仔细查看代码:如果代码在持有一个信号量时睡眠,任何其他的等待这个信号量的线程也会休眠。因此发生在持有信号量时的休眠必须短暂, 而且决不能阻塞那个将最终唤醒你的进程。 (2)当进程被唤醒,它并不知道休眠了多长时间以及休眠时发生什么;也不知道是否另有进程也在休眠等待同一事件,且那个进程可能在它之前醒来并获取了 所等待的资源。所以不能对唤醒后的系统状态做任何的假设,并必须重新检查等待条件来确保正确的响应。 除非确信其他进程会在其他地方唤醒休眠的进程,否则也不能睡眠。使进程可被找到意味着:需要维护一个称为等待队列的数据结构。它是一个进程链表,其中饱含了等待某个特定事件的所有进程。在Linux 中,一个等待队列由一个wait_queue_head_t 结构体来管理,其定义在中。 wait_queue_head_t 类型的数据结构非常简单: 它包含一个自旋锁和一个链表。这个链表是一个等待队列入口,它被声明做wait_queue_t。wait_queue_head_t包含关于睡眠进程的信息和它想怎样被唤

设备驱动加到Linux内核中

7.2.3 设备驱动加到Linux内核中 设备驱动程序编写完后将该驱动程序加到内核中。这需要修改Linux 的源代码,然后重新编译内核。 ①将设备驱动程序文件(比如mydriver.c)复制到/Linux/drivers/char目录下。该目录保存了Linux下字符设备的设备驱动程序。修改该目录下mem.c 文件,在int chr_dev_init()函数中增加如下代码: #ifdef CONFIG_MYDRIVER device_init(); #endif 其中CONFIG_MYDRIVER是在配置Linux内核时赋值。 ②在/linux/drivers/char目录下Makefile中增加如下代码: ifeq ($(CONFIG_MYDRIVER),y) L_OBJ + = mydriver.o endif 如果在配置Linux内核时选择了支持新定义的设备,则在编译内核时会编译mydriver.c生成mydriver.o文件。 ③修改/linux/drivers/char目录下config.in文件,在 comment Character devices 语句下面加上 bool suppot for mydriver CONFIG_MYDRIVER 这样,若编译内核,运行make config,make menuconfig或make xconfig,那么在配置字符设备时就会有选项: Support for mydriver 当选中这个设备时,设备驱动就加到了内核中了。 重新编译内核,在shell中将当前目录cd 到Linux目录下,然后执行以下代码: # make menuconfig # make dep # make 在配置选项时要注意选择支持用户添加的设备。这样得到的内核就包含用户的设备驱动程序。 Linux通过设备文件来提供应用程序和设备驱动的接口,应用程序通过标准的文件操作函数来打开、关闭、读取和控制设备。查看Linux文件系统下的/proc/devices,可以看到当前的设备信息。如果设备驱动程序已被成功加进,这里应该由该设备对应的项。/proc/interrupts纪录了当时中断情况,可以用来查看中断申请是否正常;对于DMA和I/O口的使用,在/proc下都有相应的文件进行记录;还可以在设备驱动程序中申请在/proc 文件系统下创建一个文件,该文件用来存放设备相关信息。这样通过查看该文件就可以了解设备的使用情况。总之,/proc文件系统为用户提供了查

嵌入式Linux内核移植详解(顶嵌)

内核移植阶段 内核是操作系统最基本的部分。它是为众多应用程序提供对计算机硬件的安全访问的一部分软件,这种访问是有限的,并且内核决定一个程序在什么时候对某部分硬件操作多长时间。直接对硬件操作是非常复杂的,所以内核通常提供一种硬件抽象的方法来完成这些操作。硬件抽象隐藏了复杂性,为应用软件和硬件提供了一套简洁,统一的接口,使程序设计更为简单。 内核和用户界面共同为用户提供了操作计算机的方便方式。也就是我们在windows下看到的操作系统了。由于内核的源码提供了非常广泛的硬件支持,通用性很好,所以移植起来就方便了许多,我们需要做的就是针对我们要移植的对象,对内核源码进行相应的配置,如果出现内核源码中不支持的硬件这时就需要我们自己添加相应的驱动程序了。 一.移植准备 1. 目标板 我们还是选用之前bootloader移植选用的开发板参数请参考上文的地址: https://www.sodocs.net/doc/ab2211091.html,/thread-80832-5-1.html。bootloader移植准备。 2. 内核源码 这里我们选用比较新的内核源码版本linux-2.6.25.8,他的下载地址是 ftp://https://www.sodocs.net/doc/ab2211091.html,/pub/linux/kernel/v2.6/linux-2.6.25.8.tar.bz2。 3. 烧写工具 我们选用网口进行烧写这就需要内核在才裁剪的时候要对网卡进行支持 4. 知识储备 要进行内核裁剪不可缺少的是要对内核源码的目录结构有一定的了解这里进 行简单介绍。 (1)arch/: arch子目录包括了所有和体系结构相关的核心代码。它的每一个子 目录都代表一种支持的体系结构,例如i386就是关于intel cpu及与之相兼容体 系结构的子目录。PC机一般都基于此目录。 (2)block/:部分块设备驱动程序。 (3)crypto:常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验 算法。 (4) documentation/:文档目录,没有内核代码,只是一套有用的文档。 (5) drivers/:放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目 录:如,/block 下为块设备驱动程序,比如ide(ide.c)。 (6)fs/:所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持 一个文件系统, 例如fat和ext2。

Linux网络管理及应用课后习题参考答案

Linux 网络管理及应用 习题参考答案 第1章Linux网络操作系统 1.Linux的创始人是谁? 答:Linus Torvalds 2.Linux与Unix操作系统有什么关系? 答:Linux是一种类Unix操作系统,完全与POSIX标准兼容,是该标准的一种实现。 3.Linux与GNU项目是什么关系?它是开源软件吗?是自由软件吗? 答:Linux是一个操作系统内核,并不是一个完整的操作系统;GNU项目是面向开发一个操作系统,采用了Linux作为其系统内核。Linux遵守GNU GPL协议,是自由软件,同时它也是开源软件。 4.开源软件与自由软件有什么区别与联系? 答:自由软件指得是对于软件所拥有的“自由”的权利,包括三种自由;开源软件是一种软件开发方法,面向建立高质量软件。用户可以获得源代码是这两者共同之处。 5.安装Linux一般如何分区?选择哪种文件系统? 答:一般至少分为两个区:根文件系统分区和交换分区。根分区一般选择ext3格式的文件系统,交换分区采用swap格式。 6.Linux支持哪几种安装方式? 答:Linux支持多种安装方式:光盘、网络、本地磁盘等。 7.Linux系统中一个文件的全路径为/etc/passwd,表示了文件的哪些信息? 答:表示了文件的位置和文件的命名两部分信息。 8.什么是虚拟机?为什么要使用虚拟机? 答:虚拟机是利用软件虚拟技术虚拟一个计算机硬件环境的软件技术。使用虚拟机可以让一台高性能的计算机充分发挥其硬件的性能,提高系统的利用率;虚拟机也适合需要频繁更换使用不同操作系统的情况,如软件测试、教育等。 9.VMWare虚拟机中可以安装哪些操作系统? 答:可以安装微软Windows系列操作系统、Linux的多种发行版、MSDOS等许多操作系统。

02--基于ARM9的Linux2.6内核移植

基于ARM9的Linux2.6内核移植 姓名 系别、专业 导师姓名、职称 完成时间

目录 摘要................................................... I ABSTARCT................................................ II 1 绪论.. (1) 1.1课题研究的背景、目的和意义 (1) 1.2嵌入式系统现状及发展趋势 (1) 1.3论文的主要工作 (4) 2 嵌入式 Linux系统构成和软件开发环境 (5) 2.1嵌入式Linux系统的体系结构 (5) 2.2嵌入式Linux系统硬件平台 (5) 2.3嵌入式Linux开发软件平台建立 (7) 2.4本章小结 (11) 3 嵌入式Linux的引导BootLoader程序 (12) 3.1 BootLoader概述 (12) 3.2 NAND Flash和NOR Flash的区别 (13) 3.3本章小结 (19) 4 Linux内核的编译、移植 (20) 4.1 Linux2.6内核的新特性简介 (20) 4.2 Linux内核启动流程 (20) 4.3内核移植的实现 (21) 4.4 MTD内核分区 (23) 4.5配置、编译内核 (24) 4.6本章小结 (26) 5 文件系统制作 (27) 5.1 yaffs文件系统简介 (27) 5.2 内核支持YAFFS文件系统 (27) 5.3本章小结 (30) 6测试 (31) 6.1简单测试方法的介绍 (31) 6.2编写简单C程序测试移植的系统 (31) 6.3在开发板执行测试程序 (32)

内核配置与裁剪

内核配置与裁剪 1. Linux内核配置 内核配置的方法很多,make config、make xconfig、make menuconfig、make oldconfig 等等,它们的功能都是一样的。这里用的是make menuconfig。 过去基于2.x的内核为用户提供了四种基本的内核设置编辑器: ?. config 服务于内核设置的一个冗长的命令行界面; ?. oldconfig 一个文本模式的界面,主要包含一个已有设置文件,对用户所发现的内核资 源中的设置变量进行排序; ?. menuconfig 一个基于光标控制库的终端导向编辑器,可提供文本模式的图形用户界 面; ?. xconfig 一个图形内核设置编辑器,需要安装X-Window系统。 前三种编辑器在设置2.6内核时仍可使用,在运行“make xconfig”后,原有的界面被两个新的图形设置编辑器所代替。这需要具体的图形库和X-Window系统的支持。另外,用户还可以通过“make defconfig”命令,利用所有内核设置变量的缺省值自动建立一个内核设置文件。 下面具体介绍Linux内核配置选项: . 代码成熟度选项 Code maturity level options ---> [*] Prompt for development and/or incomplete code/drivers [*] Select only drivers expected to compile cleanly 在内核中包含了一些不成熟的代码和功能,如果我们想使用这些功能,想打开相关的配置选项,就必需打开这一选项。 . 通用设置选项 General setup ---> () Local version - append to kernel release [*] Automatically append version information to the version string [*] Support for paging of anonymous memory (swap)

am335x_linux-3.14.43内核移植笔记

本文主要描述在EVB335X-II以Device Tree的方式移植新TI官网AM335X系列最新的linux-3.14.43版本内核以及移植Debian文件系统的过程及遇到的一些问题。整个Device Tree牵涉面比较广,即增加了新的用于描述设备硬件信息的文本格式(即.dts文件),又增加 了编译这一文本的工具,同时Bootloader也需要支持将编译后的Device Tree传递给Linux 内核。以下是修改步骤: 一、修改uboot,支持Device Tree EVB335X-II在linux-3.2版本内核移植的时候已经有uboot,因此只需在该uboot上增加Device Tree支持即可,以下是修改步骤: 1、修改include/configs/com335x.h文件,增加支持DT的宏定义: /* Flattened Device Tree */ #define CONFIG_OF_LIBFDT 2、修改uboot启动参数,增加dtb文件的加载和启动(由于目前只是移植EMMC版本的EVB335X-II,因此只需修改EMMC的启动参数即可,大概在405行),修改如下: #elif defined(CONFIG_EMMC_BOOT) #define CONFIG_BOOTCOMMAND \ "run mmcboot;" #define CONFIG_EXTRA_ENV_SETTINGS \ "lcdtype=AUO_AT070TN94\0" \ "console=ttyO0,115200n8\0" \ "mmcroot=/dev/mmcblk0p2 rw\0" \ "mmcrootfstype=ext4 rootwait\0" \ "mmcargs=setenv bootargs console=${console} noinitrd root=${mmcroot} rootfstype=${mmcrootfstype} lcdtype=${lcdtype} consoleblank=0\0" \ "mmcdev=" MMCDEV "\0" \ "loadaddr=0x81000000\0" \ "dtbfile=evb335x-ii-emmc.dtb\0" \ "bootenv=uEnv.txt\0" \ "bootpart=" BOOTPART "\0" \ "loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \ "importbootenv=echo Importing environment from mmc ...; " \ "env import -t $loadaddr ${filesize}\0" \ "loadaddr-dtb=0x82000000\0" \ "loadimage=load mmc ${bootpart} ${loadaddr} uImage\0" \ "loaddtb=load mmc ${bootpart} ${loadaddr-dtb} ${dtbfile}\0" \ "mmcboot=mmc dev ${mmcdev}; " \ "if mmc rescan; then " \ "echo SD/MMC found on device ${mmcdev};" \ "if run loadbootenv; then " \ "echo Loaded environment from ${bootenv};" \ "run importbootenv;" \ "fi;" \ "run mmcargs;" \

Linux内核驱动加载顺序

Linux内核驱动加载顺序 【问题】 背光驱动初始化先于LCD驱动初始化,导致LCD驱动初始化时出现闪屏的现象。 【解决过程】 1 mach-xxx.c中platform devices列表如下 /* platform devices */ static struct platform_device *athena_evt_platform_devices[] __initdata = { //&xxx_led_device, &xxx_rtc_device, &xxx_uart0_device, &xxx_uart1_device, &xxx_uart2_device, &xxx_uart3_device, &xxx_nand_device, &xxx_i2c_device, &xxx_lcd_device, &xxxpwm_backlight_device, ... }; LCD(xxx_lcd_device)设备先于PWM(xxxpwm_backlight_device)设备。 可见驱动的初始化顺序并不是和这个表定义的顺序始终保持一致的。(记得PM操作 - resume/suspend 的顺序 是和这个表的顺序保持一致的) 2 怀疑和编译顺序有关 Z:\kernel\drivers\video\Makefile:背光驱动(backlight/)的编译限于LCD驱动(xxxfb.o)的编译 obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-y += backlight/ display/ ... obj-$(CONFIG_FB_xxx) += xxxfb.o ak_logo.o obj-$(CONFIG_FB_AK88) += ak88-fb/ 这样编译生成的System.map中的顺序为: 906 c001f540 t __initcall_pwm_backlight_init6 907 c001f544 t __initcall_display_class_init6 908 c001f548 t __initcall_xxxfb_init6 Makefile更改为: obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-y += display/

linux网络操作系统和实训课后习题答案解析

练习题 一、选择题 1. Linux 最早是由计算机爱好者 B 开发的。 A. Richard Petersen B. Linus Torvalds C. Rob Pick D. Linux Sarwar 2. 下列 C 是自由软件。 A. Windows XP B. UNIX C. Linux D. Windows 2000 3. 下列 B 不是Linux 的特点。 A. 多任务 B. 单用户 C. 设备独立性 D. 开放性 4. Linux 的内核版本2.3.20 是 A 的版本。 A. 不稳定 B. 稳定的 C. 第三次修订 D. 第二次修订 二、填空题 1. GUN 的含义是:GNU's Not UNIX。 2. Linux 一般有3 个主要部分:内核(kernel)、命令解释层(Shell 或其他操作环境)、 实用工具。 三、简答题(略) 1. 简述Red Hat Linux 系统的特点。 2. 简述一些较为知名的Linux 发行版本。 练习题 一、选择题 1. Linux 安装过程中的硬盘分区工具是 D 。 A. PQmagic B. FDISK C. FIPS D. Disk Druid 2. Linux 的根分区系统类型是 C 。 A. FATl6 B. FAT32 C. ext3 D. NTFS 二、填空题 1. 安装Linux 最少需要两个分区,分别是 swap 交换分区和/(根)分区。 2. Linux 默认的系统管理员账号是 root 。 3. X-Window System 由三部分构成:X Server、X Client 和通信通道。 三、简答题(略) 1. Linux 有哪些安装方式 2. 安装Red Hat Linux 系统要做哪些准备工作 3. 安装Red Hat Linux 系统的基本磁盘分区有哪些 4. Red Hat Linux 系统支持的文件类型有哪些 练习题 一、选择题 1. C 命令能用来查找在文件TESTFILE 中包含四个字符的行 A. grep’’TESTFILE B. grep’….’TESTFILE C. grep’^$’TESTFILE D. grep’^….$’TESTFILE 2. B 命令用来显示/home 及其子目录下的文件名。 A. ls -a /home B. ls -R /home C. ls -l /home D. ls -d /home 3. 如果忘记了ls 命令的用法,可以采用 C 命令获得帮助 A. ls B. help ls C. man ls D. get ls 4. 查看系统当中所有进程的命令是 D 。 A. ps all B. ps aix C. ps auf D. ps aux

Linux内核裁剪实例

Linux内核裁剪实例 从零开始配置内核是不明智的,建议在某一个默认配置的基础上进行修改,以达到自己产品的实际需求。 裁剪和配置内核的基本原则: ?基于某一个最接近的主板配置来修改; ?必须的、能确定的选项选中; ?不能确定的则不要改变原来配置; ?可选可不选的,建议根据help信息决定或者不选; ?一次改动不要太多,渐进式修改和验证; ?注意及时备份配置文件,出现意外可以回退恢复。 下面给出一些常见功能的配置裁剪实例,很多功能与所采用的主板硬件相关,与其它不同主板的内核配置上不一定完全相同,但还是有一些参考意义。 1.1.1 GPIO子系统配置 Linux 2.6以上内核引入了子系统,GPIO子系统将全部GPIO的操作接口都通过 “/sys/class/gpio/”目录导出,非常方便用户使用。 输入下列命令,进入内核配置菜单: $ make ARCH=arm menuconfig 在主菜单界面中选择“Device Drivers”: [*] Networking support ---> Device Drivers ---> File systems ---> Kernel hacking ---> 进入“Device Drivers”界面,选择并进入“GPIO Support”: [*] SPI support ---> PPS support ---> PTP clock support -*- GPIO Support ---> <*> PWM Support ---> 在“GPIO Support”中选中“/sys/cla ss/gpio…”: --- GPIO Support [*] /sys/class/gpio/... (sysfs interface) *** Memory mapped GPIO drivers: *** … 配置后重新编译内核,使用新内核的系统即可通过“/sys/class/gpio/”访问系统的GPIO 了。

linux笔记

20150526 echo adfkjeroiu > /var/www/html/index.html service httpd restart ifconfig XXX.XXX.XXX.XXX elinks XXX.XXX.XXX.XXX web地址栏:XXX.XXX.XXX.XXX 20150527 方法一:Setup 设置IP 方法二:vim /etc/sysconfig/network-XXX/ifcfg-eth0 onboot=no改onboot=yes service network restart 虚拟机中安装2个linux,有时2个linux无法连接网络,即使是DHCP自动获取,也不可以;解决办法:打开其中一个linux虚拟机,单机“右下角-小电脑图标” —“设置”—“桥接模式(B);直接连接屋里网络” ,确定即可; 20150528 more /etc/issue 查看当前linux是centos还是redhat; man 命令查看当前命令的使用方法及参数 table 当一个命令不记得全部字母,可以双击table补齐; ctrl +c 终止当前程序 ctrl +l 清屏 20150529 ls -l查看命令;(-l显示更多属性) ls –a 查看隐藏文件; cp -r /etc/aaa /home/bbb复制/etc下的aaa 到/home下,并且改名bbb; (-r是整个文件夹的意思,如果,没有-r是复制单个文件) mv /etc/aaa /home/bbb 移动/etc下的aaa 到/home下,并且改名bbb;

rm –r 删除一个文件;(如果要是一个文件夹,就有询问yes或no) rm –rf 删除一个文件夹;(如果要是一个文件夹,就无询问) touch 创建文件; pwd 查看当前路径; cd.. 返回相对路径; cd / 返回绝对路径; cd- 返回刚才的路径; su – root或其它用户切换用户; mkdir 创建新目录; cat 查看文件内容; more或less 逐屏查看文件内容; useradd 新添加的用户,在没有更改密码前,无法登陆; passwd 更改密码;但是,密码必须符合复杂性; groupadd 添加一个组; 20150602 w 查看谁登陆过本计算机以及对方的IP; last 查看用户的登录日志; lastlog 查看每个用户最后登录的情况;(一般用于电脑被黑了之后); more /var/log/secure who /var/log/wtmp 干了些什么? root账户下输入su - username 切换到username下输入 history 能看到这个用户历史命令,默认最近的1000条 Linux查看History记录加时间戳小技巧 1.[root@servyou_web ~]# export HISTTIMEFORMAT="%F %T `whoami` " 2.[root@servyou_web ~]# history | tail 3. 1014 2011-06-22 19:17:29 root 15 2011-06-22 19:13:02 root ./test.sh 4. 1015 2011-06-22 19:17:29 root 16 2011-06-22 19:13:02 root vim test.sh 5. 1016 2011-06-22 19:17:29 root 17 2011-06-22 19:13:02 root ./test.sh 6. 1017 2011-06-22 19:17:29 root 18 2011-06-22 19:13:02 root vim test.sh 7. 1018 2011-06-22 19:17:29 root 19 2011-06-22 19:13:02 root ./test.sh 8. 1019 2011-06-22 19:17:29 root 20 2011-06-22 19:13:02 root vim test.sh 9. 1020 2011-06-22 19:17:29 root 21 2011-06-22 19:13:02 root ./test.sh

史上最全linux内核配置详解

对于每一个配置选项,用户可以回答"y"、"m"或"n"。其中"y"表示将相应特性的支持或设备驱动程序编译进内核;"m"表示将相应特性的支持或设备驱动程序编译成可加载模块,在需要时,可由系统或用户自行加入到内核中去;"n"表示内核不提供相应特性或驱动程序的支持。只有<>才能选择M 1. General setup(通用选项) [*]Prompt for development and/or incomplete code/drivers,设置界面中显示还在开发或者还没有完成的代码与驱动,最好选上,许多设备都需要它才能配置。 [ ]Cross-compiler tool prefix,交叉编译工具前缀,如果你要使用交叉编译工具的话输入相关前缀。默认不使用。嵌入式linux更不需要。 [ ]Local version - append to kernel release,自定义版本,也就是uname -r可以看到的版本,可以自行修改,没多大意义。 [ ]Automatically append version information to the version string,自动生成版本信息。这个选项会自动探测你的内核并且生成相应的版本,使之不会和原先的重复。这需要Perl的支持。由于在编译的命令make-kpkg 中我们会加入- –append-to-version 选项来生成自定义版本,所以这里选N。 Kernel compression mode (LZMA),选择压缩方式。 [ ]Support for paging of anonymous memory (swap),交换分区支持,也就是虚拟内存支持,嵌入式不需要。 [*]System V IPC,为进程提供通信机制,这将使系统中各进程间有交换信息与保持同步的能力。有些程序只有在选Y的情况下才能运行,所以不用考虑,这里一定要选。 [*]POSIX Message Queues,这是POSIX的消息队列,它同样是一种IPC(进程间通讯)。建议你最好将它选上。 [*]BSD Process Accounting,允许进程访问内核,将账户信息写入文件中,主要包括进程的创建时间/创建者/内存占用等信息。可以选上,无所谓。 [*]BSD Process Accounting version 3 file format,选用的话统计信息将会以新的格式(V3)写入,注意这个格式和以前的v0/v1/v2 格式不兼容,选不选无所谓。 [ ]Export task/process statistics through netlink (EXPERIMENTAL),通过通用的网络输出工作/进程的相应数据,和BSD不同的是,这些数据在进程运行的时候就可以通过相关命令访问。和BSD类似,数据将在进程结束时送入用户空间。如果不清楚,选N(实验阶段功能,下同)。 [ ]Auditing support,审计功能,某些内核模块需要它(SELINUX),如果不知道,不用选。 [ ]RCU Subsystem,一个高性能的锁机制RCU 子系统,不懂不了解,按默认就行。 [ ]Kernel .config support,将.config配置信息保存在内核中,选上它及它的子项使得其它用户能从/proc/ config.gz中得到内核的配置,选上,重新配置内核时可以利用已有配置Enable access to .config through /proc/config.gz,上一项的子项,可以通过/proc/ config.gz访问.config配置,上一个选的话,建议选上。 (16)Kernel log buffer size (16 => 64KB, 17 => 128KB) ,内核日志缓存的大小,使用默认值即可。12 => 4 KB,13 => 8 KB,14 => 16 KB单处理器,15 => 32 KB多处理器,16 => 64 KB,17 => 128 KB。 [ ]Control Group support(有子项),使用默认即可,不清楚可以不选。 Example debug cgroup subsystem,cgroup子系统调试例子 Namespace cgroup subsystem,cgroup子系统命名空间 Device controller for cgroups,cgroups设备控制器

Linux内核移植开发手册

江苏中科龙梦科技有限公司 Linux内核移植开发手册 修 订 记 录 项 次 修订日期 版 本修订內容修订者审 核 1 2009‐02‐04 0.1 初版发行陶宏亮, 胡洪兵 2 2009‐11‐20 0.2 删除一些 多余文字 陶宏亮, 胡洪兵

DISCLAIMER THIS DOCUMENTATION IS PROVIDED FOR USE WITH LEMOTE PRODUCTS. NO LICENSE TO LEMOTE PROPERTY RIGHTS IS GRANTED. LEMOTE ASSUMES NO LIABILITY, PROVIDES NO WARRANTY EITHER EXPRESSED OR IMPLIED RELATING TO THE USAGE, OR INTELLECTUAL PROPERTY RIGHT INFRINGEMENT EXCEPT AS PROVIDED FOR BY LEMOTE TERMS AND CONDITIONS OF SALE. LEMOTE PRODUCTS ARE NOT DESIGNED FOR AND SHOULD NOT BE USED IN ANY MEDICAL OR LIFE SUSTAINING OR SUPPORTING EQUIPMENT. ALL INFORMATION IN THIS DOCUMENT SHOULD BE TREATED AS PRELIMINARY. LEMOTE MAY MAKE CHANGES TO THIS DOCUMENT WITHOUT NOTICE. ANYONE RELYING ON THIS DOCUMENTATION SHOULD CONTACT LEMOTE FOR THE CURRENT DOCUMENTATION AND ERRATA. JIANGSU LEMOTE TECHNOLOGY CORPORATION LIMITED MENGLAN INDUSTRIAL PARK,YUSHAN,CHANGSHU CITY,JIANGSU PROVINCE,CHINA Tel: 0512‐52308661 Fax: 0512‐52308688 Http: //https://www.sodocs.net/doc/ab2211091.html,

实验5 linux内核的裁剪移植

实验5 linux内核的裁剪移植 一、实验目的: 学习利用menuconfig配置文件进行裁减内核,编译内核并移植到开发板上。 二、实验内容 一、开发环境 宿主机:ubuntu10.04 开发板:tiny6410 编译器:4.3.2 二、内核移植 1.下载源码 ftp://https://www.sodocs.net/doc/ab2211091.html,/pub/linux/kernel/v2.6/linux-2.6.38.tar.bz2 此实验所需的文件放到/home/embedded/11目录下: linux-2.6.38.tar.bz2, yaffs2.tar.bz2 s3c_nand.c , s3c_nand_mlc.fo ,nand_base.c ,Kconfig ,regs-nand.h 2.解压 (进入根目录下的/home/poplar/expr4/kernel目录,解压源码)# cd /home # mkdir poplar/expr4/kernel –p # cd /home/poplar/expr4/kernel # cp /home/embedded/11/linux-2.6.38.tar.bz2 ./ tar xvfj /home/poplar/expr4/kernel/linux-2.6.38.tar.bz2

3.修改架构,编译器(需要在arm上运行,所以用交叉编译器)解压完进入解压出来的linux-2.6.38目录 #cd linux-2.6.38 #vi Makefile (或者用gedit)

191行改为 ARCH ?= arm //191行CROSS_COMPILE ?= /usr/local/arm/4.3.2/bin/arm-linux- (找到其交叉编译环境,把路径加全) //192行

linux读书笔记

12.29 Linux系统 Linux是真正的多用户、多任务操作系统。它继承了UNIX系统的主要特征,具有强大的信息处理功能,特别在Internet和Intranet的应用中占有明显优势。是一个完整的UNIX类操作系统。它允许多个用户同时在一个系统上运行多道程序。真正的32位操作系统。 用户接口 用户接口定义了用户和计算机交互作用的方式。Linux操作系统提供4种不同的用户接口。命令行接口 命令行是为具有操作系统使用经验,熟悉所用命令和系统结构的人员设计的。功能强大,使用方便的命令行是UNIX/Linux系统的一个显著特征。支持命令行的系统程序是命令解释程序。它的主要功能是接收用户输入的命令,然后予以解释并执行。 “$ ”是系统提示符。 在UNIX/Linux系统中,通常将命令解释程序称为shell。各种Linux环境下都安装了多种shell。这些shell由不同的人编写并得到一部分用户的青睐,各有其优势,最常用的几种是Bourne shell(sh),C shell(csh),Bourne Again shell(bash)和Korn shell(ksh)。红旗Linux 的默认shell是bash。 Bash 菜单 图形用户接口 程序接口 程序接口也称为系统调用接口。用户在自己的C程序中使用系统调用,从而获得系统提供的更基层的服务。 系统调用是操作系统内核与用户程序,应用程序之间的接口。在UNIX/Linux系统中,系统调用以C函数的形式出现。例如:fd=fopen(“file1.c”,2);其中,open是系统调用。 所有内核之外的程序都必须经由系统调用才能获得操作系统的服务。系统调用只能在C程序中使用,不能作为命令在终端上执行。由于系统调用能直接进入内核执行,所以其执行效率高。 Linux的版本 Linux有两种版本:核心(Kernel)版本和发行(Distribution)版本。 核心版本 核心版本主要是Linux的内核。Linux内核的官方版本由Linus Torvalds本人维护着。核心版本的序号由三部分数字构成,其形式为:major.minor.patchlevel 其中,major是主版本号,minor是次版本号,二者共同构成了当前核心版本好;patchlevel 表示对当前版本的修订次数。例如:2.6.34表示对2.6核心版本的第34次修订。

相关主题