No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

开始核心级线程

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

内核级线程对多核的支持怎么样?

和用户级相比,核心级线程有什么不同?

ThreadCreate 是系统调用,内核管理TCB ,内核负责切换线程

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

如何让切换成型? − − 内核栈,TCB

  • 用户栈是否还要用? 执行的代码仍然在用户态,还要进行函数调用
  • 一个栈到一套栈;两个栈到两套栈
  • TCB 关联内核栈,那用户栈怎么办?

 

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

用户栈和内核栈之间的关联

所有中断( 时钟、外设、INT指令) 都引起上述切换

中断( 硬件) 又一次帮助了操作系统…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

仍然是那个A() ,B() ,C() ,D()…

认真体会从内核返回( 中断返回) 时的样子…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

开始内核中的切换:switch_to

switch_to: 仍然是通过TCB 找到内核栈指针;然后通过ret 切到 某个内核程序; 最后再用CS:PC 切到

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

sys_read(){ 启动磁盘读; 将自己变成阻塞;找到next;switch_to(cur, next);}

回答上面的问号??, ???, ????…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

 

???: sys_read 函数的某个地方

??: interrupt 之前的某个地方

???: sys_xxx 函数中的某个地方

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

最关键的地方来了: T 创建时如何填写?? , ????

?? 500 ,函数C()的开始地址

???? 一段能完成第二级返回的代码,一段包含iret 的代码…

内核线程switch_to 的五段论

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

ThreadCreate! 做成那个样子…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

用户级线程、核心级线程的对比

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

 

操作系统Operating Systems内核级线程实现Create Kernel Threads

核心级线程的两套栈,核心是内核栈…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

整个故事要从进入内核开始—— 某个中断开始…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

切换五段论中的中断入口和中断出口

void sched_init(void)

{set_system_gate(0x80,&system_call);}

初始化时将各种中断处理设置好

_system_call:

push %ds..%fs

pushl %edx...

call sys_fork

pushl %eax

内核栈:

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

movl _current,%eax

cmpl $0,state(%eax)

jne reschedule

cmpl $0,counter(%eax)

je reschedule

ret_from_sys_call:

 

reschedule:

pushl $ret_from_sys_call

jmp _schedule

切换五段论中的schedule

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

 

切换五段论中的switch_to

Linux 0.11 用tss切换,但也可以用栈切换,因为tss 中的信息可以写到内核栈中

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

另一个故事ThreadCreate 就顺了…

从sys_fork 开始CreateThread

_sys_fork:

push %gs; pushl %esi

...

pushl %eax

call _copy_process

addl $20,%esp

ret

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

int copy_process(int nr,long ebp,long edi,long esi,long gs,longnone,long ebx,long ecx,long edx, longfs,long es,long ds,long eip,longcs,long eflags,long esp,long ss)

copy_process的细节:创建栈

p=(struct task_struct *)get_free_page();// 申请内存空间

p->tss.esp0 = PAGE_SIZE + (long) p;

p->tss.ss0 = 0x10;// 创建内核栈

p->tss.ss = ss & 0xffff;

p->tss.esp = esp;// 创建用户栈(和父进程共用栈)

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

申请内存空间;

创建TCB;

创建内核栈和用户栈;

填写两个 stack;

关联栈和TCB;

copy_process 的细节:执行前准备

p->tss.eip = eip;

p->tss.cs = cs & 0xffff;// 将执行地址cs:eip 放在tss 中

p->tss.eax = 0;

p->tss.ecx = ecx;// 执行时的寄存器也放进去了

p->tss.ldt = _LDT(nr);

set_tss_desc(gdt+(nr<<1) + 仔细体会tss 将要承担的作用…

FIRST_TSS_ENTRY, &(p->tss));

set_ldt_desc(gdt+(nr<<1) +

FIRST_LDT_ENTRY, &(p->ldt));// 内存跟着切换

p->state = TASK_RUNNING;

 

copy_process( ...,long eip,long cs,longe flags,long esp,long ss)

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

 

...

填写两个stack;

第三个故事: 如何执行我们想要的代码?

int main(int argc, char * argv[])

{ while(1) { scanf("%s", cmd);

if(!fork()) {exec(cmd);} wait(0); }

ThreadCreate(*A) 中的A 必须体现? 用户输入hello 命令,exec(hello)

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

fork() 何时返回0 ,何时不会? 首先要找到fork() 怎么返回?

mov %eax, __NR_fork

INT 0x80

mov res,%eax 如何到这条指令?

 

父进程用iret ,因为要从核心态到用户态;那么子进程呢? 仔细想一想…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

结构: 子进程进入A ,父进程等待…

故事要从exec 这个系统调用开始

if(!fork()) {exec(cmd);}

 

_system_call:

push %ds .. %fs

pushl %edx..

call sys_execve

 

_sys_execve:

lea EIP(%esp),%eax

pushl %eax

call _do_execve

 

EIP = 0x1C

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

终于可以让AA 执行了…

int do_execve( * eip,...

{     p += change_ldt(...;

  eip[0] = ex.a_entry;

  eip[3] = p; ...

 

struct exec {

unsigned long a_magic;

unsigned a_entry; //口 入口 };

 

eip[0] = esp + 0x1C; eip[3] = esp +0x1C+0x0C = esp + 0x28 ( 正好是SP)

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

ex.a_entry 是可执行程序入口地址,产生可执行文件时写入…

No00003A操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

  • 理解switch_to 对应的栈切换,将自己变成计算机
  • ThreadCreate的目的就是初始化这样一套栈

 

更多相关文章
  • 前面我们介绍了c++作为一个面向对象的高级编程语言,知道了面向对象的特征.今天就开始正式的学习c++了.          我们知道,c++的核心就是把程序功能化,结构化,那么结构化,就必须有类.          一个类,里面有变量,有方法(函数).类里边的变量,我们称他为成员变量,函数就称为成员 ...
  • 编者按:本文<图片+社交>来自于友群的创始人李杨,他在参加了36氪与经纬中国合作的#经纬中国线下分享会#后对于社交产品有一些想法. 图片+社交是一个老话题.今天在36氪的经纬活动上,大家的讨论也很认真,想到了一些问题,随手写下来. Harry提到一个有点尖锐的看法.大意是,如果你在国内做 ...
  • 随着业务.企业规模的日益壮大,DB的数量也在不断增多,配置一台新增DB,从服务器的参数配置,磁盘阵列规划,DB安装部署,DB参数调优等等一列步骤下来,手工操作的效率变得越来越低,因为我负责的数据库近些时间,不断地迁移.新增,很能感觉到1人安装多台DB的问题,有两点:1. 要随时盯着安装进度,2单线程 ...
  • Network Connectivity 1. Important terminologies 1) Link 设备连接的连线.Link本身既可以是有线的,也可以是无线的. 2) Node 设备.电脑,笔记本电脑,手机都可以是Node. 3) Point-to-point 连接的设备只有两个. 4) ...
  • 文/王利阳前几日乐视TV超级电视S40降价引发了与联想的口水战,双方你来我往吵了几个回合.对乐视的价格调整,联想中国区智能电视事业部总经理任中伟认为,这是一种自杀行为,这种做法几乎完全不考虑产品的硬件成本.而乐视TV彭钢看法是,传统厂商只看到超级电视硬件价格低,而枉顾创造用户价值最大化的商业模式与高 ...
  • 图中为网秦CEO林宇易网科技讯 美国时间5月5日消息,国内移动互联网安全企业网秦今日在纽约交易所上市交易.开市钟敲响之前,网秦高管齐聚纽交所一楼交易大厅,讨论即将到来的开盘价格."应该在20美元左右."多名高管相互讨论.而开盘11.5美元的价格,开盘两分钟后随即破发,这让身在交易 ...
一周排行
  • 你或许问过工程师朋友,「我该从哪种语言下手?」,但每个人给的答案都不ㄧ样.他们的解释都是听不懂的外星语(什么是物件导向?!). 为了帮助你挑选适合你入门的语言,这里有一张很简单的资讯图表,只要照着路径回答问题,依照你 ...
  • 获得磁盘上最常用文件夹的路径 我们知道,苹果上的应用程序都是运行在自己的沙盒中的,很少也没有足够的权限跟沙盒外面的文件资源打交道,一般一个应用的文件目录如下: 想要获得应用目录下的文件夹路径最常用的操作: NSFil ...
  • 方法一: 个人认为最好的方法.采用的是正则表达式,这是最核心的原理. 其次.这个方法使用了JavaScript 的prototype 属性 其实你不使用这个属性一样可以用函数实现.但这样做后用起来比较方便. 下面就来 ...
  • 单臂路由 一.vlan间路由的必要性 1. 多层交换设计,可以把网络划分更小的第二层域 2. 减小了广播域,提高网络性能和效率 3. 三层路由能够更好的负载均衡,并扩展性好 4. 管理维护"排障域" ...
  •  一.Oracle Lifetime Support 分类 网站的说明http://www.oracle.com/us/support/lifetime-support/index.html 在如下这篇文章里有更详细 ...
  • // test_min_max.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namesp ...
  •   配置文件一般配置 <?xml version="1.0"?> <configuration> <configSections> <section na ...
  • 本文节选自<See MIPS run2rd>/<MIPS体系结构透视>中的部分章节,结合个人理解,对部分译文有所改动. 1.5.2 Addressing and Memory Accesses ...
  • 数据库安全现状 数据库是计算机应用系统中的一种专门管理数据库资源的系统.数据具有多种形式,如文字/数码/符号/图形/图象以及声音.数据库系统立足于数据本身的管理,将所有的数据保存于数据库中,进行科学地组织,借助于数据 ...
  • 所有机器硬件信息: dmesg |more CPU信息: cat /proc/cpuinfo 查看有几核 MEM内存: cat /proc/meminfo free -m top 磁盘信息: df -Th 查看磁盘上 ...