GDT和LDT的关系

    最近在阅读Linux内存管理时,突然对GDT(Glocal Descriptor Table)和LDT(Local Descriptor Table)产生了一些疑问。他们在内存是怎样存放的呢?程序在运行时又是如何对GDT和LDT产生了影响?

    以下配图均来自《Linux内核完全注释(1.9.5版)》,所有的内容也都是基于Linux内核0.11版。其他Linux版本则需查看相应的代码进行分析

    在Linux内核0.11中,对GDT和LDT的声明和配置如下:
    Linux内核描述符表示意图

    从上图可以看到LDTR指向的是GDT中的一部分,确切的说是指向了GDT的第五个描述符,而从这个描述符开始,包含了LDT。
    从相应的内核代码中,我们看到在task_struct的声明中,有如下内容:

    struct task_struct {
        ...
        struct desc_struct ldt[3];
        struct tss_struct tss;
    };
    

    这说明ldt是和每个task有关。每当需要创建新的process时,就需要在内存中把一块相应的区域划分给这个process的LDT:

    int copy_process(int nr, ...)
    {
        struct task_struct *p;
        p=(struct task_struct *)get_free_page();
        ...
        if (copy_mem(nr,p)) {
            //copy memory error will comes, here, free memory
            free_page((long) p);
            return -EAGAIN;
        }
        ...
        set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY, &(p->tss));
        set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, &(p->ldt));
        p->state=TASK_RUNNING;
        return last_pid;
    }
    

    在上述程序中set_ldt_desc函数的作用就是把p->ldt的地址赋值给(gdt+(nr<<1)+FIRST_LDT_ENTRY)这个内存,也即让(gdt+(nr<<1)+FIRST_LDT_ENTRY)的内容指向p->ldt,这样就完成了GDT对LDT的索引。
    nr是程序分配的新建任务的任务号,而return的是新建任务的进程号,这两个是不一样的。
    变量gdt表示GDT在内存中的地址,在文件head.s中定义的。
    FIRST_LDT_ENTRY是一个宏定义,表示数字5。从本文开头的图中可以看到,GDT的开始4项已经被占用。从第五项开始,保存着TSS(任务状态段)描述符和LDT(局部描述符表)描述符,所以任务nr的LDT描述符的地址相对于GDT地址是nr乘以2加上最初的偏移值,也即(nr<<1)+FIRST_LDT_ENTRY

    • 2
      点赞
    • 10
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值