2016-04-30

Diary

好可爱的猫~

USTC001 LINUX操作系统分析 部分期末考试题

想了我好久,却不知道我哪里写错了。后来发现我的是对的。要以16进制的格式写,而我却用10进制的格式。

1# 在Linux系统的一般执行过程中,即用户态进程X切换到用户态进程Y的过程中,分析如下进程切换的关键汇编代码,请问系统执行到标号1(即第50行代码)之前的时间点CPU的寄存器eip的值是?直接填eip存储的数值(立即数以$开头)
答案就是$1f 2# 从运行时的角度(执行视图)来看Linux系统,下列哪些属于Linux系统中的执行实体?

一直以来, linux内核并没有线程的概念. 每一个执行实体都是一个task_struct结构, 通常称之为进程. 进程是一个执行单元, 维护着执行相关的动态资源. 同时, 它又引用着程序所需的静态资源(注意这里说的是linux中的进程).通过系统调用clone创建子进程时, 可以有选择性地让子进程共享父进程所引用的资源. 这样的子进程通常称为轻量级进程.

——

《linux线程浅析》

3# Linux系统中,用户态切换到内核态时,int指令或中断信号会触发CPU自动保存下面哪些信息到内核堆栈中?
#2.Linux系统的一般执行过程

Linux系统的一般执行过程大概可以抽象成:

最一般的情况:正在运行的用户态进程X切换到运行用户态进程Y的过程

  1. 正在运行的用户态进程X
  2. 发生中断——save cs:eip/esp/eflags(current) ,


    load cs:eip(entry of a specific ISR)


    ss:esp(point to kernel stack). 这一过程由CPU自动完成
  3. SAVE_ALL //保存现场
  4. 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
  5. 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
  6. <a href="http://codelab.shiyanlou.com/s?refs=restore_all&amp;project=linux-3.18.6" rel="nofollow" target="_blank">
    restore_all
    </a>
    //恢复现场
  7. iret - pop cs:eip/ss:esp/eflags from kernel stack
  8. 继续运行用户态进程Y



理解进程调度时机跟踪分析进程调度与进程切换的过程



4# Linux内核中,系统调用处理过程中保护现场使用的宏是 SAVE_ALL 5# 动态连接有两种形式:可执行程序装载时动态连接和运行时动态链接。

——《

linux可执行文件的装载


2016-04-28

Diary

这是春节前大扫除,整理橱柜拍的。值得留恋= =!

真的是被自己当初的品味惊呆了。。。

其中第一件裤子和第三件包包悄悄的丢了,因为怕被嘲笑。

第二件给了谁忘了,因为我估计他们看不出问题来。哈哈o()o

快盘关闭服务了

我的快盘啊~61G的文件搬家好累啊。我再也不相信网盘了。我决定把我所有的网盘数据搬到本地上。


庆幸今天看到,还来得及转移数据。说来快盘我也用了将近4年了,从大学开始。不过快盘的倒下我也能理解,并不意外。现在免费快盘存活下来的大概只有百度网盘了吧。

百度网盘你还能坚持多久?不管你能坚持多久,我也不相信你,不会用你,顶多就把一些软件安装程序放在百度云上。

叹口气这次我真的再也不会使用网盘了。还是自己保存自己的数据最安全。

============================================

2016/4/29更新:

今天收到邮件,新浪微盘也关闭了。虽然我不用新浪微盘,但是我很多PDF是在上面找到的。嗨~


==========================================

2016/5/7更新:

原理一下子关了好多家



2016-04-22

和导师见面

4.17 和导师第一次见面。虽然导师和我已经认识,但是这是第一次以我的导师身份见面。

我们谈了些将来的方向。我想弄明白2件事,硕士毕业后我要成为什么样的人?硕士期间我要做什么?但是直到现在我还是没有一个明确的答案。

