linux 驅(qū)動(dòng)開(kāi)發(fā) - 內(nèi)核模塊

一贮缕、Linux內(nèi)核簡(jiǎn)介

1.宏內(nèi)核與微內(nèi)核

內(nèi)核分為四大類:?jiǎn)蝺?nèi)核(宏內(nèi)核)惜浅;微內(nèi)核;混合內(nèi)核山孔;外內(nèi)核懂讯。

  • 宏內(nèi)核(Monolithickernel)是將內(nèi)核從整體上作為一個(gè)大過(guò)程來(lái)實(shí)現(xiàn),所有的內(nèi)核服務(wù)都在一個(gè)地址空間運(yùn)行台颠,相互之間直接調(diào)用函數(shù)褐望,簡(jiǎn)單高效。
    • Linux雖是宏內(nèi)核串前,但已吸收了微內(nèi)核的部分精華瘫里。Linux是模塊化的、多線程的荡碾、內(nèi)核本身可調(diào)度的系統(tǒng)减宣,既吸收了微內(nèi)核的精華,又保留了宏內(nèi)核的優(yōu)點(diǎn)玩荠,無(wú)需消息傳遞,避免性能損失贼邓。
  • 微內(nèi)核(Microkernel)功能被劃分成獨(dú)立的過(guò)程阶冈,過(guò)程間通過(guò)IPC進(jìn)行通信,模塊化程度高塑径,一個(gè)服務(wù)失效不會(huì)影響另外一個(gè)服務(wù)女坑。
image

2.Linux體系架構(gòu)

從兩個(gè)層次上來(lái)考慮操作系統(tǒng)

  • 用戶空間:包含了用戶的應(yīng)用程序和C庫(kù)
    • GNU C Library (glibc)提供了連接內(nèi)核的系統(tǒng)調(diào)用接口,還提供了在用戶空間應(yīng)用程序和內(nèi)核之間進(jìn)行轉(zhuǎn)換的機(jī)制统舀。
  • 內(nèi)核空間:包含了系統(tǒng)調(diào)用匆骗,內(nèi)核,以及與平臺(tái)架構(gòu)相關(guān)的代碼
image

劃分原因

  • 現(xiàn)代CPU通常都實(shí)現(xiàn)了不同的工作模式

    • 以ARM為例:ARM實(shí)現(xiàn)了7種工作模式誉简,不同模式下CPU可以執(zhí)行的指令或者訪問(wèn)的寄存器不同:

      • (1)用戶模式 usr
      • (2)系統(tǒng)模式 sys
      • (3)管理模式 svc
      • (4)快速中斷 fiq
      • (5)外部中斷 irq
      • (6)數(shù)據(jù)訪問(wèn)終止 abt
      • (7)未定義指令異常碉就;
    • 以X86為例:X86實(shí)現(xiàn)了4個(gè)不同級(jí)別的權(quán)限,Ring0—Ring3 ;Ring0下可以執(zhí)行特權(quán)指令闷串,可以訪問(wèn)IO設(shè)備瓮钥;Ring3則有很多的限制。

  • 為了保護(hù)內(nèi)核的安全烹吵,把系統(tǒng)分成了2部分:用戶空間和內(nèi)核空間是程序執(zhí)行的兩種不同狀態(tài)碉熄,我們可以通過(guò)“系統(tǒng)調(diào)用”和“硬件中斷“來(lái)完成用戶空間到內(nèi)核空間的轉(zhuǎn)移;

3.Linux的內(nèi)核結(jié)構(gòu)

Linux內(nèi)核是整體式結(jié)構(gòu)(宏內(nèi)核)肋拔,各個(gè)子系統(tǒng)聯(lián)系緊密锈津,作為一個(gè)大程序在內(nèi)核空間運(yùn)行。

系統(tǒng)調(diào)用接口(system call interface凉蜂,SCI)提供了某些機(jī)制執(zhí)行從用戶空間到內(nèi)核的函數(shù)調(diào)用琼梆。

