1. 程式人生 > >【嵌入式Linux學習七步曲之第三篇 Linux系統bootlaoder移植】全面解析PowerPC架構下的扁平裝置樹FDT

【嵌入式Linux學習七步曲之第三篇 Linux系統bootlaoder移植】全面解析PowerPC架構下的扁平裝置樹FDT

全面解析PowerPC架構下的扁平裝置樹FDT


Sailor_forever  sailing_9806#163.com

(本原創文章發表於Sailor_forever 的個人blog,未經本人許可,不得用於商業用途。任何個人、媒體、其他網站不得私自抄襲;網路媒體轉載請註明出處,增加原文連結,否則屬於侵權行為。如有任何問題,請留言或者發郵件給[email protected])
http://blog.csdn.net/sailor_8318/archive/2009/12/26/5078959.aspx



【摘要】本文以MPC8378處理器、Linux2.6.25核心及U-boot1.3.4為例,講述瞭如何在PowerPC架構下使用FDT。首先介紹了引入FDT的背景,接著詳細介紹了FDT的組成及製作。最後介紹了U-boot及核心如何支援FDT。


【關鍵字】PowerPC,MPC8378,DTS,DTB,FDT,device node,property,compatible


1    背景    2
2    裝置樹的描述方式    2
2.1    root Node    3
2.2    chosen    3
2.3    cpus Node    3
2.4    System Memory    5
2.5    Devices    5
2.5.1    Compatible屬性    6
2.5.2    Addressing    6
2.6    Interrupts and Interrupt Controllers    7
3    如何製作裝置樹映像    8
3.1    輸入    8
3.2    輸出    9
3.3    命令格式    9
4    裝置樹的傳遞途徑    9
4.1    U-boot對FDT的支援    10
4.2    如何配置FDT    10
4.3    如何傳遞裝置樹    10
5    核心如何解析裝置樹    12
6    裝置樹對驅動設計產生的影響    15



1    背景
通常情況下,桌面機和伺服器可以相容大部分軟體。最好的結果就是當新增新硬體時,無需重新編譯Linux核心。標準的韌體介面可以保證bootloader將正確的引數傳遞給核心。PC可以採用bios,PowerPC and Sparc採用Open-Firmware介面。但是對於嵌入式系統,軟體差別太大,核心本身也是定製的,bootloader只需要傳遞很少的引數,因為大部分資訊都是硬編碼在系統的配置中的。這樣同一個核心映像很難同時使用在多個不同的平臺上。

早期的PowerPC平臺採用特定的資料結構bd_info來傳遞引數,其定義在include/asm-ppc/ppcboot.h,#define來定義特定平臺的資料域,但並沒有什麼資訊來說明當前採用的是那個bd_info結構,所以必須保證在核心和bootloader中同時更新,以便保持一致。

合併32-bit (arch/ppc) 和 64-bit (arch/ppc64) PowerPC的同時,決定重新整理韌體介面,建立新的目錄arch/powerpc,這裡所有的平臺必須向核心提供Open Firmware風格的裝置樹,以便核心啟動時可以獲得當前平臺的硬體配置。

2    裝置樹的描述方式
簡單的說裝置書是一種描述硬體配置資訊的資料結構,包括CPU,記憶體,匯流排及相關外設。核心啟動時可以解析這些資訊,以此決定如何配置核心及載入那些驅動。該資料結構有一個單一的根節點“/”。每個節點有個名字並可以包含多個子節點。資料的格式遵循IEEE standard 1275。

Device tree source (.dts)採用一種易編輯的文字方式來表達裝置樹,device tree compiler tool (dtc)將.dts轉換成binary device tree blob(.dtb)。裝置樹並不是控制系統裝置的唯一方法,比如核心對USB和PCI已經有非常方便的檢測機制。

/ { // the root node
    an-empty-property;
   
    a-child-node {
    array-prop = <0x100 32>;
    string-prop = "hello, world";
    };
   
    another-child-node {
    binary-prop = [0102CAFE];
    string-list = "yes","no","maybe";
    };
};
Figure 1: Simple example of the .dts file format

