博文

目前显示的是 六月, 2011的博文

Linux系统调用宏展开笔记

不知道从哪个版本的内核开始,系统调用变成宏了。在2.6.38的内核里面追踪了一下,以SYSCALL_DEFINE1为例:   SYSCALL_DEFINE1(name,...)展开sys_name,后面的数字,若为1则是一个参数,若为2则为2个参数   具体的宏,展开跟踪流程如下: #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)                                         |                                            v                            #define SYSCALL_DEFINEx(x, sname, ...)              \                                   __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)                                          |                                                                       v                                                      #define __SYSCALL_DEFINEx(x, name, ...)                 \                          asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))                                                      \                                                          \                                             #define __SC

Xen-ARM Guest DOM启动以及VCPU切换

/* 从hypervisor到DOM的转换比较复杂,简单的步骤有两个阶段: 1.将guest的contest的寄存器信息赋值,其中还包括一些DOM设置信息 2.调用scheduler通过__switch_to调度到设置的VCPU上 */ ------------hypervisor------------- construct_guest_dom() { ..... new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start); ..... } void new_thread(struct vcpu *d, unsigned long start_pc, unsigned long start_stack, unsigned long start_info) { unsigned long *domain_stack; struct cpu_info *ci; struct cpu_user_regs *domain_context; struct cpu_user_regs *regs = &d->arch.guest_context.user_regs; domain_stack = alloc_xenheap_pages(STACK_ORDER); if(domain_stack == NULL) { return; } ci = (struct cpu_info *)domain_stack; ci->cur_vcpu = d; domain_stack += (STACK_SIZE - sizeof(struct cpu_user_regs))/sizeof(unsigned long); domain_context = (struct cpu_user_regs *)domain_stack; domain_context->r0 = 0; domain_context->r12 = start_info;//参数传过来 domain_context->r13 = start_stack; domain_context->r15 = start_pc;//DOM的启始地址 domain_context->psr = 0x13; regs->

[xen-arm]关于Goldfish设备初始化

在移植goldfish的时候,如果没有module机制,怎么做呢?从pdev_bus_driver开始.  143 asmlinkage void do_softirq(void) 144 { 145     unsigned int i, cpu = smp_processor_id(); 146     unsigned long pending; 147     pending = softirq_pending(cpu); 148     ASSERT(pending != 0); 149  150     do { 151         i = find_first_set_bit(pending); 152         if(flag < 2 || sched_flag == 1) 153         { 154             if(flag == 0) 155                 switch_init(); 156             local_irq_enable(); 157             if(flag == 1){//设备初始化 158                 goldfish_pdev_bus_driver.probe(&goldfish_pdev_bus_device); 159                 printk("init screen\n"); 160                 testfb(); 161             //  mnt_init(); 162             } 163             flag = 2; 164             sched_flag = 0; 165             monitor(); 166         } 167         clear_bit(i, &softirq_pending(cpu)); 168         (*softirq_handlers[i])(); 169  170         if(flag >=2 && flag <= 60) 171            

应用程序在Linux上的执行过程

转自: http://blog.ixpub.net/html/74/13325674-109393.html 执行文件是如何在shell中被"执行"的。本文中尽可能少用一些源码,免得太过于无聊,主要讲清这个过程,感兴趣的同学可以去查看相应的源码了解更多的信息。   1.父进程的行为: 复制,等待 执行应用程序的方式有很多,从shell中执行是一种常见的情况。交互式shell是一个进程(所有的进程都由pid号为1的init进程fork得到,关于这个话题涉及到 Linux 启动和初始化,以及idle进程等,有空再说),当在用户在shell中敲入./test执行程序时,shell先fork()出一个子进程(这也是很多文章中说的子shell),并且wait()这个子进程结束,所以当test执行结束后,又回到了shell等待用户输入(如果创建的是所谓的后台进程,shell则不会等待子进程结束,而直接继续往下执行)。所以shell进程的主要工作是复制一个新的进程,并等待它的结束。   2.子进程的行为: "执行"应用程序 2.1 execve() 另一方面,在子进程中会调用execve()加载test并开始执行。这是test被执行的关键,下面我们详细分析一下。   execve()是操作系统提供的非常重要的一个系统调用,在很多文章中被称为exec()系统调用(注意和shell内部exec命令不一样),其实在Linux中并没有exec()这个系统调用,exec只是用来描述一组函数,它们都以exec开头,分别是:     #include   int execl(const char *path, const char *arg, ...);   int execlp(const char *file, const char *arg, ...);   int execle(const char *path, const char *arg, ..., char *const envp[]);   int execv(const char *path, char *const argv[]);   int execvp(const char *file, char *const argv[]);   int exe