本科期间上导师的课感觉他人很好。所以我决定跟他。他只有我一个研究生。也许看我那么热情的约他,觉得我很认真,所以他也很认真的对我。告诉我未来的几个方向。交谈的气氛很轻松很愉快,甚至老师也开自己的玩笑说自己办公桌上的书很多也是摆放。

能够很明显的感觉到老师对我也是尽他所能希望能够帮助我。他主动帮我联系了他的两个学生,询问他们所在的研究院是否有实习机会。并告诉我如果可以尽量去研究院实习。

快要结束时,我送了他两包普洱茶。很平民的包装,并不是送礼,而是由衷的感谢。

虽然第一志愿没有考上,很失望。但是现在我又重新充满希望。我希望能够在导师的指导下大干一番。

2016-04-21

如何免费下载IEEE论文

最近在做毕设,查了很多论文。除了知网上学校免费提供,IEEE是我最想看的。于是google找了找how to download ieee papers for free

#1.首先找到你所需要的论文地址
#2.去 https://sci-hub.io 或者 http://www.sci-hub.cc/ #3.把论文地址复制进搜索栏中,点击打开
看样子又是战斗民族搞的盗版了。

分析个 知乎 恶喵的奶爸 回答

其实中国对世界互联网盗版资源的贡献非常小,真正贡献大的,是俄罗斯人。



2016-04-20

用Github搭建留言板

没个留言板怎么行?Lofter只能注册用户才能留言,这简直和他们的理想相违背了。


请问一定要注册LOFTER才能留言,怎么发现有共同爱好的人?明明就是设置障碍。

所以我就必须自己弄个留言板。说干就干,今晚不看书就专门弄这个。

就搭载最近流行的GITHUB上面。其实在https://pages.github.com/上就有简单的教程。


#先创建个repo.

注意:我自己测试过,repo的名字要与owner名字相同。[username].github.io

我选择简单的github for windows。


#下载软件
#克隆repo
#自己网上找了个HTML5的模板,做了修改,添加上多说。页面很简单。

上传它…


#ok!访问地址:very9s.github.io

欢迎大家留言啊~ 考虑了下是否要绑定域名?看看时间,2016年4月21日00:30:07,算了,以后再说吧。
看,我在装B~o(^▽^)o

退掉MOOC通信原理

实在是没时间了,临近毕设deadline,实在是没时间跟进通信了。虽然我很想学,但也只好暂时放弃,以后再看吧。


虽然有点不舍,认认真真的做完前三周的作业。

2016-04-18

如何理解卷积


这两个公式学过信号与系统的一定知道,这就是卷积。

一开始我也不懂,看着上面2个复杂的公式,一脸懵然。于是我也再往上查了很多资料,试图理解到底什么是卷积。网上的资料也很多,中文的英文的我都有看过。慢慢的我懂了。

其实卷积很简单,就是

求和

#编个MATLAB理解:

  1. clear;

  2. b=[1];

  3. a=[1 -1 0.5];

  4. signal=[1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];%信号

  5. y=impz(b,a,20);  %系统的冲激响应

  6. signal_conv_y=conv(signal,y);%冲激响应与信号卷积

  7. for i=1:20 %提取冲激响应与信号卷积的前20个值,用于对比

  8. signal_conv_y_20(i)=signal_conv_y(i);

  9. end

  10. x=length(y);

  11. for i=2:x        %将冲激响应右移1个单位

  12. y_1(i)=y(i-1);

  13. end

  14. for i=3:x        %将冲激响应右移2个单位

  15. y_2(i)=y(i-2);

  16. end

  17. for i=1:x        %将3个响应叠加起来

  18. y_r(i)=y(i)+y_1(i)+y_2(i);

  19. end

  20. subplot(3,2,1);    %绘图

  21. stem(y);title(‘y’);

  22. subplot(3,2,3);

  23. stem(y_1);title(‘y_1’);

  24. subplot(3,2,5);

  25. stem(y_2);title(‘y_2’);

  26. subplot(3,2,2)

  27. stem(y_r);title(‘y_r=y+y_1+y_2’);

  28. subplot(3,2,4)

  29. stem(signal_conv_y_20);title(‘signal * impz’);

  30. subplot(3,2,6)

  31. stem(signal);title(‘signal’);


