Arm_Linux内核零碎笔记

来源:网络 责任编辑:栏目编辑 发表时间:2013-07-01 11:21 点击:

字符设备 open->sys_open->(current->task_struct->fops = kobj_map->probes[主设备号]->ops)

module_init->是把所有驱动的初始化函数指针放到一个独立的段里,从那个段得起始地址依次调用.

ioremap 会重叠映射物理地址

include/linux/init.h -> #define module_init

内核启动时,会通过协处理指令(MCR P15,0,(Rd orr 0x2000),C1,C0,0)配置ARM内核的中断跳转地址为0xFFFF0000
----------------------------------
CP15 Register 1: Control registers
V (bit[13]) This bit is used to select the location of the exception vectors:
0 = Normal exception vectors selected (address range 0x00000000-0x0000001C)
1 = High exception vectors selected (address range 0xFFFF0000-0xFFFF001C).
An implementation can provide an input signal that determines the state of this bit after reset.

#define __initdata __section(.init.data)

实在计算不出他的地址了,就反汇编内核(arm-linux-gnu-objdump -D vmlinux > linux.dis).

系统调用->fs\*.c

vmlinux(带调试信息的ELF内核)->image(纯内核(D3 F0 21 E3 10 9F 10 EE))->zImage(加了压缩代码的内核)->uImage(加了64字节信息的内核)

ARM-ATPCS规则
----------------------------------------------------------------------------------------------------------
FP当前参数栈帧指针和当前函数体的局部变量
SP当前模式栈指针和当前函数调用传参参数的指针
第五个参数开始的压栈方向是从左到右
 
 

内核启动流程
----------------------------------------------------------------------------------------------------------
arch\arm\kernel\head.S->stext()->init\main.c->start_kernel()
 
 

原子操作
----------------------------------------------------------------------------------------------------------
自旋锁
static inline void atomic_add(int i, atomic_t *v)
{
unsigned long tmp;
int result;

__asm__ __volatile__("@ atomic_add\n"
"1:ldrex %0, [%3]\n"
"add %0, %0, %4\n"
"strex %1, %0, [%3]\n"
"teq %1, #0\n"
"bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
}
static inline void atomic_sub(int i, atomic_t *v)
{
unsigned long tmp;
int result;

__asm__ __volatile__("@ atomic_sub\n"
"1:ldrex %0, [%3]\n"
"sub %0, %0, %4\n"
"strex %1, %0, [%3]\n"
"teq %1, #0\n"
"bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
}
----------------------------------------------------------------------------------------------------------
信号量
void down(struct semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
__down(sem);//关中断,把自己放到等待队列里,然后把自己设置为不可中断睡眠,开中断,请求调度.
spin_unlock_irqrestore(&sem->lock, flags);
}
static noinline void __sched __up(struct semaphore *sem)
{
struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
struct semaphore_waiter, list);
list_del(&waiter->list);
waiter->up = 1;
wake_up_process(waiter->task);
}
 
 

可中断睡眠/不可中断睡眠
-----------------------
两种任务状态,区别在于时钟中断检查时间片时,如果是可中断睡眠,就会检查该任务的信号队列,如果是不可中断睡眠,则不会检查.
 
 

中断和系统调用
-----------------------

    相关新闻>>

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • /etc/fstab 详解
    • nginx主主集群
    •  LVS-NAT和LVS-DR模式的实现详解
    •  RHCE考试之磁盘配额
    • 学习笔记:ACL详解
    •  LVM逻辑卷管理器
    • suse linux双网卡双网关配置
    •  Nginx主主负载均衡架构
    • ubuntu学习Mysql

    快速直达

    操作系统导航

    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1