image
1)Linux內(nèi)核組成(子系統(tǒng))
  • 進(jìn)程調(diào)度(SCHED):控制多個(gè)進(jìn)程對(duì)CPU的訪問(wèn)性誉。當(dāng)需要選擇下一個(gè)進(jìn)程運(yùn)行時(shí),由調(diào)度程序選擇最值得運(yùn)行的進(jìn)程叮叹“埃可運(yùn)行進(jìn)程實(shí)際上是僅等待CPU資源的進(jìn)程,如果某個(gè)進(jìn)程在等待其它資源蛉顽,則該進(jìn)程是不可運(yùn)行進(jìn)程蝗砾。Linux使用了比較簡(jiǎn)單的基于優(yōu)先級(jí)的進(jìn)程調(diào)度算法選擇新的進(jìn)程。

  • 內(nèi)存管理(memory management携冤,MM):允許多個(gè)進(jìn)程安全的共享主內(nèi)存區(qū)域悼粮。Linux 的內(nèi)存管理支持虛擬內(nèi)存,即在計(jì)算機(jī)中運(yùn)行的程序曾棕,其代碼扣猫,數(shù)據(jù),堆棧的總量可以超過(guò)實(shí)際內(nèi)存的大小翘地,操作系統(tǒng)只是把當(dāng)前使用的程序塊保留在內(nèi)存中申尤,其余的程序塊則保留在磁盤中。必要時(shí)衙耕,操作系統(tǒng)負(fù)責(zé)在磁盤和內(nèi)存間交換程序塊昧穿。內(nèi)存管理從邏輯上分為硬件無(wú)關(guān)部分和硬件有關(guān)部分。硬件無(wú)關(guān)部分提供了進(jìn)程的映射和邏輯內(nèi)存的對(duì)換橙喘;硬件相關(guān)的部分為內(nèi)存管理硬件提供了虛擬接口时鸵。

    • 一般而言,Linux的每個(gè)進(jìn)程享有4GB的內(nèi)存空間厅瞎,03GB屬于用戶空間饰潜,34GB屬于內(nèi)核空間。
  • 虛擬文件系統(tǒng)(Virtual File System,VFS):隱藏了各種硬件的具體細(xì)節(jié)和簸,為所有的設(shè)備提供了統(tǒng)一的接口彭雾,VFS提供了多達(dá)數(shù)十種不同的文件系統(tǒng)。虛擬文件系統(tǒng)可以分為邏輯文件系統(tǒng)和設(shè)備驅(qū)動(dòng)程序比搭。邏輯文件系統(tǒng)指Linux所支持的文件系統(tǒng)冠跷,如ext2,fat等,設(shè)備驅(qū)動(dòng)程序指為每一種硬件控制器所編寫的設(shè)備驅(qū)動(dòng)程序模塊身诺。

    image
  • 網(wǎng)絡(luò)接口(NET):提供了對(duì)各種網(wǎng)絡(luò)標(biāo)準(zhǔn)的存取和各種網(wǎng)絡(luò)硬件的支持蜜托。網(wǎng)絡(luò)接口可分為網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)驅(qū)動(dòng)程序。網(wǎng)絡(luò)協(xié)議部分負(fù)責(zé)實(shí)現(xiàn)每一種可能的網(wǎng)絡(luò)傳輸協(xié)議霉赡。網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序負(fù)責(zé)與硬件設(shè)備通訊橄务,每一種可能的硬件設(shè)備都有相應(yīng)的設(shè)備驅(qū)動(dòng)程序。

    image
  • 進(jìn)程間通訊(inter-process communication穴亏,IPC): 支持進(jìn)程間各種通信機(jī)制蜂挪。

    • 共享內(nèi)存
    • 管道
    • 信號(hào)量
    • 消息隊(duì)列
    • 套接字

4.內(nèi)核模塊

Linux內(nèi)核是模塊化組成的重挑,它允許內(nèi)核在運(yùn)行時(shí)動(dòng)態(tài)地向其中插入或刪除代碼。

二棠涮、內(nèi)核模塊結(jié)構(gòu)

