U-Boot移植與總結(jié)P2020篇

本文章首發(fā)地址:https://www.lgfccl.xyz 隨時down 機,轉(zhuǎn)載注明出處謝謝

UBOOT 概述

1 U-Boot簡介

U-Boot堕扶,全稱 Universal Boot Loader南用,是遵循 GPL 條款的開放源碼項目李剖。從 FADSROM尖飞、8xxROM琉挖、PPCBOOT 逐步發(fā)展演化而來玻侥。其源碼目錄决摧、編譯形式 與 Linux 內(nèi)核很相似,事實上,不少 U-Boot 源碼就是相應(yīng)的 Linux 內(nèi)核源程序的簡化掌桩,尤其是一些設(shè)備的驅(qū)動程序边锁,如網(wǎng)絡(luò)設(shè)備、flash拘鞋、ddr等砚蓬,這從 U-Boot 源碼的注釋中能體現(xiàn)這一點。

U-Boot 不僅僅支持嵌入式 Linux 系統(tǒng)的引導(dǎo)盆色,它還支持如NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS 嵌入式OS灰蛙。硬件支持包括 MIPS、 x86隔躲、ARM摩梧、Powerpc、Zynq 等諸多常用處理器宣旱。 這兩個特點正是 U-Boot 項目的開發(fā)目標(biāo)仅父,即支持盡可能多的嵌入式處理器和嵌 入式操作系統(tǒng)。
這個項目起源于 Magnus Damm.[1] 在 8xx PowerPC 架構(gòu)下寫的引導(dǎo)加載程序8xxROM浑吟。1999 年十月笙纤,Wolfgang Denk 將項目移轉(zhuǎn)到 SourceForge.net,但 SourceForge.net 不允許數(shù)字開頭的項目名稱组力,所以改名為 PPCBoot省容。PPCBoot 在 2000年 7 月 19 日第一次公開發(fā)布 0.4.1 版。也正是因此燎字,U-Boot對PPC支持最為豐富腥椒。

  • 選擇 u-boot 的理由:

? 開放源碼
? 支持多種嵌入式OS,如 Linux候衍、NetBSD笼蛛、VxWorks、QNX等
? 支持多種處理器架構(gòu)蛉鹿,如PowerPC滨砍、ARM、x86妖异、MIPS惋戏、XScale、Zynq(ARM);
? 較高的可靠性和穩(wěn)定性;
? 豐富的設(shè)備驅(qū)動源碼随闺,如串口日川、以太網(wǎng)、SDRAM矩乐、FLASH等;
? 較為豐富的開發(fā)調(diào)試文檔與強大的網(wǎng)絡(luò)技術(shù)支持;

2 目錄結(jié)構(gòu)

  • board 目標(biāo)板相關(guān)文件龄句,主要包含SDRAM回论、FLASH驅(qū)動;
  • common 獨立于處理器體系結(jié)構(gòu)的通用代碼分歇,如內(nèi)存大小探測與故障檢測傀蓉;
  • cpu 與處理器相關(guān)的文件。如mpc8xx子目錄下含串口职抡、網(wǎng)口葬燎、LCD驅(qū)動及中斷初始化等文件;
  • driver 通用設(shè)備驅(qū)動缚甩,如CFI FLASH驅(qū)動(目前對INTEL FLASH支持較好)
  • doc U-Boot的說明文檔谱净;
  • examples可在U-Boot下運行的示例程序;如hello_world.c,timer.c擅威;
  • include U-Boot頭文件壕探;尤其configs子目錄下與目標(biāo)板相關(guān)的配置頭文件是移植過程中經(jīng)常要修改的文件;
  • lib_xxx 處理器體系相關(guān)的文件郊丛,如lib_ppc, lib_arm目錄分別包含與PowerPC李请、ARM體系結(jié)構(gòu)相關(guān)的文件;
  • net 與網(wǎng)絡(luò)功能相關(guān)的文件目錄厉熟,如bootp,nfs,tftp导盅;
  • post 上電自檢文件目錄。尚有待于進一步完善揍瑟;
  • rtc RTC驅(qū)動程序白翻;
  • tools 用于創(chuàng)建U-Boot S-RECORD和BIN鏡像文件的工具;