将第一列的三个响应信号叠加起来就等于信号与冲激响应的卷积。

所以再回过头来看,卷积其实就是求和,而且这个求和很简单。只是这个求和表达式有点复杂而已。所以用*来代替简化表达式。

当然使用卷积是有前提的,那就是:

只有线性时不变系统才能导出卷积公式。

因为冲激响应要乘以某一时刻的信号强度,所以在求和前还有乘积,这就使式子变得复杂。在上面的MATLAB实验中,所有的信号强度都是1,所以好像只是3个冲激响应的求和,其实三个冲激响应是有乘以强度1的。

更进一步,稍作修改,改变下信号的形状,重新实验:


注意到y_6的值是冲激响应的3倍。

这是离散的情况,连续的情况则把求和变为积分。


Linux内核学习总结

文章目录:
  1. 实验:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
  2. 实验:完成一个简单的时间片轮转多道程序内核代码
  3. 实验:跟踪分析Linux内核的启动过程
  4. 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
  5. 从system_call开始到iret
  6. 分析Linux内核创建一个新进程的过程
  7. linux可执行文件的装载
  8. 理解进程调度时机跟踪分析进程调度与进程切换的过程
1#我对linux系统的理解

linux很难,这8周的学习我对绝对还是不理解Linux的。只能说比学之前更理解它了。很多细节深入到底层硬件方面的问题,所以还需要有计算机组成原理的知识,尤其是在堆栈方面的讨论。

linux的哲学

Linux is built with a certain set of unifying principles in mind. Understanding these principles is very helpful in understanding how the system works as a whole. They are known as the “Linux Way”, which is derived from the philosophy behind the UNIX system.

The Linux Way can be summarized as:

  • Use programs that do only one task, but do it well.
    <br/>
  • To accomplish complex tasks, use several programs linked together.
  • Store information in human-readable plain text files whenever it is possible.
  • There is no "one true way" to do anything.
  • Prefer commandline tools over graphical tools.

Most traits of Linux are a consequence of these principles. In accordance with them, a Linux system is built out of small, replaceable components. We will examine the most important of them in more detail. Those are: the boot loader, the kernel, the shell, the X window server, the window manager and the desktop environment. After that, we will have a look at the file system in Linux. Finally, we will discuss the security of a computer running Linux.

——

Linux Guide/How Linux Works

简单总结就是KISS(keep it simple and stupid)原则

  • 用程序来完成一项任务,然后把任务做好。

  • 复杂的任务用多个程序来完成。

  • 把信息存在更人性化的文本中。

  • 没有唯一的方法。

  • 命令行能做的事就不用图形工具来完成。

这些原则使linux保持简单且高效。



用户通过交互程序与内核打交道,而内核则与硬件直接打交道。这样就把用户、内核、硬件分离开。因此内核就是理解linux的关键。

在内核与用户之间并不是直接关联的,而是通过系统调用来把用户和内核隔离开。这样既安全又方便程序员进行编程,而不是深入到内核中去操作。

内核中又分为多个模块,各各模块管理者不同的任务



通过这些模块与硬件进行打交道
整体框架大概就是这样。我并不是程序员,从我学习的目的来说我并不需要深入到每个模块是如何实现的一些具体细节。就像程序员编程不需要知道每个轮子是怎么制造的一样。 Kernel (operating system)
2#反思实验都做了些什么?

八周下来,周周有实验。再把每周标题串起来,构建一条思路。


###先整体:1~3周

1.计算机只能读懂机器代码,因此我们编程后还要将代码转换成机器代码

2.计算机要高效,就必须多个进程进行轮转。因此就产生了切换时机问题,上下文保存切换问题。

###再系统:4~5周

所谓三层皮目的就是将用户与内核分隔开。用户程序调用API,API调用系统调用,系统调用调用内核