1.頭文件

內(nèi)核模塊頭文件<linux/module.h>和<linux/init.h>是必不可少的 谬哀,不同模塊根據(jù)功能的差異,所需要的頭文件也不相同 严肪。

#include <linux/module.h>
#include <linux/init.h>

2.模塊初始化

模塊的初始化負(fù)責(zé)注冊(cè)模塊本身 史煎,只有已注冊(cè)模塊的各種方法才能夠被應(yīng)用程序使用并發(fā)揮各方法的實(shí)際功能。

模塊并不是內(nèi)核內(nèi)部的代碼驳糯,而是獨(dú)立于內(nèi)核之外篇梭,通過(guò)初始化,能夠讓內(nèi)核之外的代碼來(lái)替內(nèi)核完成本應(yīng)該由內(nèi)核完成的功能酝枢,模塊初始化的功能相當(dāng)于模塊與內(nèi)核之間銜接的橋梁恬偷,告知內(nèi)核已經(jīng)準(zhǔn)備好模塊了。

內(nèi)核模塊初始化函數(shù)

//模塊初始化函數(shù)一般都需聲明為 static
//__init 表示初始化函數(shù)僅僅在初始化期間使用帘睦,一旦初始化完畢袍患,將釋放初始化函數(shù)所占用的內(nèi)存
static int __init module_init_func(void)
{
    初始化代碼
}
module_init(module_init_func);
//module_init宏定義會(huì)在模塊的目標(biāo)代碼中增加一個(gè)特殊的代碼段,用于說(shuō)明該初始化函數(shù)所在的位置竣付。

當(dāng)使用 insmod 將模塊加載進(jìn)內(nèi)核的時(shí)候协怒,初始化函數(shù)的代碼將會(huì)被執(zhí)行。

3.模塊退出

模塊的退出相當(dāng)于告知內(nèi)核“我要離開(kāi)了卑笨,將不再為您服務(wù)了”。

內(nèi)核模塊退出函數(shù)

//模塊退出函數(shù)沒(méi)有返回值仑撞;
//__exit 標(biāo)記這段代碼僅用于模塊卸載赤兴;
static void __exit module_exit_func(void)
{
    //模塊退出代碼
}
module_exit(module_exit_func);
//沒(méi)有 module_exit 定義的模塊無(wú)法被卸載

當(dāng)使用 rmmod 卸載模塊時(shí),退出函數(shù)的代碼將被執(zhí)行隧哮。

注意:如果模塊被編譯進(jìn)內(nèi)核桶良,而不是動(dòng)態(tài)加載,則__init的使用會(huì)在模塊初始化完成后丟棄該函數(shù)并回收所占內(nèi)存, _exit宏將忽略“清理收尾”的函數(shù)沮翔。

4.模塊許可證聲明

Linux 內(nèi)核是開(kāi)源的陨帆,遵守 GPL 協(xié)議,所以要求加載進(jìn)內(nèi)核的模塊也最好遵循相關(guān)協(xié)議采蚀。

為模塊指定遵守的協(xié)議用 MODULE_LINCENSE 來(lái)聲明 :

MODULE_LICENSE("GPL");
  • 內(nèi)核能夠識(shí)別的協(xié)議有
    • “GPL”
    • “GPL v2”
    • “GPL and additional rights(GPL 及附加權(quán)利)”
    • “Dual BSD/GPL(BSD/GPL 雙重許可)”
    • “Dual MPL/GPL(MPL/GPL 雙重許可)”
    • “Proprietary(私有)”

5.模塊導(dǎo)出符號(hào) 【可選】