以上關(guān)于目錄結(jié)構(gòu)的說明只適應(yīng)u-boot-2010.06之前版本月培。u-boot-2010.06之后目錄結(jié)構(gòu)改變
cpu與lib_arch合二為一嘁字,命名arch
增加include folder
分離出通用庫文件夾lib

3 主要功能

U-Boot 可支持的主要功能如下:

  • 系統(tǒng)引導(dǎo),Linux 支持最為強勁;
  • 支持NFS掛載恩急、RAMDISK(壓縮或非壓縮)形 式的根文件系統(tǒng);
  • 支持NFS掛載杉畜、從FLASH中引導(dǎo)壓縮或非壓縮系統(tǒng)內(nèi)核;
  • 支持目標(biāo)板環(huán)境參數(shù)多種存儲方式,如FLASH衷恭、NVRAM此叠、EEPROM;
  • CRC32 校驗,可校驗 FLASH 中內(nèi)核随珠、RAMDISK 鏡像文件是否完好;
  • 設(shè)備驅(qū)動 串口灭袁、SDRAM、FLASH窗看、以太網(wǎng) 茸歧、USB、PCMCIA显沈、PCI软瞎、RTC 等驅(qū)動支持;
  • 上電自檢功能 SDRAM逢唤、FLASH 大小自動檢測;SDRAM 故障檢測;CPU型號;
  • 特殊功能 XIP 內(nèi)核引導(dǎo);

二 UBOOT移植分析與流程

大多數(shù)BootLoader都分為stage1和stage2兩大部分,U-boot也不例外涤浇。依賴于cpu體系結(jié)構(gòu)的代碼(如設(shè)備初始化代碼等)通常都放在stage1且可以用匯編語言來實現(xiàn)鳖藕,而stage2則通常用C語言來實現(xiàn),這樣可以實現(xiàn)復(fù)雜的功能只锭,而且有更好的可讀性和移植性著恩。

1、 stage1(start.s代碼結(jié)構(gòu))
? U-boot的stage1代碼通常放在start.s文件中蜻展,它用匯編語言寫成喉誊,其主要代碼部分如下:
(1) 定義入口。由于一個可執(zhí)行的image必須有一個入口點纵顾,并且只能有一個全局入口裹驰,通常這個入口放在rom(Flash)的0x0地址,因此片挂,必須通知編譯器以使其知道這個入口幻林,該工作可通過修改連接器腳本來完成。
(2)設(shè)置異常向量(exception vector)音念。
(3)設(shè)置CPU的速度沪饺、時鐘頻率及中斷控制寄存器
(4)初始化內(nèi)存控制器 闷愤。
(5)將rom中的程序復(fù)制到ram中整葡。
(6)初始化堆棧
(7)轉(zhuǎn)到ram中執(zhí)行讥脐,該工作可使用指令ldrpc來完成遭居。
2、 stage2(C語言代碼部分)
lib_arm/board.c中的start armboot是C語言開始的函數(shù)旬渠,也是整個啟動代碼中C語言的主函數(shù)俱萍,同時還是整個u-boot(armboot)的主函數(shù),該函數(shù)主要完成如下操作:
(1)調(diào)用一系列的初始化函數(shù)告丢。
(2)初始化flash設(shè)備枪蘑。
(3)初始化系統(tǒng)內(nèi)存分配函數(shù)。
(4)如果目標(biāo)系統(tǒng)擁有nand設(shè)備岖免,則初始化nand設(shè)備岳颇。
(5)如果目標(biāo)系統(tǒng)有顯示設(shè)備,則初始化該類設(shè)備颅湘。
(6)初始化相關(guān)網(wǎng)絡(luò)設(shè)備话侧,填寫ip,c地址等。
(7)進入命令循環(huán)(即整個boot的工作循環(huán))闯参,接受用戶從串口輸入的命令瞻鹏,然后進行相應(yīng)的工作术羔。

1 獲取U-Boot源代碼

