U-Boot-基礎概念與學習分享

来源:https://www.cnblogs.com/m-contour/archive/2023/02/27/17159342.html
-Advertisement-
Play Games

文章對 u-boot 學習路線進行了簡單介紹, 並從 u-boot 構建框架著手解構 u-boot, 以 Kconfig 為索引文件自底向上分析框架。 除此之外還介紹了 Boot Loader 的幾個基本流程, 對其中的 TPL 過程進行了剖析。 ...


U-Boot 基礎概念與學習分享

  • Board: rockchip-px30, armv8, Cortex-A35
  • U-Boot: rockchip-linux/u-boot, branch next-dev
  • Tools: VScode, Exuberant CTags

1. 前言

學習 u-boot 啟動流程有些時日了, 雖然看了大量的文章以及在此期間仔細閱讀源碼, 但是仍感覺很多知識點掌握不深刻容易遺忘,不如在寫博文博文的時候重溯整個流程, 也分享自己學習 u-boot 的學習路線方便後來者入門。

2. 學習路線

一般來說晶元公司會提供相關的手冊介紹各個組件, 這對瞭解特定型號的開發板是很有效的, 但不適合初學者進行系統的學習, 建立全局概念應當是第一位的。 學習 u-boot 應當對以下幾個方面有所瞭解:

  • ARM Assembly, 推薦 Kyle BaldwinARM Assembly By Example, 我自己在 github 上也實現了相關的 lab。
  • Device Tree, The DeviceTree Specification 結合具體的 dts/dtsi 文件閱讀學習。
  • Linker Script, GNU Binutils 官方的ld文檔合具體的lds文件進行閱讀學習, 結合 程式員的自我修養--鏈接裝載與庫 這本書建立相關概念。
  • Kconfig, Kconfig Language 同樣用在了 u-boot 中需要對其有一定的瞭解。

如果對 DM(Driver Model) 有興趣, 可以閱讀 Linux Device Driver, Third Edition,但具備以上幾塊知識已經足夠理解 u-boot 啟動流程。 Das U-Boot 提供的文檔以及 u-boot 源碼中提供的 README 這類文檔不需要仔細讀完, 這些僅供學習參考, 但 elinux_talks 這部分資源也值得查閱。

當然還是那句話, 全局概念非常重要, 先啃源碼建立相關概念, 帶著問題探究細節會事半功倍。

3. U-Boot 框架與啟動階段

3.1 U-Boot 架構分析

u-boot 的開發者在開發文檔中描述目錄的層次結構, 但缺少更為巨集觀的概括。 以 rockchip-px30 為例, 其在 u-boot 中的文件可被劃歸為以下幾類。以CPU,ARCH,Board 三級對文件進行劃分可以幫助我們在配置新板時有更清晰的規劃。 Quentin Schulz 在 2017 年的嵌入式 linux 歐洲會議上的演講 Porting U-Boot and Linux on new ARM boards: a step-by-step guide 則具體介紹了詳細的實施步驟。