2.1    root Node
裝置樹的起點是根節點,Model和compatible屬性指明瞭當前平臺的名字,格式為<mfg>,<board>:
Mfg是vendor,board是板子模型

Compatible屬性不一定非得要,但是當兩個系統在硬體配置上基本一致時,這個引數可以用於辨別當前系統。
/ {
    model = "fsl,mpc8377rdb";
    compatible = "fsl,mpc8377rdb";
    #address-cells = <1>;
    #size-cells = <1>;

    aliases {
        ethernet0 = &enet0;
        ethernet1 = &enet1;
        serial0 = &serial0;
        serial1 = &serial1;
        //pci0 = &pci0;
    };
    // Child nodes go here
};
Figure 3: Example system root node

2.2    chosen
此節點並不真正代表裝置節點,而是一些虛擬的由bootloader傳遞給核心的一些引數,包括bootargs(cmdline)和initrd等。一般由bootloader在啟動核心時新增此節點。

2.3    cpus Node
cpus節點是root節點的子節點,對於多核CPU系統,每個CPU有一個子節點。Cpus節點並不需要特別的特性,但是通常習慣指定#address-cells = <1>和#size-cells = <0>,這指定了各個CPU節點的reg屬性的格式,其用於編碼物理CPU號。

CPU節點的格式為

[email protected],model屬性描述CPU型別,其他的是時鐘頻率及cache 相關屬性。
cpus {
    #cpus = <1>;
    #address-cells = <1>;
    #size-cells = <0>;

    PowerPC,[email protected] {
        device_type = "cpu";
        model = "PowerPC, 8377";
        reg = <0x0>;
        d-cache-line-size = <32>;
        i-cache-line-size = <32>;
        d-cache-size = <32768>;
        i-cache-size = <32768>;
        timebase-frequency = <0>;
        bus-frequency = <0>;
        clock-frequency = <0>;
    };
};
Figure 4: cpus node

cpus {
    #cpus = <2>;
    #address-cells = <1>;
    #size-cells = <0>;

    PowerPC,
[email protected]
{
        device_type = "cpu";
        reg = <0>;
        d-cache-line-size = <20>;    // 32 bytes
        i-cache-line-size = <20>;    // 32 bytes
        d-cache-size = <8000>;        // L1, 32K
        i-cache-size = <8000>;        // L1, 32K
        timebase-frequency = <0>;    // 33 MHz, from uboot
        bus-frequency = <0>;        // From uboot
        clock-frequency = <0>;        // From uboot
        32-bit;
        linux,boot-cpu;
    };
    PowerPC,
[email protected]
{
        device_type = "cpu";
        reg = <1>;
        d-cache-line-size = <20>;    // 32 bytes
        i-cache-line-size = <20>;    // 32 bytes
        d-cache-size = <8000>;        // L1, 32K
        i-cache-size = <8000>;        // L1, 32K
        timebase-frequency = <0>;    // 33 MHz, from uboot
        bus-frequency = <0>;        // From uboot
        clock-frequency = <0>;        // From uboot
        32-bit;
    };
};
2.4    System Memory
描述系統記憶體的節點成為memory node,其為root節點的子節點,通常只用一個memory節點描述系統所有的記憶體範圍,reg屬性用來定義當前可用的各個memory範圍。
memory {
    device_type = "memory";
    reg = <0x00000000 0x40000000>;    // 256MB at 0
};
Figure 5: Memory node

2.5    Devices
一系列節點用於描述系統匯流排及裝置,每個匯流排及裝置在裝置樹種都有自己的節點。處理器的local bus通常直接作為根節點的子節點,附著在local bus上的Devices and bridges將作為其子節點。
下圖顯示的PLB bus上的裝置包括interrupt controller, an Ethernet device,
及 OPB bridge,OPB總線上有serial devices and a Flash device
plb {
    compatible = "simple-bus";
    #address-cells = <1>;
    #size-cells = <1>;
    ranges;
    UIC0: interrupt-controller {
    compatible = "ibm,uic-440gp",
    "ibm,uic";
    interrupt-controller;
    #interrupt-cells = <2>;
    };
    [email protected] {
    compatible = "ibm,emac-440gp";
    reg = <0x20000 0x70>;
    interrupt-parent = <&UIC0>;
    interrupts = <0 4>;
    };
    opb {
        compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <1>;
        ranges = <0x0 0xe0000000
        0x20000000>;
        [email protected] {
        compatible = "ns16550";
        reg = <0x0 0x10>;
        interrupt-parent = <&UIC0>;
        interrupts = <1 4>;
        };
        [email protected] {
        compatible = "ns16550";
        reg = <0x10000 0x10>;
        interrupt-parent = <&UIC0>;
        interrupts = <2 4>;
        };
        [email protected] {
        compatible = "amd,s29gl256n",
        "cfi-flash";
        reg = <0x1ff00000 0x100000>;
        };
    };
};
Figure 6: Simple System Device Hierarchy