如下舉例,由于此服務(wù)器基本處于爹媽不維護狀態(tài)乙漓,所以建議直接瀏覽器下載壓縮包级历,或者wget下載,如果用git clone下載很慢叭披。

  • 官方版本:這個版本是U-Boot開源社區(qū)維護的寥殖。
  • Powerpc私有Git:這個版本是Freescale(被NXP收購)自己維護的目前已經(jīng)不更新,不過是最好的選擇涩蜘。
  • Yocto SDK 工具:bitbake -c compile -f u-boot 獲取嚼贡,不建議 SDK占用資源大(50G),且編譯基于bitbake同诫,bitbake又基于python開發(fā)效率不高粤策,對于嵌入式編成,優(yōu)選利用交叉編譯環(huán)境误窖。
  > wget http://git.freescale.com/git/cgit.cgi/auto/u-boot.git/snapshot/u-boot-2016.01_bsp14.0.tar.gz
  > tar xvf u-boot-2016.01_bsp14.0.tar.gz
  > cd u-boot-2016.01_bsp14.0
  > ls -alh 
  • 如上獲取了官方支持的最新的U-Boot源代碼叮盘,接下來獲取交叉編譯工具(不通內(nèi)核架構(gòu)工具不一樣)方式也有3種:
   source ./fsl-setup-poky -h 查看支持的參考Demo板卡
   source ./fsl-setup-poky -m 選擇你的處理器如P2020RDB 
   bitbake fsl-toolchain
   cd build_<machine>_release/tmp/deploy/sdk
   ./fsl-networking-eglibc-<host-system>-<core>-toolchain-<release>.sh

默認(rèn)安裝/opt/下直接允許即可

2 P2020芯片U-Boot配置

2.1 獲取Demo板卡參考配置

P2020芯片原Freescale出過兩個Demo板卡想际,我們?nèi)∑渲蠵2020RDB-PC 進行參考即可

  > cd u-boot-2016.01_bsp14.0
  > source /opt/fsl-networking/QorIQ-SDK-V1.6/environment-setup-ppce500v2-fsl-linux-gnuspe;
  > unset LDFLAGS;
  > make distclean;make P2020RDB-PC_config;make -j8;
  > powerpc-fsl-linux-gnuspe-objdump -j .text -l -C -S u-boot >uboot.map;

到此培漏,你應(yīng)該可以獲得bin,大小根據(jù)頭文件include/configs/p1_p2_rdb_pc.h里的 #define CONFIG_SYS_TEXT_BASE 0xeff40000決定胡本,這個地址到0xefffffff正好是768K大小牌柄。這里你看你會有疑問,e500V2架構(gòu)Core第一條指令不是去0xFFFFFFFC去取指令嗎打瘪,且一般是跳轉(zhuǎn)到前4K Page Size處友鼻,沒錯這里就是由于兩個default決定的了傻昙。
請參考:P2020RM的4.3.3章節(jié):Boot page tranlation,E500CORERM 1.5.1 章節(jié) Initial Instruction Fetch
? 我們這里不展開討論TLB以及MMU闺骚,LAW的概念,后續(xù)我會根據(jù)時間繼續(xù)進行介紹妆档。

2.2 自定義板卡配置

如上僻爽,你已經(jīng)獲取了u-boot.bin,通過code warrior jtag或者usb code warrior jtag 燒寫程序到Nor的0xfff40000地址即可啟動贾惦,可能是亂碼胸梆,根據(jù)至于code warrior 的永久license和如何根據(jù)自己Nor Flash生成tcl敦捧,生成Nor的自定義型號,這里不展開討論碰镜,后續(xù)看時間專門出一片code warrior 工具使用介紹(自己看help也夠用了)兢卵,不過這個cw工具官方已經(jīng)不在維護,建議不要過度依賴绪颖。cw的后臺server是ccs服務(wù)程序秽荤,這個程序又可以寫一片博客了,看時間進行總結(jié)吧柠横。

  • 這里指列舉幾個看你修改的文件窃款,請自行修改:

    Include/configs/p1_p2_rdb_pc.h --->修改sys clk,ddr clk牍氛,nor law reg晨继,ddr2(3) 參數(shù)等。

    • board/freescale/p1_p2_rdb/下的law.c tab.c p1_p2_rdb.c 這三個文件就是tlb和law修改搬俊,按需修改紊扬。
    • 期間可能需要修改Makefile,如編譯遇到libgcc問題唉擂,請自行g(shù)oogle 搜nxp論壇即可珠月。
  • 到此U-Boot P2020自定義板卡移植結(jié)束,當(dāng)然前提是你板子的硬件設(shè)計已經(jīng)OK楔敌,比如啟動位置啤挎,各種clk配置陪好。

3 U-Boot 啟動分析