###最后细节:6~8周

三层皮之间的相互调用必然涉及到不用的程序执行,也就是进程切换。进程又可分为用户空间和内核空间进程。进程进行切换,又设计到上下文的保存于切换,于是又回到底层的堆栈操作上。实际上我认为,在这里程序员就不再需要讨论堆栈操作了,将堆栈操作留给系统去做就可以了。否则就会陷入到无限的细节中。这也就是为什么对内核进行层层封装了。



#3.总结课程

这门课让我对linux有了一个感性的认识,这些认识对我日后学习嵌入式必然有帮助。我学习这门课的目的也大体达到。剩下的一些问题,或者说缺乏的理性认识,则可以在实践中慢慢摸索。

《Linux内核分析》课程后最大的遗憾?好吧,那就是缺乏对细节的把握。这单单看视频是不够的。

==================================================

sunfy + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000



2016-04-17

GOOGLE搭建免费静态网页

无意间看到一篇谷歌的帮助文档

Host web pages with Google Drive

觉得挺有意思的,于是自己做了实验。用谷歌drive搭建一个静态网页。这个就跟用github和dropages搭建静态空间一样。挺有意思的。而且貌似搭建完,并没有被墙。


#第一步:上传整个整个静态页面文档。
上传过程简单,就不再演示。 #第二步:分享 #第三步:点击高级

记录链接中的id。

#第四步:点击更改

选择开启,然后保存。

#结束:访问

访问地址是:www.googledrive.com/host/[doc id]

其中把[doc id]换成刚刚记录的ID就可以了。


我下了个模板,做了简单的修改,添加上多说。当成简单的留言板。 我的留言板 我在非科学上网的情况下还是可以打开的。不知道你们可以打开不。

还是挺不错的。总感觉墙外的东西比墙内的好。嗨~

Diary

少上点网,多看书。

最近很迷看别人的博客,看到了很多不错的博客,然后羡慕他们。

时间都浪费了,还有很多事要去做。关掉电脑~

2016-04-16

如何理解逻辑努力(Logical effort)

本科的时候对逻辑努力就十分模糊,始终缺少一种感性的认识。这次在学堂在线上跟的课程《40260173X 数字集成电路分析与设计(2016春)》让我对逻辑努力有一个新的认识。记录下来以免忘记,同时也是分享。


=====================================================

#1.从延迟开始:

很简单,世界上没有立即反应的东西。响应总是会产生延迟。因而就必须讨论电路的延迟。


#2.如何考虑延迟:

“使一个孤立的门的传播延时最小是一个纯粹脱离实际的努力”——《Digital Integrated Circuits A Design Perspective 2nd》

孤立的门的传播延时就是本征延时。

也就是说虽然增大反相器的尺寸可以减小它的延迟(可以理解为电阻减小了,电流变大了因而速度变快了),但同时也增大了它的输入电容。因而在实际环境中还需考虑前级、后级的影响。

##a) 引入反相器的延迟公式:
  • tp0是本征延迟,与门的尺寸无关,只与工艺及版图有关。所谓本征延迟就是只没有负载的情况下。就是前面说的不切实际的讨论。

  • γ是比例系数,同样只与工艺有关。用来描述本征输出电容与输入栅电容Cg的关系,即Cint=γCg

  • f称为等效扇出。从式子中可知反相器的延时只与外部负载电容与输入电容的比值有关,这个比值就是f

因此延时公式大概可以这样理解:反相器的延时就等于本征延时加上 由前后级额外影响所产生的额外延时。

额外延时也可以理解为:电路要做出响应所需要做的额外努力,而要额外努力就必然会产生额外延时。

##b) 为什么引入反相器的延时公式:

这个问题本质上也是在回答引入反相器延时公式的目的是什么:作为“参考系”计算组合逻辑的延时。