2.5.1    Compatible屬性
幾乎每個裝置都有compatible屬性,OS利用此關鍵字來確定node所描述的裝置,通常compatible字串的格式如下:
<manufacturer>,<part-num>
對於每個特定的compatible值,需要為該裝置定義一個device tree binding。
有時候compatible是一系列字串,如果某個裝置在暫存器級別和某個舊裝置相容,則可以同時指定多個字串,這樣OS就知道這兩個驅動是相容的。通常該裝置的compatible字串在前,然後是相容的舊裝置的字串。

2.5.2    Addressing
裝置地址由reg屬性指定,其為一系列cell單元。格式如下:
reg = <base1 size1 [base2 size2 [...]]>;
每個reg的實際大小有父節點的#address-cells and #size-cells屬性決定,#address-cells是用來指定base address基地址的cells個數,#size-cells是用來指定region size的cells個數。Reg所使用的cells個數必須是(#address-cells + #size-cells)的倍數。

Reg定義的是bus address,而非system address,bus address是裝置依賴的總線上的相對地址,或者更專業的說bus address是相對於父節點的。

Ranges屬性可以將bus address對映到父節點一級,格式如下:
ranges = <addr1 parent1 size1 [...]>;
addr為匯流排地址,寬度為#address-cells,parent是父節點總線上的地址,寬度為父節點的#address-cells,size寬度為父節點的#size-cells。但是當匯流排地址和父節點地址對映關係為1:1時,可以簡化對映關係:
ranges;

在本示例中,Flash在OPB總線上的地址為0x1ff00000,但OPB匯流排中,PLB bus address 0xe0000000 對映到了0x0000000 on the OPB bus,因此Flash裝置的地址為0xfff00000。

2.6    Interrupts and Interrupt Controllers
裝置樹的自然佈局很方便描述裝置間的簡單關係,但是中斷系統是個比較複雜的例子。可以將serial device描述為OPB匯流排的子節點,但也可以說其是interrupt controller裝置的子節點,那麼如何描述呢?目前的規範是,自然樹的結構適用於描述那些定址和控制裝置的主要介面,次要連線可以通過phandle屬性來描述相互之間的關係,其為節點中的一個指標,指向另一個節點。

對於中斷連線,裝置節點利用interrupt-parent and interrupts屬性來描述到interrupt controller的連線。interrupt-parent是指向描述interrupt controller節點的指標,interrupts是interrupt controller可以觸發的一系列中斷訊號。

Interrupt controller節點必須定義空屬性interrupt-controller,同時定義#interrupt-cells,確定幾個cells描述一箇中斷訊號。由於Interrupt controller節點在裝置樹種被其他節點連結,因此必須定義屬性linux,phandle = <xx>。

對於大部分SOC系統,通常只有一個interrupt controller,,但是多個interrupt controller之間可以級聯。interrupt controller和裝置之間的關係就形成了interrupt tree。

對於serial device node,interrupt-parent屬性定義了其在中斷樹中與其父節點的關係。Interrupts屬性定義了特定的中斷標識,其格式取決於中斷樹中父節點的#interrupt-cells,通常#interrupt-cells為2,這樣第一個值表示interrupt controller中的硬體中斷編號,第二個值表示中斷觸發方式:電平觸發或者邊沿觸發。

/* IPIC
 * interrupts cell = <intr #, sense>
 * sense values match linux IORESOURCE_IRQ_* defines:
 * sense == 8: Level, low assertion
 * sense == 2: Edge, high-to-low change
 */