本部分涉及的代碼非常多卵凑,所以只能對關(guān)鍵代碼進行解釋庆聘,還有更多部分涉 及到 POWERPC 體系結(jié)構(gòu)、MMU 工作原理等勺卢,這里對這些內(nèi)容不再敘述伙判,但是 使用U-Boot過程中,上述內(nèi)容是必備的黑忱,可以參考《POWERPC 體系結(jié)構(gòu)》與 《MMU 工作原理》等手冊相關(guān)內(nèi)容宴抚。

3.1 入口函數(shù)

打開文件,vim arch/powerpc/cpu/mpc85xx/start.S 文件開始定義了:
CPU 復(fù)位后做了三件事情甫煞,1清寄存器菇曲、2設(shè)置異常向量表、3設(shè)置更多更大TLB供CPU看見地址:

/*
  * e500 Startup -- after reset only the last 4KB of the effective
  * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
  * section is located at THIS LAST page and basically does three
  * things: clear some registers, set up exception tables and
  * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
  * continue the boot procedure.

  * Once the boot rom is mapped by TLB entries we can proceed
  * with normal startup.
  *
  */

     .section .bootpg,"ax"
     .globl _start_e500

 _start_e500:
 /* Enable debug exception */
     li  r1,MSR_DE
     mtmsr   r1

     /*
      * If we got an ePAPR device tree pointer passed in as r3, we need that
      * later in cpu_init_early_f(). Save it to a safe register before we
      * clobber it so that we can fetch it from there later.
      */
     mr  r24, r3

接下來就是根據(jù)不同芯片的ERRATUM 進行操作抚吠,和關(guān)閉L2常潮,L1禁止cache的操作,源碼很簡單這里不粘貼楷力,只撿最關(guān)鍵幾點喊式,接下來是初始化異常向量表孵户,告訴CPU出現(xiàn)下列異常應(yīng)該怎么辦:

/* Interrupt vectors do not fit in minimal SPL. */
 #if !defined(MINIMAL_SPL)
     /* Setup interrupt vectors */
     lis r1,CONFIG_SYS_MONITOR_BASE@h
     mtspr   IVPR,r1

     li  r4,CriticalInput@l
     mtspr   IVOR0,r4    /* 0: Critical input */
     li  r4,MachineCheck@l
     mtspr   IVOR1,r4    /* 1: Machine check */
     li  r4,DataStorage@l
     mtspr   IVOR2,r4    /* 2: Data storage */
     li  r4,InstStorage@l
     mtspr   IVOR3,r4    /* 3: Instruction storage */
     li  r4,ExtInterrupt@l
     mtspr   IVOR4,r4    /* 4: External interrupt */
     li  r4,Alignment@l
     mtspr   IVOR5,r4    /* 5: Alignment */
     li  r4,ProgramCheck@l
     mtspr   IVOR6,r4    /* 6: Program check */
     li  r4,FPUnavailable@l
     mtspr   IVOR7,r4    /* 7: floating point unavailable */
     li  r4,SystemCall@l
     mtspr   IVOR8,r4    /* 8: System call */
     /* 9: Auxiliary processor unavailable(unsupported) */
     li  r4,Decrementer@l
     mtspr   IVOR10,r4   /* 10: Decrementer */
     li  r4,IntervalTimer@l
     mtspr   IVOR11,r4   /* 11: Interval timer */
     li  r4,WatchdogTimer@l
     mtspr   IVOR12,r4   /* 12: Watchdog timer */
     li  r4,DataTLBError@l 等

直至后就是cache 當(dāng)臨時stack供C語言代碼運行,新tlb 映射岔留,u-boot C代碼出事后ddr夏哭,基本設(shè)置,copy自身代碼到ram(ddr)等等献联。這部分代碼基本不會出什么問題方庭,后續(xù)就到了最關(guān)鍵的relocate 技術(shù)了。

3.2 U-Boot中的Relocate技術(shù)

所謂代碼重定位技術(shù)就是對于鏈接時地址已經(jīng)固定的數(shù)據(jù)段與代碼段酱固,在進行代碼搬移后械念,需要對這些數(shù)據(jù)段與代碼段的地址進行修改,使程序能夠正確尋 址的技術(shù)运悲。在 bootloader 中龄减,通常有 GOT與 PLT兩種實現(xiàn)方法。其基本原理就是利 用數(shù)據(jù)段與代碼段的相對位置不變實現(xiàn)的班眯。代碼重定位技術(shù)也應(yīng)用于 OS 中希停,OS 的加載器也實現(xiàn)了 PIC凉夯,這里不做算法研究盛龄。
我們知道對于全局變量的訪問讨阻,首先要獲取該變量的全局地址仁烹,而這個地址是編譯鏈接時生成的一個地址,對于沒有-fpic 選項編譯的程序句惯,此值是一個靜態(tài)的地址豫喧,當(dāng)程序從 flash 重新定位到 ram 后靴跛,訪問的地址仍然在 Flash 中诊霹,那 么如何讀寫呢?