使用模塊導(dǎo)出符號(hào)疲牵,方便其它模塊依賴于該模塊,并使用模塊中的變量和函數(shù)等榆鼠。

  • 在Linux2.6的內(nèi)核中纲爸,/proc/kallsyms文件對(duì)應(yīng)著符號(hào)表,它記錄了符號(hào)和符號(hào)對(duì)應(yīng)的內(nèi)存地址妆够。

    $ cat /proc/kallsyms 
    ...
    ffffff80084039b8 t shash_digest_unaligned
    ffffff8008403a30 T crypto_shash_digest
    ffffff8008403ac0 t shash_async_final
    ffffff8008403af0 T shash_ahash_update
    ffffff8008403b50 t shash_async_update
    ffffff8008403b80 t crypto_exit_shash_ops_async
    ffffff8008403bb0 t crypto_shash_report
    ffffff8008403c18 t crypto_shash_show
    ffffff8008403c78 T crypto_alloc_shash
    ffffff8008403cc8 T crypto_register_shash
    ffffff8008403d00 T crypto_unregister_shash
    ffffff8008403d30 T crypto_register_shashes
    ffffff8008403df8 T crypto_unregister_shashes
    ffffff8008403e90 T shash_register_instance
    ffffff8008403ed0 T shash_free_instance
    ffffff8008403f08 T crypto_init_shash_spawn
    ffffff8008403f58 T shash_attr_alg
    ffffff8008403fb0 T shash_ahash_finup
    ffffff8008404068 t shash_async_finup
    ffffff80084040b0 T shash_ahash_digest
    ffffff80084041e0 t shash_async_digest
    ...
    
  • 使用一下宏定義導(dǎo)出符號(hào)

    EXPORT_SYMBOL(module_symbol);
    //或
    EXPORT_GPL_SYMBOL(module_symbol);
    

6.模塊描述 [可選]

模塊編寫者還可以為所編寫的模塊增加一些其它描述信息识啦,如模塊作者负蚊、模塊本身的描述或者模塊版本等

MODULE_AUTHOR("Abing <Linux@zlgmcu.com>");
MODULE_DESCRIPTION("ZHIYUAN ecm1352 beep Driver");
MODULE_VERSION("V1.00");

模塊描述以及許可證聲明一般放在文件末尾。

三颓哮、向Linux內(nèi)核添加新內(nèi)核模塊

1.添加模塊驅(qū)動(dòng)文件

在linux/drivers/下新建目錄hello家妆,并且在hello/目錄下新建hello.c、Makefile冕茅、Kconfig三個(gè)文件伤极。

1)內(nèi)核模塊程序hello.c
/* hello world module */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

static int __init hello_init(void)
{
  printk(KERN_INFO "Hello, I'm ready!\n");
  return 0;
}
static void __exit hello_exit(void)
{
  printk(KERN_INFO "I'll be leaving, bye!\n");
}
module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("michael");
MODULE_DESCRIPTION("hello world module");
  • 內(nèi)核通過(guò) printk() 輸出的信息具有日志級(jí)別,日志級(jí)別是通過(guò)在 printk() 輸出的字符串前加一個(gè)帶尖括號(hào)的整數(shù)來(lái)控制的嵌赠,如 printk(“<6>Hello, world!/n”);塑荒。內(nèi)核中共提供了八種不同的日志級(jí)別

    // 在 linux/kernel.h 中有相應(yīng)的宏對(duì)應(yīng)
    #define KERN_EMERG    "<0>"    /* system is unusable */
    #define KERN_ALERT    "<1>"    /* action must be taken immediately */
    #define KERN_CRIT     "<2>"    /* critical conditions */
    #define KERN_ERR      "<3>"    /* error conditions */
    #define KERN_WARNING  "<4>"    /* warning conditions */
    #define KERN_NOTICE   "<5>"    /* normal but significant */
    #define KERN_INFO     "<6>"    /* informational */
    #define KERN_DEBUG    "<7>"    /* debug-level messages */
    
2)Kconfig
menu "HELLO TEST Driver "
comment "HELLO TEST Driver Config"
 
config HELLO
    tristate "hello module test"
    default m
    help
    This is the hello test driver.
 
endmenu
  • 在menuconfig的“driver”菜單下添加“HELLO TEST Driver”子菜單,并加入“HELLO”配置選項(xiàng)姜挺,選項(xiàng)默認(rèn)為m齿税。
  • 保存menuconfig后,會(huì)在kernel根目錄下的.config文件中生成“CONFIG_HELLO=m”炊豪,在編譯的時(shí)候會(huì)添加到臨時(shí)環(huán)境變量中凌箕。
