<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[ZYX的专栏]]></title><description><![CDATA[专注嵌入式开发]]></description><link>https://blog.youkuaiyun.com/u012007928</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; u012007928]]></copyright><item><title><![CDATA[mount实现的过程]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43816397</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43816397</guid><author>u012007928</author><pubDate>Sat, 14 Feb 2015 11:00:35 +0800</pubDate><description><![CDATA[本质上，Ext3 mount的过程实际上是inode被替代的过程。例如，/dev/sdb块设备被mount到/mnt/alan目录。那么mount这个过程所需要解决的问题就是将/mnt/alan的dentry目录项所指向的inode屏蔽掉，然后重新定位到/dev/sdb所表示的inode索引节点。在没有分析阅读linux
 vfs mount代码的时候，我的想法是修改dentry所指向的inod]]></description><category></category></item><item><title><![CDATA[二维数组]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43730791</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43730791</guid><author>u012007928</author><pubDate>Wed, 11 Feb 2015 09:58:46 +0800</pubDate><description><![CDATA[int arr[5][];  这样的定义是无法编译通过的。

因为你没有给出二维数组的第二个维度。即可以写成 int arr[][5]，或者int arr[3][5]。
也就是说，定义二维数组时必须写明第二个维度，而第一个维度可以给也可以不给，如果不给第一个维度，编译器会根据你的初始化语句自动决定第一维度。
二维数组在内存中其实是一个平坦的一维数组，下面具体说明：
int arr[3][5] 和 ]]></description><category></category></item><item><title><![CDATA[数组名和数组名取地址的区别]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43730447</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43730447</guid><author>u012007928</author><pubDate>Wed, 11 Feb 2015 09:26:51 +0800</pubDate><description><![CDATA[以下代码会打印出什么样的日志呢？



[cpp] view
 plaincopy






#include   
  
int a[2] = {1,2};  
int main(){  
        printf("a = %p\n", a); // I  
        printf("&a = %p\n", &a); // II  
      ]]></description><category></category></item><item><title><![CDATA[进程页表两级结构：页目录和页表页]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43706273</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43706273</guid><author>u012007928</author><pubDate>Tue, 10 Feb 2015 18:20:36 +0800</pubDate><description><![CDATA[进程页表的基本结构仅适合于小进程地址空间，在大地址空间下，该结构发生了变化。大虚址空间下的内存进程页表结构采用页表页和页目录。
   32位意味着虚址空间可达4GB
   虚址空间计算方法：32位的编址为232，232=210*210*210*22=4GB
1k=1024b
1m=1024K
1g=1024M
   若虚址空间为2GB，在页长4KB时共有
2G=1024K*1024K]]></description><category></category></item><item><title><![CDATA[形参和实参的区别]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43573673</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43573673</guid><author>u012007928</author><pubDate>Fri, 06 Feb 2015 20:32:19 +0800</pubDate><description><![CDATA[形参:全称为"形式参数"是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传如的参数.
实参:全称为"实际参数"是在调用时传递个该函数的参数.


--------------------------------------------------------------------------------

void Exchg1(int x, int y) 
{]]></description><category></category></item><item><title><![CDATA[二级指针和内存分配问题 形参和实参]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43571521</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43571521</guid><author>u012007928</author><pubDate>Fri, 06 Feb 2015 20:08:27 +0800</pubDate><description><![CDATA[char p是声明一个字符类型变量p,char * p1是声明一个字符类型的指针变量p1,那么char ** p2就相当与给char类型的指针变量再声明一个指针.(2级指针)

举个例子,假如:
char p='a';//假设声明了p后,p在内存的1000处,则&p=1000(&为取变量首地址)
char * p1=&p;//则p1=1000,*p1=p='a',p1就和p关联了;假设p1被放在2]]></description><category></category></item><item><title><![CDATA[stm32 lwip的DHCP]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43483091</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43483091</guid><author>u012007928</author><pubDate>Wed, 04 Feb 2015 10:40:40 +0800</pubDate><description><![CDATA[stm32f107 lwip dhcp
第一篇        DHCP自动获取功能的实现
概要
  DHCP在电脑中经常用到，因为我们并不关心我们电脑的IP是多少 只要能连上网络就行了。在嵌入式的产品设备中，DHCP用到的比较少，因为很多的操作是通过ip来进行的。除非那种有服务器的系统设备会用到。这里我们只能简单说一下流程，设计的代码太多了，具体的需要学习者自己去慢慢研究。
dhcp模块：]]></description><category></category></item><item><title><![CDATA[linux线程的退出--附：一个变量，两个精彩]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43407877</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43407877</guid><author>u012007928</author><pubDate>Mon, 02 Feb 2015 14:16:25 +0800</pubDate><description><![CDATA[linux的2.6内核更好的实现了内核级别的线程，使得线程的语义更加符合posix的约定，总的来说，线程会在两种地方退出，第一个是正常退出，第二种是异常退出，正常退出的情况下，比如在一个进程的一个线程调用exec的时候，那么所有的别的线程都会退出，另外在一个线程调用exit库函数的时候或者调用group_exit系统调用的时候，整个线程都会退出，异常的情况下，接收到内核的严重错误信号的时候也会退出]]></description><category></category></item><item><title><![CDATA[进程内核栈、用户栈]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43404365</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43404365</guid><author>u012007928</author><pubDate>Mon, 02 Feb 2015 08:56:28 +0800</pubDate><description><![CDATA[进程内核栈、用户栈

1.进程的堆栈
     内核在创建进程的时候，在创建task_struct的同事，会为进程创建相应的堆栈。每个进程会有两个栈，一个用户栈，存在于用户空间，一个内核栈，存在于内核空间。当进程在用户空间运行时，cpu堆栈指针寄存器里面的内容是用户堆栈地址，使用用户栈；当进程在内核空间时，cpu堆栈指针寄存器里面的内容是内核栈空间地址，使用内核栈。
2.进程用户栈和内核栈]]></description><category></category></item><item><title><![CDATA[多线程信号总结]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43308055</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43308055</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 15:56:01 +0800</pubDate><description><![CDATA[linux 多线程信号总结(一)

1. 在多线程环境下，产生的信号是传递给整个进程的，一般而言，所有线程都有机会收到这个信号，进程在收到信号的的线程上下文执行信号处理函数，具体是哪个线程执行的难以获知。也就是说，信号会随机发个该进程的一个线程。

2 signal函数BSD/Linux的实现并不在信号处理函数调用时，恢复信号的处理为默认，而是在信号处理时阻塞此信号，直到信号处理函数返回。]]></description><category></category></item><item><title><![CDATA[list_for_each_entry]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43307257</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43307257</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 15:02:49 +0800</pubDate><description><![CDATA[#define list_for_each_entry(pos, head, member)              \  
    for (pos = list_entry((head)->next, typeof(*pos), member);   \  
         prefetch(pos->member.next), &pos->member != (head);  \  ]]></description><category></category></item><item><title><![CDATA[list_for_each]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43306849</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43306849</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 14:32:48 +0800</pubDate><description><![CDATA[Linux系统中的每个进程都有一个父进程（init进程除外）；每个进程还有0个或多个子进程。在进程描述符中parent指针指向其父进程，还有一个名为children的子进程链表（父进程task_struct中的children相当于链表的表头）。

而我们可以使用list_for_each(/include/linux/list.h)来依次遍历访问子进程：

struct task_str]]></description><category></category></item><item><title><![CDATA[list_entry()详解]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43306709</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43306709</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 14:22:12 +0800</pubDate><description><![CDATA[Linux内核中，获取节点地址的函数list_entry()非常常用，由于其定义有点晦涩，先解析如下：




list_entry的宏定义：

#define list_entry(ptr, type, member) / 
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 
这个倒是不难理解：从一个]]></description><category></category></item><item><title><![CDATA[select函数的实现源码]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43304549</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43304549</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 11:12:52 +0800</pubDate><description><![CDATA[代码摘自：linux-2.6.29
sys_select -> core_sys_select -> do_select




int do_select(int n, fd_set_bits *fds, struct timespec *end_time)

{

        ktime_t expire, *to = NULL;

        struct p]]></description><category></category></item><item><title><![CDATA[信号 中断系统调用 递送]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43303265</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43303265</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 09:58:33 +0800</pubDate><description><![CDATA[1 前言 
写作本文的目的和其它文章略有不同，不是为了系统和全面的介绍”信号”这个子系统，--虽然它不复杂，其内容也不是一篇短短的文章所能够覆盖的，而是要回答自己的疑惑，解决工作中遇到的一些问题，理解那些不能够马上了解的部分。说到底，可以将这篇文章看作问题的答案。 

曾经遇到的问题放在最后一节”问题与答案”中，在阅读正文之前先扫描一下问题可能更加有助于理解文章中的内容。 

欢迎大家对]]></description><category></category></item><item><title><![CDATA[阻塞访问原理——等待队列]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43302925</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43302925</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 09:34:39 +0800</pubDate><description><![CDATA[有些时候，一个系统调用可能无法马上取到或者送出数据：一个温度采集器如果没有采用中断或者轮询的策略，而是在用户发出请求时才进行采集，并在一定的时间后返回结果。如果用户程序希望调用read或write并且在调用返回时能确保得到想要的结果，那么用户程序应该阻塞，直到有结果或者错误后返回，用户程序的阻塞体现为进程的睡眠，也即系统调用中将进程状态切换为睡眠态。

 

睡眠和等待队列

一个进程]]></description><category></category></item><item><title><![CDATA[Linux的进程调度时机（Schedule函数何时调用）]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43302525</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43302525</guid><author>u012007928</author><pubDate>Fri, 30 Jan 2015 08:48:47 +0800</pubDate><description><![CDATA[Linux在众多进程中是怎么进行调度的，这个牵涉到Linux进程调度时机的概念，由Linux内核中Schedule（）的函数来决定是否要进行进程的切换，如果要切换的话，切换到哪个进程等等。

Linux进程调度时机主要有：

1、进程状态转换的时刻：进程终止、进程睡眠；

2、当前进程的时间片用完时（current->counter=0）；

3、设备驱动程序

4、进程从中断]]></description><category></category></item><item><title><![CDATA[打开文件的内核源码分析]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43271263</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43271263</guid><author>u012007928</author><pubDate>Thu, 29 Jan 2015 14:51:03 +0800</pubDate><description><![CDATA[一、概要
   用户进程在能够读/写一个文件之前必须要先打开这个文件，从概念上说是一个进程与文件系统之间的一种有链接的通信，对于打开文件实质就是在进程和文件之间建立起连接，而“打开文件号”就是唯一的标识这个连接。在文件系统的处理当中，每当一个进程重复打开同一个文件时就建立起一个由file数据结构代表的独立的上下文。通常，一个file数据结构，即一个读/写文件的上下文，都是由一个“打开文件号”加以]]></description><category></category></item><item><title><![CDATA[Linux操作系统常见文件结构体]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43266843</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43266843</guid><author>u012007928</author><pubDate>Thu, 29 Jan 2015 09:55:11 +0800</pubDate><description><![CDATA[大家都知道进程，可是知道linux是怎么管理其进程的吗？每一个进程都有一个进程描述符，具体是task_struct结构体存储相关的信息，在linux/sched.h文件里定义，那么我们先看看linux内核3.0版本的task_struct结构体的定义吧（删除了不必要的字段，只保留了重要的字段）。同时欢迎大家转载和交流。
struct task_struct {
 
 
 
//这个是进程]]></description><category></category></item><item><title><![CDATA[waitpid函数源码]]></title><link>https://blog.youkuaiyun.com/u012007928/article/details/43266275</link><guid>https://blog.youkuaiyun.com/u012007928/article/details/43266275</guid><author>u012007928</author><pubDate>Thu, 29 Jan 2015 09:06:21 +0800</pubDate><description><![CDATA[int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)//挂起当前进程，直到pid指定的子进程退出终止或者收到要求终止该进程
 的信号 ，或者需要调用 一个信号处理函数

{
    int flag, code;
    struct task_struct ** p;

    verify_area(s]]></description><category></category></item></channel></rss>