[email protected] {
    linux,phandle = <700>;
    interrupt-controller;
    #address-cells = <0>;
    #interrupt-cells = <2>;
    reg = <700 100>;
    built-in;
    device_type = "ipic";
};

[email protected] {
    device_type = "serial";
    compatible = "ns16550";
    reg = <4500 100>;
    clock-frequency = <0>;
    interrupts = <9 8>;
    interrupt-parent = <700>;
};

3    如何製作裝置樹映像
Device tree compiler(dtc)負責將文字格式的裝置樹轉換成OS可以識別的格式。
3.1    輸入
Dtc接受三種輸入格式:
原始檔,即device tree source;
Blob (dtb),flattened tree format,主要用於檢查現有的DTB映像;
FS檔案系統,/proc/device-tree下面的檔案樹目錄,主要用於從當前執行的核心中獲得裝置樹映像。

-sh-3.1# ls -al /proc/device-tree
ls -l /proc/device-tree/
-r--r--r--    1 root     root            4 Jan  1 00:05 #address-cells
-r--r--r--    1 root     root            4 Jan  1 00:05 #size-cells
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 aliases
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 chosen
-r--r--r--    1 root     root           15 Jan  1 00:05 compatible
dr-xr-xr-x    3 root     root            0 Jan  1 00:05 cpus
dr-xr-xr-x   15 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    4 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 memory
-r--r--r--    1 root     root            1 Jan  1 00:05 name
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 [email protected]

ls -l /proc/device-tree/immr/@e0000000/
-r--r--r--    1 root     root            4 Jan  1 00:06 #address-cells
-r--r--r--    1 root     root            4 Jan  1 00:06 #size-cells
-r--r--r--    1 root     root            4 Jan  1 00:06 bus-frequency
-r--r--r--    1 root     root           11 Jan  1 00:06 compatible
-r--r--r--    1 root     root            4 Jan  1 00:06 device_type
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    3 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    3 root     root            0 Jan  1 00:06 [email protected]
-r--r--r--    1 root     root            5 Jan  1 00:06 name
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
-r--r--r--    1 root     root           12 Jan  1 00:06 ranges
-r--r--r--    1 root     root            8 Jan  1 00:06 reg
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 [email protected]

3.2    輸出
Blob (dtb),主要用於從DTS獲得裝置樹映像;
source (dts), 當輸入引數為Blob (dtb),可以“反彙編”出裝置樹原始檔;
assembler source (asm),其最終可以編譯成.O檔案,可以連結到bootloader中或者frrmware image。

3.3    命令格式
dtc [-I <input -format > ] [-O <output -format > ] [-o output-filename] [-V output_version] input_filename

dtc -I dts -O dtb -S 0x3000 -o obj_name.dtb source_name.dts
-S 指定的是生成的dtb檔案的大小,需要適當地擴大以供u-boot 建立/choose節點時使用

4    裝置樹的傳遞途徑
對於Open Firmware (OF)系統,prom_init.c中的程式碼負責解析裝置樹,並將其轉化為blob印象。

對於無Open Firmware (OF)的系統,核心可以直接從入口啟動,並接受外部傳遞的flattened device tree引數。對於嵌入式系統,此引數由bootloader提供,或者封裝過的zImage映像提供。

4.1    U-boot對FDT的支援
U-boot為了支援FDT,專門添加了新的程式碼,如下:
/Libfdt目錄
fdt.h
libfdt.h
fdt_support.h
fdt_support.c

4.2    如何配置FDT
通常在板子配置標頭檔案定義相關巨集,以支援FDT
/* Pass open firmware flat tree */
#define CONFIG_OF_LIBFDT    1
#define CONFIG_OF_BOARD_SETUP    1
#define CONFIG_OF_STDOUT_VIA_ALIAS 1

CONFIG_OF_BOARD_SETUP巨集表示會對裝置樹中的部分引數進行調整,主要是timebase-frequency,bus-frequency,clock-frequency等引數,在裝置樹配置檔案中,這些引數可能為0,即採用U-boot中的引數。

4.3    如何傳遞裝置樹
Lib_ppc/board.c中do_bootm_linux負責啟動Linux核心。
#if defined(CONFIG_OF_LIBFDT)
#include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>