這就需要一種機制來保證獲取的全局變量的地址是一個動態(tài)的值羞延,也是說當(dāng) 程序重定位到 RAM 中后,這個地址也需要隨之修正脾还。而 U-boot 正是將所有全局 符號的地址保存在一個表中 GOT伴箩,程序訪問變量時先從這個表中動態(tài)獲取該符 號的地址,而這個地址在重定位時已經(jīng)修正過了鄙漏,從而保證能從重定位后的地址 處正確訪問全局變量嗤谚。

總的來講,U-Boot 依靠維護 GOT 表來實現(xiàn)怔蚌,在 GOT 表中存放一些全局 label表巩步,這些表項記錄重要的地址。運行在 Flash 時媚创,GOT 表中存放的是編譯時 全局 label 的值(地址);當(dāng) U-Boot 運行時檢測 RAM 大小進行代碼搬運之后,利用代碼搬運前后產(chǎn)生的地址偏移對(相對偏移)GOT表中的各個表項值進行更新渗钉,使其記錄 RAM 中的相應(yīng)的地址。 這樣代碼運行時不會出現(xiàn)代碼/變量地址出錯的問題钞钙。

  • 代碼運行到 in_ram之后首先進行GOT轉(zhuǎn)換鳄橘,其實核心思想就是程序的編譯后的指令,
     .globl  in_ram
 in_ram:

     /*
      * Relocation Function, r12 point to got2+0x8000
      *
      * Adjust got2 pointers, no need to check for 0, this code
      * already puts a few entries in the table.
      */
     li  r0,__got2_entries@sectoff@l
     la  r3,GOT(_GOT2_TABLE_)
     lwz r11,GOT(_GOT2_TABLE_)
     mtctr   r0
     sub r11,r3,r11
     addi    r3,r3,-4
 1:  lwzu    r0,4(r3)
     cmpwi   r0,0
     beq-    2f
     add r0,r0,r11
     stw r0,0(r3)
 2:  bdnz    1b

其實可以這么理解芒炼,一旦有全局變量的地方都需要進行地址換算瘫怜,這個U-boot原始位置與最新位置,在調(diào)用relocate函數(shù)之前已經(jīng)算好本刽,并傳參數(shù)給匯編代碼鲸湃。其實就是公式:
New GOTPTR-Old GOTPTR=Destination Address+(Offset);
New GOTPTR-Old GOTPTR=UBoot目的地址-UBoot源地址;
這里Offset可以是負(fù)數(shù)子寓,具體參考Uboot源代碼暗挑。

/*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
  * This "function" does not return, instead it continues in RAM
  * after relocating the monitor code.
  *
  * r3 = dest
  * r4 = src
  * r5 = length in bytes
  * r6 = cachelinesize
  */
     .globl  relocate_code
 relocate_code:
     mr  r1,r3       /* Set new stack pointer        */
     mr  r9,r4       /* Save copy of Init Data pointer   */
     mr  r10,r5      /* Save copy of Destination Address */

     GET_GOT
 #ifndef CONFIG_SPL_SKIP_RELOCATE
     mr  r3,r5               /* Destination Address  */
     lis r4,CONFIG_SYS_MONITOR_BASE@h        /* Source      Address  */
     ori r4,r4,CONFIG_SYS_MONITOR_BASE@l
     lwz r5,GOT(__init_end)
     sub r5,r5,r4
     li  r6,CONFIG_SYS_CACHELINE_SIZE        /* Cache Line Size  */

     /*
      * Fix GOT pointer:
      *
      * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
      *
      * Offset:
      */
     sub r15,r10,r4

     /* First our own GOT */
     add r12,r12,r15
       */
     sub r15,r10,r4

     /* First our own GOT */
     add r12,r12,r15
     /* the the one used by the C code */
     add r30,r30,r15

4 U-Boot主要命令