3)Makefile
obj-$(CONFIG_HELLO) += hello.o

可用于動(dòng)態(tài)模塊外部編譯的寫法

  • 編譯模塊的內(nèi)核配置必須與所運(yùn)行內(nèi)核的編譯配置一樣 。

    ifneq ($(KERNELRELEASE),)
             obj-m += hello.o
    else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build  # 定義內(nèi)核路徑
    PWD := $(shell pwd)
    default:
            $(MAKE) -C $(KERNELDIR) M=$(PWD) modules   # 表示在當(dāng)前目錄下編譯
    clean:
            rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
    endif
    
    • KERNELRELEASE是在內(nèi)核源碼的頂層Makefile中定義的一個(gè)變量词渤,在第一次讀取執(zhí)行此Makefile時(shí)牵舱,KERNELRELEASE沒(méi)有被定義,所以make將讀取執(zhí)行else之后的內(nèi)容缺虐。
    • 當(dāng)從內(nèi)核源碼目錄返回時(shí)芜壁,KERNELRELEASE已被定義,kbuild也被啟動(dòng)去解析kbuild語(yǔ)法的語(yǔ)句高氮,make將繼續(xù)讀取else之前的內(nèi)容慧妄,生成的目標(biāo)模塊名。

2.修改上一級(jí)目錄的Kconfig和Makefile

進(jìn)入linux/drivers/

  • 編輯Makefile剪芍,在后面添加一行:

    obj-$(CONFIG_HELLO) += hello/
    
  • 編輯Kconfig塞淹,在后面添加一行:

    source "drivers/hello/Kconfig"
    
    • 注:某些內(nèi)核版本需要同時(shí)在arch/arm/Kconfig中添加:source "drivers/hello/Kconfig"

3.make menuconfig配置和編譯

  • 執(zhí)行:make menuconfig ARCH=arm進(jìn)入配置菜單
  • 選擇并進(jìn)入:Device Drivers選項(xiàng)
image
  • 進(jìn)入 HELLO TEST Driver選項(xiàng)

    image
    • 可以選擇<m> <y> <n>,分別為編譯成內(nèi)核模塊罪裹、編譯進(jìn)內(nèi)核饱普、不編譯。

如果選擇編譯成動(dòng)態(tài)模塊<m>

  • 編譯內(nèi)核過(guò)程中状共,會(huì)有如下輸出:

    LD drivers/hello/built-in.o
    CC [M] drivers/hello/hello.o
    CC drivers/hello/hello.mod.o
    LD [M] drivers/hello/hello.ko
    

如果選擇編譯進(jìn)內(nèi)核<y>

  • 編譯內(nèi)核過(guò)程中套耕,會(huì)有如下輸出:

    CC drivers/hello/hello.o
    LD drivers/hello/built-in.o
    

4.動(dòng)態(tài)模塊加載和卸載

加載模塊使用 insmod 命令,卸載模塊使用 rmmod 命令峡继。

$ insmod hello.ko
$ rmmod hello.ko
#加載和卸載模塊必須具有 root 權(quán)限 箍铲。

對(duì)于可接受參數(shù)的模塊,在加載模塊的時(shí)候?yàn)樽兞抠x值即可鬓椭,卸載模塊無(wú)需參數(shù)颠猴。

$ insmod hello.ko num=8
$ rmmod hello.ko

四关划、帶參數(shù)的內(nèi)核模塊

模塊參數(shù)必須使用 module_param 宏來(lái)聲明,通常放在文件頭部翘瓮。

module_param 需要 3個(gè)參數(shù):變量名稱贮折、類型以及用于 sysfs 入口的訪問(wèn)掩碼。