static void fdt_error (const char *msg);
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
        cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        char **of_flat_tree, ulong *of_size);
#endif

相關流程如下:
 

在該流程中,主要從啟動引數中找出裝置樹,然後在裝置樹中新增chosen 節點, 並將initrd 的地址地址,結束地址,bootargs,cmd_line 等引數儲存到chosen 節點中,最後根據是否支援扁平裝置樹選擇不同的核心啟動方式。

#if defined(CONFIG_OF_LIBFDT)
    if (of_flat_tree) {    /* device tree; boot new style */
        /*
         * Linux Kernel Parameters (passing device tree):
         *   r3: pointer to the fdt, followed by the board info data
         *   r4: physical pointer to the kernel itself
         *   r5: NULL
         *   r6: NULL
         *   r7: NULL
         */
        debug ("   Booting using OF flat tree.../n");
        (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
        /* does not return */
    } else
#endif
    {
        /*
         * Linux Kernel Parameters (passing board info data):
         *   r3: ptr to board info data
         *   r4: initrd_start or 0 if no initrd
         *   r5: initrd_end - unused if r4 is 0
         *   r6: Start of command line string
         *   r7: End   of command line string
         */
        debug ("   Booting using board info.../n");
        (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
        /* does not return */
    }

如果未定義CONFIG_OF_LIBFDT或者當前bootm命令沒有FDT引數時則採用傳統的方式啟動核心。

啟動命令格式如下:
Bootm kernel_addr  ramdisk_addr/-  fdt_addr
當不採用ramdisk時,第二個引數為“-”

5    核心如何解析裝置樹
1)首先將從u-boot 傳遞過來的映像基地址和dtb 檔案映像基地址儲存通用暫存器r30,r31;
2)通過呼叫machine_init()、early_init_devtree()函式來獲取核心前期初始化所需的bootargs,cmd_line等系統引導引數;

3)呼叫start_kernel()、setup_arch()、unflatten_device_tree()函式來解析dtb 檔案,構建一個由device_node 結構連線而成的單項鍊表,並使用全域性變數allnodes 指標來儲存這個連結串列的頭指標;
4)核心呼叫OF 提供的API 函式獲取allnodes連結串列資訊來初始化核心其他子系統、裝置等。
 

Head_32.S
/*
 * This is where the main kernel code starts.
 */
start_here:
。。。。
/*
 * Do early platform-specific initialization,
 * and set up the MMU.
 */
    mr    r3,r31
    mr    r4,r30
    bl    machine_init

/*
 * Find out what kind of machine we're on and save any data we need
 * from the early boot process (devtree is copied on pmac by prom_init()).
 * This is called very early on the boot process, after a minimal
 * MMU environment has been set up but before MMU_init is called.
 */
void __init machine_init(unsigned long dt_ptr, unsigned long phys)
{
    /* If btext is enabled, we might have a BAT setup for early display,
     * thus we do enable some very basic udbg output
     */
#ifdef CONFIG_BOOTX_TEXT
    udbg_putc = btext_drawchar;
#endif

    /* Do some early initialization based on the flat device tree */
    early_init_devtree(__va(dt_ptr));
}

/* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p)
{
    *cmdline_p = cmd_line;

    /* so udelay does something sensible, assume <= 1000 bogomips */
    loops_per_jiffy = 500000000 / HZ;

    unflatten_device_tree();
…..
}

/**
 * unflattens the device-tree passed by the firmware, creating the
 * tree of struct device_node. It also fills the "name" and "type"
 * pointers of the nodes so the normal device-tree walking functions
 * can be used (this used to be done by finish_device_tree)
 */