##c) 组合逻辑延时公式:
  • p: called intrinsic delay factor, which represents the ratio of the intrinsic (or unloaded) delays of the minimum-sized complex gate over the minimum-sized inverter, and is a function of gate topology, as well as layout style.
  • g: called logical effort, which represents the ratio of the input Cap. (driven by the same input signal) of a minimum-sized complex gate over the minimum-sized inverter. Logic effort depends only on circuit topology.
  • f : called effective fan-out or electrical effort, defined as the ratio between the external load and the input Cap. of the complex gate

组合逻辑的延时就等于本征延时加上 由前后级额外影响所产生的额外延时。也就是本征延时加上努力延时

####如何计算本征延时?

以前面计算的反相器为参考,组合逻辑的本征延时是参考反相器的本征延时的p倍


####如何计算额外的延时?

以反相器的额外努力为参考,g就是组合逻辑相对于反相器额外努力的倍数。称之为逻辑努力。逻辑努力越接近于1,说明所要做的额外努力越少(或者说越接近于反相器),从而所产生的额外努力延时更短,也就是说该逻辑门更快。

而整个努力延时等于逻辑努力与等效扇出的乘积。这说明等效删除越大(或者说负载越大)所产生的延时显然也会随之增大。

f可以理解为需要多少份的额外努力,

g可以理解为每份额外努力有多少。


#3.终极结论:

当扇出为0(也就是无负载时)时,反相器的延迟就是本征延迟。现实中只考虑本征延时是没有意义的。

当有扇出时(也就是有负载时)延迟就等于本征延迟再加上努力延迟。

同时线的斜率也等于逻辑努力

不同的逻辑电路有不同的逻辑努力,它只与电路的拓扑结构有关。

从表格也可以推知:NAND比NOR速度更快。因为NAND所需要的努力时间更少。

延时=本征延时+努力延时

努力延时=逻辑努力*等效扇出


===================================

附上一张和老师的讨论。



2016-04-14

Diary

40260173X 数字集成电路分析与设计(2016春)

这门课只有我一个人在讨论。估计只有我一个人申请了证书。

2016-04-12

为什么Python中的string不可变

Why are Python strings immutable?

There are several advantages.

  • One is performance: knowing that a string is immutable means we can allocate space for it at creation time, and the storage requirements are fixed and unchanging. This is also one of the reasons for the distinction between tuples and lists.

  • Another advantage is that strings in Python are considered as “elemental” as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string “eight” to anything else.

大白话就是:

  1. 固定的内存空间更有效率

  2. 就像没有人会改变数值8的写法一样,字符串“eight”也不需要改变。


2016-04-11

理解进程调度时机跟踪分析进程调度与进程切换的过程

理解Linux系统中进程调度的时机

Linux的调度程序是一个叫Schedule()的函数,这个函数被调用的频率很高,由它来决定是否要进行进程的切换,如果要切换的话,切换到哪个进程等等。

Linux调度时机主要有:

  1. 中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule():
  2. 内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;

  3. 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。

不同类型的进程有不同的调度需求

第一种分类:

  1. I/O-bound:频繁的进行I/O通常会花费很多时间等待I/O操作的完成
  2. CPU-bound:计算密集型需要大量的CPU时间进行运算

第二种分类:

  1. 批处理进程(batch process):不必与用户交互,通常在后台运行不必很快响应典型的批处理程序:编译程序、科学计算

  2. 实时进程(real-time process):有实时需求,不应被低优先级的进程阻塞响应时间要短、要稳定典型的实时进程:视频/音频、机械控制等

  3. 交互式进程(interactive process):需要经常与用户交互,因此要花很多时间等待用户输入操作响应时间要快,平均延迟要低于50~150ms典型的交互式程序:shell、文本编辑程序、图形应用程序等Linux 进程调度+Linux系统一般执行过程 笔记

进程上下文包含了进程执行需要的所有信息:

用户地址空间:包括程序代码,数据,用户堆栈等

控制信息:进程描述符,内核堆栈等

硬件上下文(注意中断也要保存硬件上下文只是保存的方法不同)

