| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 9455 人关注过本帖
标题:计算机
取消只看楼主 加入收藏
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
enum pid_type
{
    PIDTYPE_PID,   进程的PID
    PIDTYPE_PGID,  进程组ID
    PIDTYPE_SID,   会话ID
    PIDTYPE_MAX
};

搞这么多个组是因为有需要给一个组同时发信号,
比如有时,使用 kill -9 杀一个程序,有了组的概念,就比较方便杀死相关的线程和进程。
会话也一样,你退出了telnet,就必须杀死你登录时创建的所有非后台进程。有了会话id,杀就非常方便。

The quieter you become, the more you can hear
2012-09-23 00:36
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
pid 结构体中嵌套着upid结构体, upid结构体中又嵌套着pid_namespace 结构体

The quieter you become, the more you can hear
2012-09-23 00:43
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
如何将task_struct 实例变为数字ID,

这个过程包含下面两个步骤

1. 获得与task_struct 关联的pid 实例,辅助函数task_pid, task_tgid, task_pgrp 和 task_session 分别用于取得 不同类型的ID.
<sched.h>
static inline struct pid *task_pid(struct task_struct *task)
{
        return task->pids[PIDTYPE_PID].pid;
}

kernel/pid.c
在获得pid 实例之后, 从struct pid 的 numbers 数组中的 uid 信息, 即可获得数字ID
pid_t pid_nr_ns ( struct pid *pid, struct pid_namespace *ns)
{
        struct upid *upid;
        pid_t nr = 0;
        if( pid && ns->level <= pid->level) {
                upid = &pid->numbers[ns->level];
                if(upid->ns == ns )
                        nr = upid->nr;
        }
        return nr;
}

因为父命名空间可以看到子命名空间的PID, 反过来却不行,

内核必须确保当前命名空间的level 小于或等于产生局部PID的命名空间的level

同样重要的是, 内核只需要关注产生全局PID

The quieter you become, the more you can hear
2012-09-23 01:06
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
可以使用如下方法查看页的大小, 单位是字节,一般linux的结果是4096
$ getconf PAGESIZE

或者
$ getconf PAGE_SIZE


[ 本帖最后由 madfrogme 于 2012-9-24 10:50 编辑 ]

The quieter you become, the more you can hear
2012-09-24 09:49
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
alloc_pidmap()函数,这个函数的功能就是分配新的空闲PID号,
其中有一句
offset = pid & BITS_PER_PAGE_MASK;

BITS_PER_PAGE_MASK的定义为如下

kernel/pid.c
53 #define BITS_PER_PAGE           (PAGE_SIZE*8)
54 #define BITS_PER_PAGE_MASK      (BITS_PER_PAGE-1)

PAGE_SIZE查到是4096, 所以BITS_PER_PAGE 就是32768, 2^15 (1,000,000,000,000,000)

所以BITS_PER_PAGE_MASK 就是( 0,111,111,111,111,111)了

于是pid & BITS_PER_PAGE_MASK; 就是取 pid的下15位了
所以offset 最大只能为32767


[ 本帖最后由 madfrogme 于 2012-9-24 11:02 编辑 ]

The quieter you become, the more you can hear
2012-09-24 09:59
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
几个和pid 有关的定义
include/linux/pid_namespace.h 中
 struct pidmap {
        atomic_t nr_free;
        void *page;
 };

#define PIDMAP_ENTRIES         ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)

struct pid_namespace {
  ...
         struct pidmap pidmap[PIDMAP_ENTRIES];
         int last_pid;
         struct task_struct *child_reaper;
         struct kmem_cache *pid_cachep;
         unsigned int level;
         struct pid_namespace *parent;
 ...
}

include/linux/threads.h 文件

#ifndef _LINUX_THREADS_H
#define _LINUX_THREADS_H


/*
 * The default limit for the nr of threads is now in
 * /proc/sys/kernel/threads-max.
 */

/*
 * Maximum supported processors.  Setting this smaller saves quite a
 * bit of memory.  Use nr_cpu_ids instead of this except for static bitmaps.
 */