void __init unflatten_device_tree(void)
{
    unsigned long start, mem, size;
    struct device_node **allnextp = &allnodes;

    DBG(" -> unflatten_device_tree()/n");

    /* First pass, scan for size */
    start = ((unsigned long)initial_boot_params) +
        initial_boot_params->off_dt_struct;
    size = unflatten_dt_node(0, &start, NULL, NULL, 0);
    size = (size | 3) + 1;

    DBG("  size is %lx, allocating.../n", size);

    /* Allocate memory for the expanded device tree */
    mem = lmb_alloc(size + 4, __alignof__(struct device_node));
    mem = (unsigned long) __va(mem);

    ((u32 *)mem)[size / 4] = 0xdeadbeef;

    DBG("  unflattening %lx.../n", mem);

    /* Second pass, do actual unflattening */
    start = ((unsigned long)initial_boot_params) +
        initial_boot_params->off_dt_struct;
    unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
    if (*((u32 *)start) != OF_DT_END)
        printk(KERN_WARNING "Weird tag at end of tree: %08x/n", *((u32 *)start));
    if (((u32 *)mem)[size / 4] != 0xdeadbeef)
        printk(KERN_WARNING "End of tree marker overwritten: %08x/n",
               ((u32 *)mem)[size / 4] );
    *allnextp = NULL;

    /* Get pointer to OF "/chosen" node for use everywhere */
    of_chosen = of_find_node_by_path("/chosen");
    if (of_chosen == NULL)
        of_chosen = of_find_node_by_path("/[email protected]");

    DBG(" <- unflatten_device_tree()/n");
}

6    裝置樹對驅動設計產生的影響
TBD

相關推薦

嵌入式Linux學習 Linux系統bootlaoder移植全面解析PowerPC架構扁平裝置FDT

全面解析PowerPC架構下的扁平裝置樹FDT Sailor_forever  sailing_9806#163.com (本原創文章發表於Sailor_forever 的個人blog,未經本人許可,不得用於商業用途。任何個人、媒體、其他網站不得私自抄襲;網路媒體轉載請

Linux搭建伺服器(包括mysql、Tomcat、JDK) Tomcat

Tomcat篇  Tomcat相對來說就比較好設定了。 然後將檔案放到伺服器上 在usr下建立一個tomcat資料夾   命令: cd /usr/   命令: mkdir ./tomcat 然後將檔案放到tomcat目錄下 1.解壓   執行命令:tar

深入學習jQuery選擇器系列——過濾選擇器索引選擇器

通用形式$(':eq(index)')  $(':eq(index)')選擇器選擇索引等於index的元素(index從0開始),返回單個元素索引  [注意]索引選擇器的索引和子元素選擇器的索引有明顯的不同  【1】索引選擇器索引從0開始,而子元素選擇器索引從1開始  【2】索引選擇器的索引是指定元素的索引,

新年金融科技刷卡與收益

一次 高頻 基本上 機器 得到 範圍 卡方 百貨 tps **《刷卡與收益》** 刷卡原則 1.我們經常去商場POS機刷卡買東西,刷卡這個動作完成後,錢的流轉是怎麽樣的呢?這裏有幾個角色 (1

大話企業上雲

ges 當前 可靠性 運營 數據安全 需要 常見 water 企業 前言:不論什麽項目,最終部署實施都有其對應的方法論。按照項目的方法論,可以將上雲過程分為如下四個階段:評估階段~~~設計階段~~~實施階段~~~~運維階段一、評估階段1.1可行×××主要是驗證上雲的可行性,

區塊鏈100--數字簽名

數字簽名類似於我們現實世界中的檔案簽名,我們把名字寫在一個檔案上,就代表了我們認可了這份檔案,並且說明了這份檔案是真是可靠的,那麼問題是如果檔案的署名被偽造了怎麼辦?在現實世界中,我們一般會找當事人直接驗證這份檔案是否是親自簽署的而不是被人假冒的,而在計算機世界

學生資訊管理系統登入介面java程式碼

class DLFrame extends JFrame implements ActionListener, ItemListener {// 登入介面  JPanel p1 = null;  JPanel p2 = null;  JPanel p3 = null;  

java 商城系統架構——叢集架構搭建

其實叢集說起來是很簡單的,無非就是server部署在多臺機器上,DB、session、檔案等在做個機器、CDN加速就OK了。 但是實際上需要做的事還有非常多,並且在過程中需要填非常多的坑。 這裡說一個很多人都不太瞭解的,就是虛擬IP,比如你訪問baidu.com,多少年還

分庫分表

分庫分表之第三篇 3. Sharding-JDBC執行原理 3.1 基本概念 3.2. SQL解析 3.3.SQL路由 3.4. SQL改寫 3.6.結果歸併 3.7 總結   3. Sharding-JDBC執行原理 3.1 基本概念 在瞭解Sharding-JDBC

JAVA位元組碼檔案(訪問標識)

一、Access Flags 訪問標誌 訪問標誌資訊包括該 Class 檔案是類還是介面,是否被定義成 public 或者 abstract , 如果是類,是否被宣告成 final。 訪問標誌表       二、Access Flags 的分析   &

Linux學習軟體安裝

環境  虛擬機器:VMware 10   Linux版本:CentOS-6.5-x86_64   客戶端:Xshell4  FTP:Xftp4 一、編譯安裝1.解壓 原始碼檔案是壓縮包 要先解壓tar -zxvf tengine-2.1.0.tar.gz 2.進入解壓包 檢視README檔案 裡面有對軟體

Linux學習軟件安裝

vmw arc 缺少 perl 指導 tar 編譯安裝 驗證 erl 環境  虛擬機:VMware 10   Linux版本:CentOS-6.5-x86_64   客戶端:Xshell4  FTP:Xftp4 一、編譯安裝1.解壓 源碼文件是壓縮包 要先解壓tar -z

Linux學習指令碼程式設計

環境  虛擬機器:VMware 10   Linux版本:CentOS-6.5-x86_64   客戶端:Xshell4  FTP:Xftp4 一、多層bash#.和source都是當前bash [[email protected] ~]# echo $$ 1578 sh01.sh: e

Linux學習第一(虛擬機的和鏡像文件的安裝)

image 下載文件 型號 啟動 計算機 服務 .cn img blog 一、安裝虛擬機(本文以vmware workstation 12為例)   1.在網上所有虛擬機並下載。   2.找到下載文件安裝好   3.一直下一步   4.接下來的就是選擇安裝的目錄了,當

不銹鋼齒輪泵安全操作

工作壓力 管道 情況 必須 需要 溫度 不可 零部件 IT 不銹鋼齒輪泵一般輸送有腐蝕性的介質,在使用過程中要註意仔細保養,啟動的時候特別註意查看管道的接口是否密封好,查看電機的旋轉方向是否正確。時時註意軸承溫度不要過高,不銹鋼泵因為介質具有腐蝕性,所以如果停機不再使用

Linux學習筆記_shell程式設計環境變數配置檔案

shell程式設計之環境變數配置檔案 https://www.imooc.com/learn/361 簡介:本課程是《Tony老師聊shell》系列課程的第三篇,為你帶來常用的Linux環境變數配置檔案的使用。對環境變數配置檔案的功能進行了詳解, 然後又介紹了其他環境變數配置檔案,包括登

Linux學習筆記_shell程式設計運算子

shell程式設計之運算子 https://www.imooc.com/learn/355 **簡介:**本課程是《Tony老師聊shell——變數》課程的延續,主要介紹Linux shell程式設計基礎中的運算子。包括declare命令、數值運算方法和變數測試。 首先在declare

Linux學習筆記_shell程式設計變數

shell程式設計之變數 https://www.imooc.com/learn/336 **簡介:**本課程是《Linux達人養成計劃I》中第九章課程的延續,主要介紹Linux shell程式設計基礎中的變數。包括Bash變數的分類和各變數的詳細使用,如:使用者自定義變數、環境變數、語

itext學習-------()對pdf文件進行加密和許可權設定

上篇文章,我們學習了pdf的屬性設定,但是我們知道,在實際開發中,如果pdf文件被黑客盜取的話,那麼pdf中的資訊就會被洩露,因此本篇文章將會介紹pdf的加密設定,並且設定許可權。 首先我們要說明的是,itext中對pdf文件的加密包括兩部分,第一部分是使用者密

Linux學習小白成長

1、簡介 Linux就是一個作業系統,就像你之前用過的windows和macos。下面是小弟畫的關係圖,有助於理解作業系統 作業系統始於二十世紀五十年代,當時的作業系統能執行批處理程式。批處理程式不需要使用者的互動,它從檔案或者穿孔卡片讀取資料,然後輸出到另外一個檔案或者印表機。貝爾實