2.schedule()函数

schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
关键函数
__schedule();




next = pick_next_task(rq, prev);包装了使用某种进程调度策略,但不管使用什么调度策略,它总是选择下一个进程

选完下一个进程后,就要完成进程上下文的切换。
进程上下文的切换主要是通过context_switch(rq, prev, next)实现。

## context_switch(rq, prev, next) 是如何实现上下文切换的?

1-prepare_task_switch(rq,prev,next);//提前做准备

2-context_tracking_task_switch(prev,next);//切换寄存器的状态和堆栈

3-switch_to(prev,next,prev);

switch_to(prev, next, prev);的汇编

switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程

42  asm volatile(“pushfl\n\t”      /* save    flags */

43           “pushl %%ebp\n\t”        /* save    EBP   */ \

44           "movl %%esp,%[prev_sp]\n\t"  /* save    ESP   */ \这两步实际上完成了内核 45           "movl %[next_sp],%%esp\n\t"  /* restore ESP   */ \堆栈的切换

46           “movl $1f,%[prev_ip]\n\t”    /* save    EIP   */ \

47           “pushl %[next_ip]\n\t”   /* restore EIP   */    \将NEXT进程的起点压入堆栈

48           __switch_canary                   \

49           “jmp __switch_to\n”  /* regparm call  */ \

50           “1:\t”                        \

51           “popl %%ebp\n\t”     /* restore EBP   */    \

52           “popfl\n”         /* restore flags */  \

53                                  \

54           /* output parameters */                \

55           : [prev_sp] “=m” (prev->thread.sp),     \

56             [prev_ip] “=m” (prev->thread.ip),        \

57             “=a” (last),                 \

58                                  \

59             /* clobbered output registers: */     \

60             “=b” (ebx), “=c” (ecx), “=d” (edx),      \

61             “=S” (esi), “=D” (edi)             \

62                                       \

63             __switch_canary_oparam                \

64                                  \

65             /* input parameters: */                \

66           : [next_sp]  “m” (next->thread.sp),        \

67             [next_ip]  “m” (next->thread.ip),       \

68                                       \

69             /* regparm parameters for __switch_to(): */  \

70             [prev]     “a” (prev),              \

71             [next]     “d” (next)               \

72                                  \

73             __switch_canary_iparam                \

74                                  \

75           : /* reloaded segment registers */           \

76          “memory”);                  \

Linux系统的一般执行过程

Linux系统的一般执行过程大概可以抽象成:

最一般的情况:正在运行的用户态进程X切换到运行用户态进程Y的过程

  1. 正在运行的用户态进程X

  2. 发生中断——save cs:eip/esp/eflags(current) ,

    load cs:eip(entry of a specific ISR)

    ss:esp(point to kernel stack). 这一过程由CPU自动完成

  3. SAVE_ALL //保存现场

  4. 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换

  5. 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)

  6. restore_all //恢复现场
  7. iret - pop cs:eip/ss:esp/eflags from kernel stack

  8. 继续运行用户态进程Y

几种特殊情况

  • 通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换;

  • 内核线程主动调用schedule(),只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略;

  • 创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork;

  • 加载一个新的可执行程序后返回到用户态的情况,如execve;

Linux系统架构和执行过程概览

  • 内核(进程管理,进程调度,进程间通讯机制,内存管理,中断异常处理,文件系统,I/O系统,网络部分)
  • 其他程序(例如函数库、shell程序、系统程序等等)



从用户的角度来看:
从CPU的角度来看: #4.gdb跟踪分析一个schedule()函数
qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img -s -S

打开GDB

gdb

file …/linux-3.18.6/vmlinux

target remote:1234

设置断点:

b schedule

b context_switch

b switch_to

b pick_next_task



==================================================

似乎明白了一点点。

sunfy + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000



Ubuntu SSR setting

使用electron-ssr客户端 https://github.com/shadowsocksrr/electron-ssr 设置proxy