#ifndef CONFIG_NR_CPUS
/* FIXME: This should be fixed in the arch's Kconfig */
#define CONFIG_NR_CPUS    1
#endif

/* Places which use this should consider cpumask_var_t. */
#define NR_CPUS        CONFIG_NR_CPUS

#define MIN_THREADS_LEFT_FOR_ROOT 4

/*
 * This controls the default maximum pid allocated to a process
 */
#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)

/*
 * A maximum of 4 million PIDs should be enough for a while.
 * [NOTE: PID/TIDs are limited to 2^29 ~= 500+ million, see futex.h.]
 */
#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
    (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))

#endif

The quieter you become, the more you can hear
2012-09-24 10:24
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
arch/x86/kernel/process.c 中
sys_fork 的定义

 int sys_fork(struct pt_regs *regs)
 {
         return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
 }

pt_regs 结构体在arch/x86/include/asm/ptrace.h中有定义

struct pt_regs {
    long ebx;
    long ecx;
    long edx;
    long esi;
    long edi;
    long ebp;
    long eax;
    int  xds;
    int  xes;
    int  xfs;
    int  xgs;
    long orig_eax;
    long eip;
    int  xcs;
    long eflags;
    long esp;
    int  xss;
};

実際にはシステムコール側の関数の引数宣言がどのような 形になっていてもスタックに積まれている値は struct pt_regs の形式になっており,

通常は最初の 5 個のうちのいくつかがシステムコール側で使用されるようになって います.

すべてのシステムコールは int 0x80 で entry.S の ENTRY(system_call) を 経由してカーネルの関数が呼び出されるため,

実はどのシステムコールでも同じ 情報を受け取っていることになります

The quieter you become, the more you can hear
2012-09-24 23:50
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
execve システムコールではレジスタに以下のような情報を渡す必要があります.

    ebx : (char *)filename,
    ecx : char ** argv,
    edx : char ** envp

なぜなら,sys_execve 中では do_execve に次のように情報を渡しています

do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);

The quieter you become, the more you can hear
2012-09-24 23:52
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
Page Table Entries (PTE)

A page table entry is what represents a page.

We will not cover the page table until a little later so dont worry too much about it.

However we will need to look at what an entry in the table looks like now. T

he x86 architecture defines a specific bit format for working with pages, so lets take a look at it.

Bit 0 (P): Present flag
0: Page is not in memory
1: Page is present (in memory)

Bit 1 (R/W): Read/Write flag
0: Page is read only
1: Page is writable

Bit 2 (U/S):User mode/Supervisor mode flag
0: Page is kernel (supervisor) mode
1: Page is user mode. Cannot read or write supervisor pages

Bits 3-4 (RSVD): Reserved by Intel

Bit 5 (A): Access flag. Set by processor
0: Page has not been accessed
1: Page has been accessed

Bit 6 (D): Dirty flag. Set by processor
0: Page has not been written to
1: Page has been written to

Bits 7-8 (RSVD): Reserved

Bits 9-11 (AVAIL): Available for use

Bits 12-31 (FRAME): Frame address


[ 本帖最后由 madfrogme 于 2012-9-25 11:45 编辑 ]

The quieter you become, the more you can hear
2012-09-25 10:38
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
Lets give out a simple example.

Lets say that we want this page to manage the 4KB address space beginning at physical location 1MB (0x100000).

What this means--to put in other words--is that this page is "mapped" to address 1MB.

To create this page, simply set 0x100000 in bits 12-31 (the frame address) of the page, and set the present bit. Voila--the page is mapped to 1MB. :) For example:

%define        PRIV        3
mov        ebx, 0x100000 | PRIV    ; this page is mapped to 1MB

Notice that 0x100000 is 4KB aligned? It ORs it with 3 (11 binary which sets the first two bits. Looking at the above table,

we can see that it sets the present and read/write flags, making this page present

 (Meaning its in physical memory. This is true as it is mapped from physical address 0x100000), and is writable.

The quieter you become, the more you can hear
2012-09-25 10:57
快速回复:计算机
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029921 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved