月度归档:2016年03月

过去一年的计划


这是我过去一年的考研计划。

生活不像鸡汤那么甜。

虽然没考上理想的学校,但是这一年我收获颇多。

现在我不再那么迷茫了。

栅漏负载共源放大器的直观分析

采用MOSFET晶体管代替无源电阻负载,芯片面积可以明显节省且与无源负载相比,有源负载可以提供更高的阻值,从而获得更大的增益。

有源负载有:

  1. 栅-漏负载( Gate-Drain-Connected Loads :可以为放大器提供大带宽、低输出阻抗,但代价是增益降低。
  2. 电流源负载( Current Source Loads :可以使放大器具有很高的增益和输出输出阻抗,但代价是带宽减小。

PS.栅漏负载可以看作阻值是1/gm的电阻。

栅漏负载共源放大器直观分析方法:

小信号增益=-漏端电阻/源端电阻

PS.

  1. 漏端电阻:连接放大管漏端的电阻阻值
    
  2. 源端电阻:从放大管源端看进去的电阻(1/gm)
    

漏端电阻=(1/gm2)并Rl(注意在小信号中,VDD是交流的地)

源端电阻=(1/gm1)+Rs

其实不一定只有采用栅漏负载的共源放大器才能使用这种直观方式。

采用电流源负载的共源放大器也可用该直观方式分析。

(共源共栅代替M2可以提高增益)

《cmos circuit design layout and simulation》21.2.1

  • 高阻节点:通常有与之相关的低频极点

  • 低阻节点:限制了放大器的速度

分析Linux内核创建一个新进程的过程

task_struct数据结构

linux进程管理分析

In user space, the process is the process identifier (PID) said. From the user’s perspective, a PID is a numeric value, can uniquely identify a process. A PID does not change during the whole life process, but PID can be re used in the process is destroyed, so they are not always ideal cache.

In user space, to create the process can be used in several ways. You can execute a program (which leads to create a new process), also can be in within the program, called a fork or Exec System Call. Fork calls will lead to create a child process, and the exec call will use the new program instead of the current process context.

在用户空间中,每个进程都有一个独一无二的PID。从用户的角度来看,PID在整个进程过程中都不能够改变,但当进程被回收后,PID则可以再次被利用。

在用户态中创建一个进程有多种方法。

  1. 你可以运行一个程序,而程序就会自动创建一个进程。

  2. 也可以在一个进程中庸系统调用创建一个进程。例如:Fork可以创建一个子进程。

精简的task_struct:

Task_struct 在/linux/include/linux/sched.h.

Task_struct

{

  • Volatile long state;
    
  • Long counter;
    
  • Long priority
    
  • Unsigned long signals;  // pending sigs
    
  • Unsigned long blocked; //masked sigs
    
  • Int pid, pgrp, uid, euid, gid, egid;
    
  • Struct linux_binfmt;
    
  • Struct task_struct p_opptr;    // ptr to original parent
    
  • Struct task_struct p_pptr;     // ptr to immediate parent
    
  • Struct task_struct p_cptr;     // ptr to most recent child
    
  • Struct task_struct p_ysptr;    // ptr to following sibling
    
  • Struct task_struct p_osptr;    // ptr to previous sibling
    
  • Struct task_struct *next_task;  // in process list
    
  • Struct task_struct *prev_task;  // in process list
    
  • Struct task_struct *next_run; // in ready queue
    
  • Struct task_struct *prev_run; //in ready queue
    
  • Struct mm_struct  mm[1];
    
  • Unsigned long kernel_stack_page;
    
  • Unsigned long saved_kernel_stack;
    
  • Struct fs_struct fs[1];
    
  • Long utime, stime, cutime, cstime, start_time;
    
  • Struct sem_queue *semsleeping;
    
  • Struct wait_queue *wait_chldexit;
    
  • Struct sigaction sigaction[32];
    
  • Struct rlimit rlim[RLIM_NLIMITS];
    
  • Struct thread_struct tss;  // includes saved registers
    
  • Unsigned long policy;  // SCHED_FIFO,SCHED_RR,SCHED_OTHER
    
  • Unsigned long rt_priority;
    
  • // for SMPs
    
  • Int processor, last processor;
    
  • Int lock_depth;
    
  • }

进程的状态:

task_struct field:

long state;

5 States (see include/linux/sched.h):

  • #define TASK_RUNNING            0
    
  • #define TASK_INTERRUPTIBLE      1
    
  • #define TASK_UNINTERRUPTIBLE    2
    
  • #define TASK_ZOMBIE             4
    
  • #define TASK_STOPPED            8
    

进程的创建:

从该图可以看出do_fork是创建进程的基本函数。do_fork在/linux/kernel/fork.c,包括copy_process().

所以我们主要来看看do_fork:

在 Linux 内核中,供用户创建进程的系统调用fork()函数的响应函数是 sys_fork()、sys_clone()、sys_vfork()。这三个函数都是通过调用内核函数 do_fork() 来实现的。根据调用时所使用的 clone_flags 参数不同,do_fork() 函数完成的工作也各异。

Clone flags = CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_PID

/

/do_fork中的主要函数调用

do_fork(clone_flags, unsigned long usp, struct pt_regs *regs)

{

  • p = copy_process();//调用该函数用来设置进程的信息,包括进程描述、其他数据等
    
    
    :
    
  • wake_up_new_task(p, clone_flags);
    

}

参数说明:

clone_flags:这和 clone( )的flags参数相同。

stack_start:这也和clone()中的child_stack参数一样。

regs:Pointer to the values of the general purpose registers saved into the Kernel Mode stack when switching from User Mode to Kernel Mode.

stack_size:我查到的资料并不太明确知道这个参数具体是做什么的。通常将它设置为0.

parent_tidptr, child_tidptr:这和clone()中的ptid and ctid参数一样。

clone主要的flags:

CLONE_PTRACE:P.S.: If CLONE_PTRACE is specified, and the calling process is being traced, then trace the child also.

CLONE_STOPPED:强制子进程从TASK_STOPPED状态开始。

CLONE_UNTRACED:Set by the kernel to override the value of the CLONE_PTRACE flag

CLONE_VM:Shares the memory descriptor and all page tables

所调用到的clone()函数是为了复制进程的描述。而该函数的主要功能是:

The copy_process( ) function sets up

  • the process descriptor

  • any other kernel data structure required for a child’s execution.

  • Its parameters are the same as do_fork( ), plus the PID of the child.

static task_t *copy_process( )

{       :

p = dup_task_struct(current);

:

retval = copy_thread(0,clone_flags,…, regs);

:

sched_fork§;

:

}

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

==================分割线==============================

好乱,我自己都看的好乱。。。

不管了,直接上实验截图了。一知半解的。

cd LinuxKernel

rm -rf menu

git clone https://github.com/mengning/menu.git

cd menu

mv test_fork.c test.c

make

结合之前查的资料,虽然实验有些失败,但是还是可以得出这样一个过程:

fork() -> sys_clone() -> do_fork() -> dup_task_struct() -> copy_process() -> copy_thread() -> ret_from_fork()

好吧不得不承认,这章我不懂。。。为了证书只能在这里瞎掰了。

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

放弃过的blog

大一大二十分着迷wordpress。想要弄出一个出色的个人blog。期间折腾了不下5个wordpress。没有一个成功的,或者说没有一个是坚持到现在的。现在想起来,大部分时间不是在发表博文,而是在折腾网站。一会这个主题,一会那个主题。折腾了一些无关紧要的东西,最后把自己弄的没耐心没信心,所以全都半途而废了。哦,对,还注册了个域名。。。

昨天不知怎么了打开了SAE平台。居然发现我里面还有个应用。我都忘记了。没错就是wordpress。进去看了看,发现里面文章居然还没有删掉。于是我把它导出来,导进了lofter。

看看第一篇文章《几乎又放弃了》,o()o现在可以更新已经《已经放弃了》。从标题也可以看出我不是第一次放弃了。

还叫了一个不错的名字“无穷π”,“无穷代表着理性,派代表着无知”

再来看看我的自我介绍

自我介绍还是挺有意思的。

其实还有些所谓的技术文章。。。被我删了,放在了回收站。贴出来实在是搞笑。

昨晚我也犹豫了下,要不要继续这个blog?想了想还是决定用lofter吧。

因为只要我又回到wordpress,我就会又开始折腾。比如说再复习下PHP,SAE开发等等之类。舍本逐末,最后又会放弃了。还不如干脆只在lofter(突然又想到我在点点也用过一段时间。。。),这样我就只能安心的写文章了。再过段时间吧去申请个域名,绑定独立域名。

我甚至都忘记了用户名跟密码是啥,还好chrome有记录。

还是熟悉的仪表盘:

其实还有一个重要的原因让我继续用lofter的是不用考虑图床的问题。想当初对于一个没有多少经费的学生来说,存储空间是相当宝贵的。

虽说这个blog失败了,但是我还是有不少收获的。

  1. 知道弄一个网站大概的流程。
    
  2. 明白了为什么之前的都以失败告终。因为我把有限的精力放在了一些细枝末节的东西上。比如为了弄个好看的主题可以折腾一个礼拜、为了实现强大的功能能找上一整天的插件,等等。最后主题还是用默认,想要的插件功能还是没有找到。所以放弃是肯定的,也不必自责自己。
    
  3. 开始一个项目--->坚持1个月--->开始松懈--->几乎放弃--->放弃了--->自责--->重新计划--->忘记了。这就是我的模式。这是个值得探讨的问题。
    <a href="https://www.zhihu.com/question/21368231" rel="nofollow" target="_blank">
     《知乎:自控力极差的人如何自救?》
    </a>
    
  4. <strong>
     Incremental change is better than ambitious failure.
    </strong>
    
    
    <strong>
     逐步的改善 好过雄心勃勃的失败。
    </strong>
    
    
    <a href="https://www.zhihu.com/question/21368231" rel="nofollow" target="_blank">
     <br/>
    </a>
    

从system_call开始到iret

自己搭建了实验环境,逃离实验楼,实在是太卡了。自己的环境就是爽!

实验开始:

先加如getuid和getuidAsm代码:


运行系统:


实验下,添加的功能是否可以
效果没问题。

用GDB调试,设置断点

一步一步执行


实验目的达到了。

===========================================================================================================================这里是分割线========================================

从system_call开始到iret

网上有几张图很好的说明了这个过程。

能力不足,不足以详细的说明从system_call到iret的详细过程。在查阅了些资料后,发现有几张图还是解释的不错的,于是就把他们贴出来了。其实也是一种偷懒啦~

下图引用

《linux系统调用原理分析(下)》

下图引用

《system_call中断处理过程》

经过《扒开系统调用的三层皮》2周的学习,对系统调用有些感性的认识,但是没有书看啊,总感觉还是挺乱的。

sunfy + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://www.xuetangx.com/courses/course-v1:ustcX+USTC001+_/about ”

ubuntu环境搭建MenuOS的过程

实验楼做实验总是卡死,于是决定干脆自己搭建环境。


安装ubunt 14

安装qemu

下载linux-3.9.4源码包

原有桌面环境太消耗资源了,于是换成了xfce4

解压linux-3.18.6源码包

开始漫长的make。。。。。

终于好了

安装个git

git clone https://github.com/mengning/menu.git


搭建好啦

使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。


首先man getuid查看相关信息

编程


编译并运行:

嵌入式汇编:

系统调用是怎么工作的?

一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作"保护模式")。系统调用是这些规则的一个例外。其原理是进程先用适当的值填充寄存器,然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。在Intel CPU中,这个由中断

0x80

实现。硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统的内核–所以你就可以为所欲为。

进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(或到其他进程,如果这个进程时间用尽)。如果你希望读这段代码,它在<内核源码目录>/kernel/entry.S,Entry(system_call)的下一行。

对比结果相同

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

Linux 中 x86 的内联汇编 系统调用跟我学(1)
Linux系统调用列表
【linux系统编程】 Linux系统调用概述

> sunfy(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

没有鸡汤,试着接受平庸的自己。

我一直自命不凡,即使当下的我很平凡,也会认为未来的我将会不平凡。

但是现在我不这么认为了,我不再认为我将逃出平庸。我一直都很平庸。现在我已经23了,对那种不平庸的未来我已经失去了信心。虽然目前我难以接受我将会平庸下去的这个残忍事实,但我知道我必须慢慢接受平庸的自己。否则我只会陷入无限的痛苦中。

考研失败,努力了一年没有得到想要的回报。

面试失败,面试官说觉得我还不错,可是送走我后却迟迟没有通知我报道。

我好像还是活在从前的世界中,当我慢慢接近社会时,我明显的感受到了外界的压力。我渴望能够改变自己,却不知道从哪开始。

我希望能有人给我指指路,却不知谁能帮我。

迷茫、恐慌、不知所措用来形容最适合不过了!