CPU (armv8), ARCH (arm), Board(px30)

  • CPU 層級依賴文件
    • arch/arm/cpu/armv8/*c;*S;*lds
    • arch/arm/include/asm/armv8/*h
  • ARCH(arm) 層級依賴文件
    • arch/arm/lib/*c;*S;*lds
    • arch/arm/include/asm/*h;*S
  • Board 層級依賴文件
    • board/rockchip/evb_px30/*c
    • arch/arm/mach-rockchip/px30/*c
  • Board 層級配置文件
    • arch/arm/include/asm/arch-rockchip/*h;*S
    • include/rockchip/*h
    • include/px30_common.h;evb_px30.h
  • Board 層級非依賴文件
    • common(cmd, flash, env, usb, ...), disk(partition)
    • drivers, fs, net, lib

U-Boot Hierarchy, HangX-Ma

u-boot 的初始化過程就是 CPU \(\rightarrow\) ARCH \(\rightarrow\) Board 的過程, 但並不嚴格劃歸, ARCH部分的通用代碼會調用 Board 相關的介面。 在 wowo 的文章中提到曾經存在於 ARCH 和 Board 之間的 machine 層級由於最新的ARM64架構引入了 device tree 的緣故, 已經將 machine 概念刪除了, 在當前 u-boot 中看到的 mach-xxx 的目錄或文件就屬於 machine 層級, 雖然 u-boot 還未更新相關的架構概念, 但在開發層面 u-boot 和 linux 內核幾乎同時適用了 device tree, 這意味著 u-boot 也很可能在之後的更新中刪除類似的 mach-xxx 文件。

3.1.1 舉例——從 Kconfig 自底向上

Kconfig 中自底向上梳理整個編譯框架, 假設我們使用的目標板是 rockchip-px30 系列的 evb-px30, 那麼 board/rockchip/evb_px30 文件夾中定義了目標板的一些依賴代碼, 在 include/configs/evb_px30.h 會有該目標板的配置信息, 類似的配置信息和編譯是息息相關的需要格外留意, 後續不過提點。

從頂層的 board/rockchip/evb_px30/Kconfig 查看, 可以找到 TARGET_EVB_PX30 整個關鍵量以及定義的 BORADVENDOR 等編譯相關的變數。

# board\rockchip\evb_px30\Kconfig
if TARGET_EVB_PX30

config SYS_BOARD
    default "evb_px30"

config SYS_VENDOR
    default "rockchip"

config SYS_CONFIG_NAME
    default "evb_px30"

config BOARD_SPECIFIC_OPTIONS # dummy
    def_bool y

endif

順著前述所提及的關鍵量, 在 arch/arm/mach-rockchip/px30/Kconfig 中能找到引用信息(尤其是 source 了前述的 Kconfig 文件), 由於當前使用的就是 evb-px30 板, EVB_PX30bool 變數是 true。 可以看到該 Kconfig 文件在框架中屬於亟待更新的 machine 層級, 所以在該部分可以看到 SYS_SOC 這個配置變數。 在該 Kconfig 文件中還覆蓋定義了 SYS_MALLOC_F_LENSPL_SERIAL_SUPPORT

# arch/arm/mach-rockchip/px30/Kconfig
if ROCKCHIP_PX30

config TARGET_EVB_PX30
    bool "EVB_PX30"
    select BOARD_LATE_INIT

config SYS_SOC
    default "rockchip"

config SYS_MALLOC_F_LEN
    default 0x400

config SPL_SERIAL_SUPPORT
    default y

source "board/rockchip/evb_px30/Kconfig"

endif

在更上一級目錄則看到更為通用的 Kconfig 文件會配置 ROCKCHIP_PX30 這個定義量。 可以看到在該目錄下配置了 px30 系列使用預設配置。 我們再向上一級的查找 ARCH_ROCKCHIP 變數以其找到頂層的 xxx_defconfig 配置文件。

# arch\arm\mach-rockchip\Kconfig
if ARCH_ROCKCHIP

config ROCKCHIP_PX30
    bool "Support Rockchip PX30"
    select ARM64 if !ARM64_BOOT_AARCH32
    select GICV2
    select ARM_SMCCC
    select SUPPORT_SPL
    select SUPPORT_TPL
    select SPL if !ARM64_BOOT_AARCH32
    select TPL if !ARM64_BOOT_AARCH32
    select TPL_TINY_FRAMEWORK if TPL

    imply SPL_SEPARATE_BSS
    imply SPL_SERIAL_SUPPORT
    imply TPL_SERIAL_SUPPORT
    help
      The Rockchip PX30 is a ARM-based SoC with a quad-core Cortex-A35
      including NEON and GPU, Mali-400 graphics, several DDR3 options
      and video codec support. Peripherals include Gigabit Ethernet,
      USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.

if ROCKCHIP_PX30

config TPL_LDSCRIPT
    default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"

config TPL_TEXT_BASE
    default 0xff0e1000

config TPL_MAX_SIZE
    default 10240

config ROCKCHIP_RK3326
    bool "Support Rockchip RK3326 "
    help
      RK3326 can use most code from PX30, but at some situations we have
      to distinguish between RK3326 and PX30, so this macro gives help.
      It is usually selected in rk3326 board defconfig.
endif
...

在更上一級, 我們先找到了 arch\arm\Kconfig, ARCH 層級的預設配置。

# arch\arm\Kconfig
...
config ARCH_ROCKCHIP
    bool "Support Rockchip SoCs"
    select OF_CONTROL
    select BLK
    select DM
    select SPL_DM if SPL
    select SYS_MALLOC_F
    select SYS_THUMB_BUILD if !ARM64
    select SPL_SYS_MALLOC_SIMPLE if SPL
    imply DM_GPIO
    select DM_SERIAL
    select DM_SPI
    select DM_SPI_FLASH
    select DM_USB if USB
    select CMD_ROCKUSB if USB_GADGET_DOWNLOAD
    select ENABLE_ARM_SOC_BOOT0_HOOK
    select SYS_NS16550
    select SPI
    select DEBUG_UART_BOARD_INIT
    select PANIC_HANG
    imply DM_MMC
    imply DM_I2C
    imply DM_PWM
    imply DM_REGULATOR
    imply CMD_FASTBOOT
    imply FASTBOOT
    imply FAT_WRITE
    imply USB_FUNCTION_FASTBOOT
    imply USB_FUNCTION_ROCKUSB
    imply SPL_SYSRESET
    imply TPL_SYSRESET
    imply ADC
    imply SARADC_ROCKCHIP
...

最終我們能在 configs/evb-px30_defconfig(Target) 中找到用戶自定義的基本巨集信息, 另外一些信息則在前述提及的配置文件中。 例如 include/configs/px30_common.hinclude/configs/evb_px30.h, 以及 include/configs/rockchip-common.h。 我們自底向上, 特定的板級文件開始溯源, 找到了最終頂層的配置文件。 根據頂層的配置文件以及每個層級的配置文件可以梳理出編譯特定板所需的功能。 另外, 在底層的 TARGET 的配置中可以看到諸如 SYS_xxx 的一系列配置, 這些配置會在更上層的 arch\Kconfig 中定義。 所以綜上可以總結出如下配置關係圖。

flowchart subgraph Target evb-px30_defconfig end subgraph arch subgraph arm subgraph mach-rockchip subgraph px30 Board/evb-px30 end end end end style Target fill:#A44,stroke:#333,stroke-width:4px style arch fill:#A44,stroke:#333,stroke-width:4px style arm fill:#A43,stroke:#333,stroke-width:4px style mach-rockchip fill:#BBA,stroke:#333,stroke-width:4px style px30 fill:#444,stroke:#333,stroke-width:4px Target -.-> arch

3.2 Boot Loader Stage

BLx(Boot Loader Stage) 指代 Boot Loader 的各個階段, 具體的劃分根據 u-boot 初始化時所在存儲設備略有不同, 一般將 u-boot 啟動劃分為 4 個階段, BL0, BL1, BL2, BL3。值得註意的是這與 ARM TrustZone 的劃分非屬同源, 在 ARM TrustZone 的劃分中, u-boot 屬於 BL33 Non-secure 部分。

  • BL0, SOC 生產廠家固化在 iROM(Internal ROM) 中的啟動代碼, 主要負責載入 BL1 的程式, 該部分被稱作 Initial Program Loader (IPL) 或者 Primary Program Loader (PPL)。
  • BL1, 該部分被稱為 SPL(Secondary Program Loader), 若 SPL 部分仍超過了 flash 存儲限制, 首先會通過 TPL(Trinary Program Loader) 進行更簡潔的初始化如 DDR 部分的初始化,以保證代碼體積極小, 之後再從指定位置載入 SPL 繼續執行初始化。
  • BL2, 該階段 u-boot 運行程式重定位之前的部分, 主要負責一系列初始化操作以及構建 C 語言的運行環境, 最為關鍵的是將 u-boot 重定位至 DRAM/SDRAM 中繼續執行 BL3 階段的程式。
  • BL3, 在該階段實質上載入了u-boot, 當然通過 ATF(Architecture Trusted Firmware) 載入也是可以的。 該階段在負責初始化 SOC 的外設, 準備內核啟動參數以及載入運行內核等操作。

Boot loader sequences, HouchengLin

根據以上描述, 以圖例形式表述 u-boot 的啟動流程應當如下所示。

flowchart LR p1(BootROM) p2(TPL, optional) p3(SPL) p4(ATF, optional) p5(U-Boot) p6(Kernel) p1 --> p2 --> p3 --> p4 --> p5 --> p6 p1 -.-> p3 p3 -.-> p5 p1 ==> p5

4. 淺析 TPL

嵌入式的代碼鐵定有個名為 start.S 的入口彙編代碼, 但在進行源碼分析之前, 我比較喜歡閱讀鏈接腳本以此獲悉 u-boot 的構成以及分析啟動過程中的一些工作。 在 arch/arm/cpu/armv8 目錄下有兩個 lds 文件, armv8 的 BootROM \(\rightarrow\) u-boot 的引導使用 u-boot.lds 進行鏈接, 而在 u-boot 之前存在 SPL/TPL 階段則會使用 u-boot-spl.ldsarch/arm/mach-rockchip/u-boot-tpl-v8.lds 進行鏈接。

在上述流程中提及 TPL 的存在, 這也是讓我比較困惑的, TPL 如何 與 SPL 進行配合實現對 bootloader 的引導啟動, 這一塊內容值得深入探究。 不妨先從 TPL 的鏈接腳本入手, 釐清 TPL 階段的相關邏輯。

這兩篇文章關於 u-boot-spl.lds 有著不同詳略的解析, 可以用以瞭解 u-boot 相關的鏈接腳本的 section 的基本功能以及瞭解鏈接腳本的基本概念, 這些內容已有前人做了充分的解析不再贅述。

4.1 TPL Configurations

根據前述配置, evb-px30 在啟動時會經由 TPL 以及 SPL 引導 u-boot。 在 arch/arm/mach-rockchip/Kconfig 中可以看到與 TPL 相關的一些定義:TPLTPL_TINY_FRAMEWORKTPL_TINY_FRAMEWORKTPL_LDSCRIPTTPL_TEXT_BASETPL_MAX_SIZESUPPORT_TPL, 這些巨集定義會影響後續編譯的過程。

其中, CONFIG_TPL_BUILD 這個巨集定義非常重要。 網上很多博客提及相關內容僅說明在定義 CONFIG_TPL 之後 CONFIG_TPL_BUILD 會自動定義, 但沒有詳細說明具體位置。 在 scripts/Makefile.autoconf 文件的 85-87 行可以看到幾行規則, 實際上向 tpl/u-boot.cfg 傳遞了 CONFIG_SPL_BUILDCONFIG_TPL_BUILD 這兩個量。 在其他任何 config.mkKconfigKbuild 這樣的文件中都不會找到這兩個量的定義。

# scripts/Makefile.autoconf
tpl/u-boot.cfg: include/config.h FORCE
    $(Q)mkdir -p $(dir $@)
    $(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD -DCONFIG_TPL_BUILD)

另外在頂層的 Makefile 文件我們可以找到這樣一則規則, 是 script/Makefile.autoconf 的上一級引用。

# Makefile
u-boot.cfg spl/u-boot.cfg tpl/u-boot.cfg: include/config.h FORCE
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf $(@)

而當我們查看 script/Makefile.autoconf 所描述的功能時, 可以看到前述的 CONFIG_SPL_BUILDCONFIG_TPL_BUILD 以及其他生成的巨集定義最終會被轉移到 Kconfig 中以完成全局性的定義。

# This helper makefile is used for creating
#  - symbolic links (arch/$ARCH/include/asm/arch
#  - include/autoconf.mk, {spl,tpl}/include/autoconf.mk
#  - include/config.h
#
# When our migration to Kconfig is done
# (= When we move all CONFIGs from header files to Kconfig)
# this makefile can be deleted.

4.2 TPL Linker Script

BootROM 完成基本的初始化後首先會在 iRAM 中載入 TPL 段的運行代碼。

OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start)
SECTIONS
{
    . = 0x00000000;

    .text : {
        . = ALIGN(8);
        *(.__image_copy_start)
        CPUDIR/start.o (.text*)
        *(.text*)
    }

    .rodata : {
        . = ALIGN(8);
        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
    }

    .data : {
        . = ALIGN(8);
        *(.data*)
    }

    .u_boot_list : {
        . = ALIGN(8);
        KEEP(*(SORT(.u_boot_list*)));
    }

    .image_copy_end : {
        . = ALIGN(8);
        *(.__image_copy_end)
    }

    .end : {
        . = ALIGN(8);
        *(.__end)
    }

    _image_binary_end = .;

    .bss_start (NOLOAD) : {
        . = ALIGN(8);
        KEEP(*(.__bss_start));
    }

    .bss (NOLOAD) : {
        *(.bss*)
         . = ALIGN(8);
    }

    .bss_end (NOLOAD) : {
        KEEP(*(.__bss_end));
    }

    /DISCARD/ : { *(.dynsym) }
    /DISCARD/ : { *(.dynstr*) }
    /DISCARD/ : { *(.dynamic*) }
    /DISCARD/ : { *(.plt*) }
    /DISCARD/ : { *(.interp*) }
    /DISCARD/ : { *(.gnu*) }
}

#if defined(CONFIG_TPL_MAX_SIZE)
ASSERT(__image_copy_end - __image_copy_start < (CONFIG_TPL_MAX_SIZE), \
 "TPL image too big");
#endif

#if defined(CONFIG_TPL_BSS_MAX_SIZE)
ASSERT(__bss_end - __bss_start < (CONFIG_TPL_BSS_MAX_SIZE), \
 "TPL image BSS too big");
#endif

#if defined(CONFIG_TPL_MAX_FOOTPRINT)
ASSERT(__bss_end - _start < (CONFIG_TPL_MAX_FOOTPRINT), \
 "TPL image plus BSS too big");
#endif

ENTRY(_start) 實際上聲明瞭程式的入口地址, 對 TPL 而言這是顯而易見的, 因為 TPL 需要在該階段獲得程式的控制權完成一系列基本的初始化進程。 與其他 ld 文件不同的是, TPL 的鏈接腳本對 TPL 程式本身的大小有嚴格的控制。 在 machine 級的 arch/arm/mach-rockchip/Kconfig 中我們定義了 TPL_MAX_SIZE, 這使得我們可以檢查 TPL image 的大小以滿足 iRAM 的空間限制要求。一般來說,__image_copy_start__image_copy_end 這兩個變數常用來輔助 u-boot 的重定位, 但在此處被賦予了新的功能。 另外可以看到 bss 段都被聲明瞭 NOLOAD 屬性, 這意味著 bss 段在 image 中並不占用任何空間, 但相關的地址信息會被保留用以在 u-boot載入時的一些數據初始化操作。 因而可以歸納得到 TPL 載入時實際的記憶體分佈情況。


TPL Loading Memory, HangX-Ma

另外可以從 ld 文件中看到, 入口程式是 CPUDIR/start.o, CPUDIR 可以依據層級劃分從各個較為頂層的 Makefile 文件中找到具體定義。 但根據架構分析中的概念, 不難得出此處的 CPUDIRarch/arm/armv8start.S 最終會定位到 _main 程式入口繼續執行流程。(關於 start.S 的詳細流程可以參考 ARMv8架構u-boot啟動流程詳細分析(二), 內核新視界) 由於我們的編譯是 AArch64 架構, 那麼 C Runtime Environment 的建立也應當是 crt0_64.S, 可以在這個文件中看到, board_init_f_alloc_reserveboard_init_f_init_reserveboard_init_f_boot_flags 幾個函數通過在棧頂預留記憶體來達到給 GD(Global Data) 開闢記憶體空間, 在 AArch64 架構中 GD 指針地址會被保留在 x18 寄存器中供全局使用, 之後跳轉到 board_init_f。 這是一個分水嶺, TPL, SPL 以及 u-boot 都會執行這個函數。

一般來說可以將 u-boot 的啟動過程劃分為兩個階段, 也就是前述的 BL2 和 BL3 的區分。 Pre-relocation(common/board_f.c), 此處的 f 表示程式執行所在的存儲介質是 flash, 以及 After-relocation(common/board_r.c), 此處的 r 表示程式執行所在的存儲介質是 RAM

我們知道 TPL 只完成一些很基本的初始化流程, 對於 TPL 而言實際上不存在重定位的需求, 所以關鍵就在 board_init_f 這個函數。

  • SPL: arch\arm\mach-rockchip\spl.c
  • TPL: arch\arm\mach-rockchip\tpl.c
  • U-Boot: common\board_f.c

在編譯鏈接時, 編譯組件就會對這幾個文件進行區分, 以保證綁定正確的可執行文件。 在 arch\arm\mach-rockchip\Makefile 中就巧妙的在編譯 TPL 文件時取消了 SPL 相關文件的生成, 而在編譯 SPL 文件時則不受 TPL 的相關定義影響。

根據之前的巨集定義梳理的在 TPL 階段的 board_init_f 所做的工作如下, 時鐘初始化, CPU 部分初始化, UART 串口初始化, SDRAM 初始化。 這些工作都完成之後會通過 arch\arm\mach-rockchip\Kconfig 預設定義的 TPL_ROCKCHIP_BACK_TO_BROM 巨集引導的 back_to_bootrom 返回 BootROM 階段再進行下一階段的 SPL。

board_init_f
    rockchip_stimer_init
    arch_cpu_init
    debug_uart_init
    timer_init
    sdram_init
    back_to_bootrom
flowchart LR p1(BootROM) p2(TPL) p3(SPL) p4(U-Boot) p5(Kernel) p1 -.->|stage 1 'init'| p2 p2 -.->|stage 2 'back to rom'| p1 p1 -->|stage 3| p3 p3 --> p4 p4 --> p5

至於 SPL 的具體流程可以參考 TPL 的流程進行推導相關的資料也非常詳細, 在參考部分的 U-Boot 部分已經列舉了篩選過的較好的資料可供選讀。

5. 總結

文章對 u-boot 學習路線進行了簡單介紹, 並從 u-boot 構建框架著手解構 u-boot, 以 Kconfig 為索引文件自底向上分析框架。 除此之外還介紹了 Boot Loader 的幾個基本流程, 對其中的 TPL 過程進行了剖析。後續會在此篇博文的基礎上進行增改擴充基礎概念部分, 而其他需要仔細剖析的部分則另建博文進行闡述。

6. 參考

6.1 U-Boot

6.2 ARM 參考手冊

6.3 AArch64 架構


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 最近又在項目中碰到需要將原本單實現的介面改造成多個實現的場景,這裡記錄一下常見的幾種改法。 假設已經存在如下介面ICustomService和其實現CustomService,由於只有一種實現,註入和使用非常容易。 public interface ICustomService { void ...
  • Dapper是什麼? Dapper是一款.Net平臺簡單(Simple)的對象映射庫,並且Dapper擁有著“微型ORM之王”的稱號。 就速度而言與手寫ADO.NET SqlDateReader相同。 ORM是Object Relational Mapper的縮寫,代表著資料庫與編程語言之間的映射。 ...
  • 服務端 工作需要又需要用到socketTCP通訊,這麼多年了,終於稍微能寫點了。讓我說其實也說不出個啥來,看了很多的非同步後稍微對非同步socket的導流 endreceive後 再beginreceive 形成一個內迴圈有了個認識,加上我自己的封包拆包機制,然後再仿那些其它的大多數代碼結構弄點onRe ...
  • 1.1 操作系統的概念: 1.1.1 什麼是操作系統: 控制和管理整個電腦系統的硬體和軟體資源 合理地組織調度電腦的工作和資源的分配 提供給用戶和其他軟體方便的介面和環境 是電腦最基本的系統軟體 1.1.2 操作系統的功能和目標: 操作系統作為系統資源(資源:軟體、硬體、文件等)的管理者,提供 ...
  • 修改預設的yum倉庫,把原有的移動到創建的目錄里(踢出國外的yum源) # 切換到/ect/yum.repos.d/目錄下 cd /etc/yum.repos.d/ # 新建repo目錄 mkdir repo # 把原有的移動到創建的目錄里 mv ./*.repo ./repo/ 配置yum源 # ...
  • 前言 今天閱讀了一本說明書,《gdbOF: A Debugging Tool for OpenFOAM》 受himryangzz視頻啟發去讀相關內容,在此對himryangzz表示感謝 希望本篇文章能為需要gdb調試of的人節約時間 文章前言: 文章前言說of確實做的很不錯,但調試者需要對of類的結 ...
  • 0x00漏洞信息 漏洞影響:本地提權 漏洞文件:win32kfull.sys 漏洞函數:vStrWrite04 漏洞原因:越界讀寫 分析系統:Windows 1903 0x01漏洞分析 崩潰時的堆棧: nt!KiBugCheckDebugBreak+0x12 nt!KeBugCheck2+0x952 ...
  • VirtuanBox 安裝完成虛擬機後,打開VirtuanBox,添加一塊網卡,設置如下, 還可以通過控制面板查看該網卡的具體參數信息,也可進行相應修改: 虛擬機中針對剛安裝的centos系統,設置網路,配置兩快網卡如下: 打開centos系統,複製/etc/sysconfig/network-sc ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...