static int num = 5;
module_param(num, int, S_IRUGO);
  • 內(nèi)核模塊支持的參數(shù)類型有: bool资盅、 invbool调榄、 charp、 int呵扛、 short每庆、 long、 uint今穿、 ushort和 ulong缤灵。
  • 訪問(wèn)掩碼的值在<linux/stat.h>定義, S_IRUGO 表示任何人都可以讀取該參數(shù)蓝晒,但不能修改腮出。
  • 支持傳參的模塊需包含 moduleparam.h 頭文件。

能夠接收參數(shù)的模塊范例

#include <linux/module.h>
#include <linux/init.h>
// moduleparam.h 文件已經(jīng)包含在 module.h 文件中

static int num = 3;
static char *whom = "master";

module_param(num, int, S_IRUGO);
module_param(whom, charp, S_IRUGO);

static int __init hello_init(void)
{
  printk(KERN_INFO "%s, I get %d\n", whom, num); //KERN_INFO 表示這條打印信息的級(jí)別
  return 0;
}

static void __exit hello_exit(void)
{
  printk("I'll be leaving, bye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("luxiaodai");
MODULE_DESCRIPTION("this is my first module");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芝薇,一起剝皮案震驚了整個(gè)濱河市胚嘲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洛二,老刑警劉巖馋劈,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異晾嘶,居然都是意外死亡侣滩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門变擒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人寝志,你說(shuō)我怎么就攤上這事娇斑。” “怎么了材部?”我有些...
    開(kāi)封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵毫缆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乐导,道長(zhǎng)苦丁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任物臂,我火速辦了婚禮旺拉,結(jié)果婚禮上产上,老公的妹妹穿的比我還像新娘。我一直安慰自己蛾狗,他們只是感情好晋涣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著沉桌,像睡著了一般谢鹊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上留凭,一...
    開(kāi)封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天佃扼,我揣著相機(jī)與錄音,去河邊找鬼蔼夜。 笑死兼耀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挎扰。 我是一名探鬼主播翠订,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼遵倦!你這毒婦竟也來(lái)了尽超?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤梧躺,失蹤者是張志新(化名)和其女友劉穎似谁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體掠哥,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巩踏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了续搀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塞琼。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖禁舷,靈堂內(nèi)的尸體忽然破棺而出彪杉,到底是詐尸還是另有隱情,我是刑警寧澤牵咙,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布派近,位于F島的核電站,受9級(jí)特大地震影響洁桌,放射性物質(zhì)發(fā)生泄漏渴丸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谱轨。 院中可真熱鬧戒幔,春花似錦、人聲如沸碟嘴。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)娜扇。三九已至错沃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雀瓢,已是汗流浹背枢析。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刃麸,地道東北人醒叁。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像泊业,于是被迫代替她去往敵國(guó)和親把沼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • make menuconfig過(guò)程解析作者 codercjg 在 28 九月 2015, 5:27 下午 make...
    codercjg閱讀 955評(píng)論 0 1
  • 1 Linux 內(nèi)核模塊簡(jiǎn)介 Linux 內(nèi)核是一個(gè)十分龐大的系統(tǒng)吁伺,如何能夠?yàn)槠涫萆硪牵喼七m合自己應(yīng)用場(chǎng)景的 li...
    守拙圓閱讀 1,074評(píng)論 0 2
  • 一、Linux內(nèi)核模塊簡(jiǎn)介 1.1 Linux內(nèi)核模塊介紹 Linux內(nèi)核的整體結(jié)構(gòu)已經(jīng)非常龐大篮奄,而其包含的組件也...
    konishi5202閱讀 2,876評(píng)論 0 4
  • 本人在開(kāi)發(fā)Android Nfc POS之初捆愁,探索調(diào)試了一番驅(qū)動(dòng),目前在Nexus 5X 7.1.1上已經(jīng)調(diào)成窟却,之...
    Eric_Y15閱讀 1,595評(píng)論 0 3
  • 告誡自己—— 幫助被教者最好的方式昼丑, 并非是“修正TA”。 而是在TA身上找到最大的優(yōu)點(diǎn)夸赫。 約翰.麥斯威爾把這個(gè)方...
    小旅閱讀 629評(píng)論 0 0