U-Boot發(fā)展到現(xiàn)在,已經(jīng)接近 linux 系統(tǒng)斜友。它具備了豐富的命令炸裆,可以幫助 用戶實現(xiàn)調(diào)試與系統(tǒng)環(huán)境設(shè)置等。下面我僅介紹下幾個常用的命令鲜屏。1烹看、HELP 命令
? 在終端輸入 help 命令,將會顯示系統(tǒng)支持的命令及簡要說明洛史。

  • help == ?

    ? - alias for 'help'
    base - print or set address offset
    bdinfo - print Board Info structure
    boot - boot default, i.e., run 'bootcmd' - boot default, i.e., run 'bootcmd'
    flinfo. - print flash bank and erase info

    tftp - download image from serverip via net

    rx - receive by xmodel

    setenv editenv savenv and so on

總結(jié)

U-BOOT 是一個非常好用的嵌入式 bootloader惯殊。它已經(jīng)成為目前嵌入式linux的御用boot,內(nèi)容非常豐富也殖,但結(jié)構(gòu)混亂土思,看下common里面的board_r和board_f就能可見一斑,本文只是從整體上對其啟動部分原理做了簡要陳述忆嗜。關(guān)于 u-boot 程序開發(fā)浪漠,已經(jīng)超出了 u-boot 啟動部分內(nèi)容,并且需要很多外圍硬件的相關(guān)知識霎褐,所以沒有進行講解址愿。

? 本文參 考了網(wǎng)絡(luò)相關(guān)文章,并進行了實踐驗證冻璃,以及Powerpc 相關(guān)手冊响谓,但由于本人技術(shù)水平有限,難免存在 理解錯誤省艳,望大家指正娘纷。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跋炕,隨后出現(xiàn)的幾起案子赖晶,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遏插,死亡現(xiàn)場離奇詭異捂贿,居然都是意外死亡,警方通過查閱死者的電腦和手機胳嘲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門厂僧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人了牛,你說我怎么就攤上這事颜屠。” “怎么了鹰祸?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵甫窟,是天一觀的道長。 經(jīng)常有香客問我蛙婴,道長粗井,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任敬锐,我火速辦了婚禮背传,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘台夺。我一直安慰自己径玖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布颤介。 她就那樣靜靜地躺著梳星,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滚朵。 梳的紋絲不亂的頭發(fā)上冤灾,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音辕近,去河邊找鬼韵吨。 笑死,一個胖子當(dāng)著我的面吹牛移宅,可吹牛的內(nèi)容都是我干的归粉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼漏峰,長吁一口氣:“原來是場噩夢啊……” “哼糠悼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浅乔,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤倔喂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體席噩,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡班缰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了班挖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲁捏。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡芯砸,死狀恐怖萧芙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情假丧,我是刑警寧澤双揪,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站包帚,受9級特大地震影響渔期,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渴邦,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一疯趟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谋梭,春花似錦信峻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隘庄,卻和暖如春踢步,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丑掺。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工获印, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人街州。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓兼丰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親菇肃。 傳聞我的和親對象是個殘疾皇子地粪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

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

  • [TOC] Android 簡介 Android 操作系統(tǒng)是基于Linux內(nèi)核, Google使用Linux內(nèi)核構(gòu)...
    Joe_HUST閱讀 8,904評論 0 9
  • 轉(zhuǎn)發(fā)http://www.reibang.com/p/439ce15436c1 Android 簡介 Andro...
    wholesky閱讀 1,302評論 0 1
  • 姓名:吳兆陽 學(xué)號:14020199009 轉(zhuǎn)自韋東山 嵌牛導(dǎo)讀:對嵌入式初學(xué)者,沒有足夠的視野選擇一個合適投入方...
    吳兆陽閱讀 2,380評論 0 4
  • 學(xué)習(xí)stm32gpio 學(xué)習(xí)linux 程序員的三大方向 程序員的方向琐谤,一般可以分為3類:專業(yè)領(lǐng)域蟆技、業(yè)務(wù)領(lǐng)域、操作...
    王公民閱讀 742評論 0 3
  • 我們知道,bootloader是系統(tǒng)上電后最初加載運行的代碼质礼。它提供了處理器上電復(fù)位后最開始需要執(zhí)行的初始化代碼旺聚。...
    我是嘻哈大哥閱讀 5,288評論 0 2