- 浏览: 365088 次
- 性别:
- 来自: 深圳
最新评论
-
abc08010051:
结果呢?烂尾跑路了?
关于actor模型的优缺点分析(1) -
qinhanlei:
hi, 感谢分享,受益匪浅! 顺便请问一下,您使用的是什么绘图 ...
skynet任务调度分析 -
maxer025:
楼主,github 地址?
WebIM第一版本及下一步工作 -
boyhailong:
博主的分析能力真是强 skynet的很多东西我表示还是看不太懂 ...
skynet任务调度分析 -
ranweizheng:
亲这篇里面没有说当(.class 元素 元素) 与( .cla ...
css样式表中的样式覆盖顺序
文章列表
哈哈,如果返回http消息头中指定了“Content-Type: application/json”的话,jQuery回调函数中传入的data是直接解析后的json对象,如果不指定Content-Type(就是用默认的),jQuery回调函数中传入的data是string字符串。
不看文档没常识。仔 ...
刚才写zenktodo的时候,通过动态添加class的方式修改一个div的样式,总是不起作用。
#navigator {
height: 100%;
width: 200;
position: absolute;
left: 0;
border: solid 2 #EEE;
}
.current_block {
border: solid 2 #AE0;
}
查找一 ...
惭愧,刚浏览了xiaotie的一些博客,作为和他同一年入学的校友,同样都是在一个非IT专业读到了硕士,2003年同一年毕业,到现在已经工作10年了。相比较而言,现在收入可能多一点,但生活远远没有他充实,同时也没有他的竞争 ...
node.js的包管理软件npm非常好用,命令简洁明了,在家里部署express时非常方便。但在公司安装时遇到了麻烦。npm install默认在指定的目录或文件中找不到要安装的包时,就会去https://registry.npmjs.org/查找并下载相应的包。npm config可以配置proxy和https-proxy,不过如果proxy需要用户名密码,npm就搞不出来了。在linux下配好proxy,用curl也能获取到包(不过需要用curl -k,否则还是说要验证,不知怎么搞定),但是用npm install时就是下载不下来。
所以只能先手工将express以及它的依赖包(co ...
学习rabbitmq,在看其java client api文档时,讲到AMQP类的请求、应答描述符都有builder类,符合Builder模式,让创建协议对象更加简单,允许使用不变的状态创建他们。
一直没有系统学习设计模式,从网上查了一下Builder模式的讲解 ...
时隔近20天,终于搞定了一个问题。使用linker script设置内核起始地址为0xC0000000后,在没有启用分页的情况下,终于让加载到0x100000的内核成功运行起来了。内核代码正常运行,时钟中断正常。
ucore lab2 project5中首先设置了一个临时gdt,将base地址设置为-0xC0000000,这样在后续所有地址访问中,地址都会与这个base地址相加,相当于减去了0xC0000000,应该可以正常运行。
开始时qemu虚拟机直接宕掉,原因是把DS、ES、FS、GS、CS的内容都改了,忘了改SS,而ESP的值设置了一个0xC0xxxxxx的值,从而执行出 ...
要对内核进行页映射,首先要知道内核在内存中的位置和内核的大小。内核在内存中的位置很好知道,因为是启动代码拷贝进去的,而内核的大小就不好知道了,只有最后将各个obj文件组合成内核文件的ld命令才知道。而ld命令的 ...
paging由x86 cpu控制寄存器中的三个bit控制:
CR0 bit31:PG位,控制是否启用paging
CR4 bit4:PSE位,页大小扩展,允许4M大小的页面
CR4 bit5:PAE位,物理地址扩展
先看32位的paging处理,就是PSE=PAE=0,而PG=1时的情况。
一个线性地址被分为3部分,第一部分是页目录表项索引,高10位(bit31-bit22),第二部分是页表表项索引,中间10位(bit21-bit12),最后部分是页内偏移地址,低12位(bit11-bit0)。由此,一个页目录表最多有2^10 = 1024项,一个页表最多有2^10=102 ...
看内核刚进入时加载临时gdt的代码:
lgdt __gdtdesc - KERNBASE
.data
gdt:
...
__gdtdesc:
.word 0x17
.long gdt-KERNBASE
其中KERNBASE = 0xC0000000。在lgdt指令中,使用了__gdtdesc的真实物理地址,而在__gdtdesc中,使用了gdt的真实物理地址。其中lgdt指令中的__gdtdesc真实地址,应该是要经过段式处理的,而__gdtdesc中的gdt地址呢?是否也需要经过段式处理才能访问呢?
查看intel的文档,GDTR/IDTR中的 ...
project5到project9主要处理内存管理。
其中project5是一个大工程,内部分为5个小工程,本次主要针对第一个小工程进行分析。
在project3.1中,就已经使用了ld的linker script,直接在其中指定链接时的一些配置。比如起始代码的符号,起始地址值,某个段的align值,以及可以定义一些变量。
在project5中,起始地址改为汇编函数kern_entry,其中重新设置gdt,然后调入c代码kern_init。同时设置内核地址为0xC0100000,为内存管理做准备,同时也是起始地址改为汇编kern_entry的原因:因为内核代码开始时仍然是 ...
这是内核态和用户态切换的最后一篇,也是project4的最后一篇了。
完成了使用call gate进行用户态到内核态的切换,使用lret进行内核态到用户态的切换的实验。这是project4.1.2的内容。
内核态到用户态的切换比较麻烦一些,首先将用户态段selector给ds,es,fs,gs赋值,将用户态栈的selector压栈,然后ebp压栈。因为c编译器会再函数开头将ebp压栈,然后将esp赋值给ebp,因此压栈的实际上就是压用户态栈selector前的esp的值。然后将用户态代码段selector压栈,然后将lret下一条指令位置压栈,然后执行lret,完成。代码如下:
...
用户态到内核态切换相对比较简单。用户态切换到内核态时,需要切换堆栈,堆栈地址在当前task的tss段中,因此需要先建立好一个task,并为内核态的ss和esp赋好值。
仍然使用中断切换到内核态,中断处理函数中,首先将保存在新堆栈中的老堆栈的esp取出来,然后在老堆栈的esp指针指向位置之上建立一个trapframe(不包括ss和esp值),然后将新堆栈中的这一堆内容拷贝过来,然后给tf赋值为新堆栈的trapframe的地址,之后直接返回到trap_asm就ok了。
在使用过程中,发现切换不了。使用gdb跟踪发现,不断发生通用保护异常13,才发现idt中为用户态切换到内核态而建的中 ...
终于又回来了。内核态和用户态切换比较麻烦,今天解决了一个bug,搞定了从内核态切换到用户态。
x86中,从高优先级代码切换到低优先级代码的唯一方法就是使用ret或iret返回指令,而从低优先级切换到高优先级的方法是int ...
离上次更新ucore工程已经过去6天了。这几天工作比较忙,经常加班,回家一般23点多了。另外x86 cpu知识忘得差不多了,优先级切换、段式、页式内存访问和保护等记不起来,project4也没法继续做下去。周末终于有时间把x86文档啃了一下(25366821-pentium4-V3A-System-Programming-Guide.pdf),终于又捡起来些。
这是以前学习x86时记的一些东东,重新翻出来,发现还比较有用。更新了一些内容,记在这里,以备查阅:
段式保护规则:1·当一个segment selector载入段寄存器时,才会触发段式保护。
2·CPL:进程的当前 ...
修改了代码中的一个bug,时钟终端终于正常了。
project4是一个很大的工程,包括了6个小工程。今天完成的是第一个工程:添加中断,初始化pic(8259A)和pit(8253)。
第二个工程project4.1主要添加了用户态段和一个TSS段,重新初始化gdt,并加载了一个TSS
第三个工程project4.1.1实现用户态和内核态的切换,主要通过修改int中断,在中断处理函数中修改trapframe的CS、DS等的值实现。同时这个工程中需要注意idt中从user到kernel那一项的dpl是3(改成0试试???)
第四个工程project4.1.2使用lret从kernel跳 ...