开始核心级线程

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

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

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

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

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

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

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

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

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

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

开始内核中的切换:switch_to

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

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

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

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

??: interrupt 之前的某个地方

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

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

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

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

内核线程switch_to 的五段论

ThreadCreate! 做成那个样子…

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

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

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

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

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

void sched_init(void)

{set_system_gate(0x80,&system_call);}

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

_system_call:

push %ds..%fs

pushl %edx...

call sys_fork

pushl %eax

内核栈:

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

切换五段论中的switch_to

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

另一个故事ThreadCreate 就顺了…

从sys_fork 开始CreateThread

_sys_fork:

push %gs; pushl %esi

...

pushl %eax

call _copy_process

addl $20,%esp

ret

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;// 创建用户栈(和父进程共用栈)

申请内存空间;

创建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)

...

填写两个stack;

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

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

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

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

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

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

mov %eax, __NR_fork

INT 0x80

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

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

结构: 子进程进入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

终于可以让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)

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

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

[No00003A]操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads的更多相关文章

  1. [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

    操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...

  2. [No00003C]操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore

    操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore 进程合作:多进程共同完成一个任务 从纸上到实际:生产者− − ...

  3. [No000039]操作系统Operating Systems用户级线程User Threads

    多进程是操作系统的基本图像 是否可以资源不动而切换指令序列? 进程 = 资源 + 指令执行序列 线程: 保留了并发的优点,避免了进程切换代价 实质就是映射表不变而PC 指针变 多个执行序列+ 一个地址 ...

  4. [No000036]操作系统Operating Systems系统调用的实现System_Call

    实现一个whoami 系统调用 系统调用的直观实现 问题+直观想法… 用户程序调用whoami, 一个字符串"systemcall "放在操作系统中(系统引导时载入) ,取出来打印 ...

  5. [No000038]操作系统Operating Systems -CPU

    管理CPU ,先要使用CPU… CPU 的工作原理 CPU上电以后发生了什么? 自动的取指 — 执行 CPU 怎么工作? CPU怎么管理? 管理CPU 的最直观方法 设好PC 初值就完事! 看看这样做 ...

  6. [No000037]操作系统Operating Systems操作系统历史与硬件概况History of OS & Summaries!

    培根:读史使人明智 操作系统的简史 (1955-1965) 计算机非常昂贵,上古神机IBM7094 ,造价在250万美元以上 计算机使用原则:只专注于计算 批处理操作系统(Batch system) ...

  7. [No000031]操作系统 Operating Systems 之Open the OS!

    从打开电源开始… 这神秘的黑色背后发生着什么?… 打开电源,计算机执行的第一句指令什么? 计算模型(图灵机) ⇒ 我们要 关注 指针IP 及其 指向的内容 看看x86 PC (1) 刚开机时CPU 处 ...

  8. 【内核】linux2.6版本内核编译配置选项(二)

    目录 Linux2.6版本内核编译配置选项(一):http://infohacker.blog.51cto.com/6751239/1203633 Linux2.6版本内核编译配置选项(二):http ...

  9. 【操作系统】二、JVM线程与Linux内核线程的映射

    Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...

随机推荐

  1. 在Autodesk Vault 2014中使用VDF(Vault Development Framework) API获取所有文件的属性信息

      这几天在玩儿Vault API, 从Autodesk Vault 2014开始提供了Vault Development Framework(VDF) API,让开发工作更简单了.在Vault 20 ...

  2. 【Leafletjs】2.添加marker到地图

    本人建了一个Leaflet交流群:Leaflet&WebGIS  331437754 接着上篇我们在地图中添加一个marker,非常简单只需添加如下代码即可: var marker = L.m ...

  3. Projects\Portal_Content\Indexer\CiFiles文件夹下文件占用磁盘空间过大问题。

    C:\Program Files\Microsoft Office Servers\12.0\Data\Office Server\Applications\9765757d-15ee-432c-94 ...

  4. APP One Link ,android and ios qrcode merge as One QRCode and one short link

    Adroid and ios qrcode merge as One QRCode and one short link is publish , the web site is www.appone ...

  5. Android C代码回调java方法

    本文将讲述下列三种C代码回调java方法 1.c代码回调java空方法 2.c代码回调java int类型参数方法 3.c代码回调javaString类型参数方法 方法都差不多,先看c代码回调java ...

  6. JS怎么动态命名变量名

    [摘要]本文是对JS怎么动态命名变量名的讲解,对学习JavaScript编程技术有所帮助,与大家分享. 1.用eval,例子: 1 2 3 4 5 6 7 <script> var Thr ...

  7. WordCount的程序设计没写出来怎么办

    这一星期要完成三个小作业,完成前两个已经让我很吃力的了,现在这个WordCount的编程我都没有头绪,不知道从何下手.虽然要求很看起来很简单,可是不知道怎么去设计这个程序,这两天我也在积极找书学习相关 ...

  8. [CMD]oracle数据库的导出导入

    除了推荐使用PL/SQL Developer 工具对oracle进行导出导入(http://www.cnblogs.com/whylaughing/p/5983490.html )之外,比较常用的还有 ...

  9. Git中文版教程

    1. 起步 1.1 关于版本控制 1.2 Git 简史 1.3 Git 基础 1.4 命令行 1.5 安装 Git 1.6 初次运行 Git 前的配置 1.7 获取帮助 1.8 总结 2. Git 基 ...

  10. Mongodb Manual阅读笔记:CH9 Sharding

    9.分片(Sharding) Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb ...