ARMv8 创建3级页表示例

最近在研究arm v8页表创建过程,顺带做了一个如下形式的页表,

// level 1 table, 4 entries:
// 0000 0000 - 3FFF FFFF, 1GB block, DDR
// 4000 0000 - 7FFF FFFF, 1GB block, DDR
// 8000 0000 - BFFF FFFF, 1GB block, DDR
// C000 0000 - FFFF FFFF, point to level2 tabel
//
// level 2 table, 512 entries:
// C000 0000 - DFFF FFFF, 256 entries, 512MB DDR, 2MB block
// E000 0000 - EFFF FFFF, 128  entries, 256MB OSPI0 flash, 2MB block

// F100 0000 - F11F FFFF, 1 entry, point to level 3_1
// F200 0000 - F21F FFFF, 1 entry, point to level 3_2
// F240 0000 - F25F FFFF, 1 entry, point to level 3_3
// F260 0000 - F27F FFFF, 1 entry, point to level 3_4
// F500 0000 - F500 7FFF, 1 entries, GIC 32kB, point to level 3_5

// F220 0000 - F23D FFFF, 1 entries, 2MB block, device, RNE_CFG1
// F400 0000 - F403 FFFF, 1 entries, 2MB block, normal memory, RNE_MEM, 1.5M acture, SRAM
 

下面是页表创建过程与详细注释,供后来者学习参考。

//----------------------------------------------------------------
// setup translation table
//
//----------------------------------------------------------------
#include "v8_mmu.h".text.cfi_sections .debug_frame  // put stack frame info into .debug_frame instead of .eh_frame.global setup_ttb.global ZeroBlock.global __ttb0_l1.global __ttb0_l2_ram.global __ttb0_l3_ram_1.global __ttb0_l3_ram_2.global __ttb0_l3_ram_3//----------------------------------------------------------------
// setup translation table
// level 1 table, 4 entries:
// 0000 0000 - 3FFF FFFF, 1GB block, DDR
// 4000 0000 - 7FFF FFFF, 1GB block, DDR
// 8000 0000 - BFFF FFFF, 1GB block, DDR
// C000 0000 - FFFF FFFF, point to level2 tabel
//
// level 2 table, 512 entries:
// C000 0000 - DFFF FFFF, 256 entries, 512MB DDR, 2MB block
// E000 0000 - EFFF FFFF, 128  entries, 256MB OSPI0 flash, 2MB block// F100 0000 - F11F FFFF, 1 entry, point to level 3_1
// F200 0000 - F21F FFFF, 1 entry, point to level 3_2
// F240 0000 - F25F FFFF, 1 entry, point to level 3_3
// F260 0000 - F27F FFFF, 1 entry, point to level 3_4
// F500 0000 - F500 7FFF, 1 entries, GIC 32kB, point to level 3_5// F220 0000 - F23D FFFF, 1 entries, 2MB block, device, RNE_CFG1
// F400 0000 - F403 FFFF, 1 entries, 2MB block, normal memory, RNE_MEM, 1.5M acture, SRAM//----------------------------------------------------------------.type setup_ttb, "function".cfi_startproc
setup_ttb://// x21 = address of L1 tables// x22 = address of L2 tables// x23 = address of L3_1 tables// x24 = address of L3_2 tables// x25 = address of L3_3 tables// x26 = address of L3_4 tables// x27 = address of L3_5 tablesldr x2, =0  // x2 = 0 (用于清零内存)ldr x3, =0 // x3 = 0 (同上)// 清零 L1 页表 (__ttb0_l1) (L1 页表(32 字节,4 个条目))ldr x21, =__ttb0_l1  // x21 = L1 页表基地址mov x0, x21            // x0 = 当前操作地址mov x1, #(4 << 3)      // x1 = 4个条目 * 8字节 = 32字节 (L1页表大小)add x0, x0, x1         // x0 指向区域末尾 (预递减清零准备)// can not call func ZeroBlock,  not support nesting
loop_zero_0:subs x1, x1, #16       // 每次处理16字节 (2个条目),更新计数器stp  x2, x3, [x0, #-16]! // 存储双零并递减地址: [x0-16] = (0,0), x0-=16b.ne loop_zero_0        // 循环直到x1=0// 清零 L2 页表 (__ttb0_l2_ram) (L2 页表(4096 字节,512 条目))ldr x22, =__ttb0_l2_ram // x22 = L2 页表基地址mov x1, #(512 << 3)    // x1 = 512条目 * 8字节 = 4096字节 (标准2MB块大小)mov x0, x22            // x0 = 当前操作地址add x0, x0, x1         // x0 指向区域末尾//循环使用 subs + b.ne 实现精确计数(当 x1 减至 0 时退出)
loop_zero_1:subs x1, x1, #16       // 每次16字节stp  x2, x3, [x0, #-16]! // 存储双零并前移指针b.ne loop_zero_1       // 循环// 清零第一个 L3 页表 (__ttb0_l3_ram_1) (三个 L3 页表(各 4096 字节))ldr x23, =__ttb0_l3_ram_1 // x23 = L3 页表1基地址mov x1, #(512 << 3)    // 4096字节 (标准4KB页表大小)mov x0, x23add x0, x0, x1        // 指向末尾
loop_zero_2:subs x1, x1, #16stp  x2, x3, [x0, #-16]!b.ne loop_zero_2// 清零第二个 L3 页表 (__ttb0_l3_ram_2)ldr x24, =__ttb0_l3_ram_2 // x24 = L3 页表2基地址mov x1, #(512 << 3)    // 4096字节mov x0, x24add x0, x0, x1        // 指向末尾
loop_zero_3:subs x1, x1, #16stp  x2, x3, [x0, #-16]!b.ne loop_zero_3// 清零第三个 L3 页表 (__ttb0_l3_ram_3)ldr x25, =__ttb0_l3_ram_3 // x25 = L3 页表3基地址mov x1, #(512 << 3)    // 4096字节mov x0, x25add x0, x0, x1         // 指向末尾
loop_zero_4:subs x1, x1, #16stp  x2, x3, [x0, #-16]!b.ne loop_zero_4// 清零第4个 L3 页表 (__ttb0_l3_ram_4)ldr x26, =__ttb0_l3_ram_4 // x26 = L3 页表4基地址mov x1, #(512 << 3)    // 4096字节mov x0, x26add x0, x0, x1         // 指向末尾
loop_zero_5:subs x1, x1, #16stp  x2, x3, [x0, #-16]!b.ne loop_zero_5// 清零第5个 L3 页表 (__ttb0_l3_ram_5)ldr x27, =__ttb0_l3_ram_5 // x26 = L3 页表4基地址mov x1, #(512 << 3)    // 4096字节mov x0, x27add x0, x0, x1         // 指向末尾
loop_zero_6:subs x1, x1, #16stp  x2, x3, [x0, #-16]!b.ne loop_zero_6// 设置 L1 页表项配置// 0000 0000 - 3FFF FFFF, 1GB block, DDR// 4000 0000 - 7FFF FFFF, 1GB block, DDR// 8000 0000 - BFFF FFFF, 1GB block, DDR// 3 1G block, write to l1 table//ldr x1, =3                // x1 = 3 (需要配置的页表项数量)ldr x2, =0x40000000      // x2 = 1GB 地址增量 (每个 L1 条目映射 1GB 空间)// 构建 L1 块描述符属性值:// - 物理地址基址: 0x00000000// - 块描述符类型 (TT_S1_ATTR_BLOCK)  TT_S1_ATTR_BLOCK:使用块描述符 (1GB/2MB 大页)// - 内存属性索引 1 (MATTR=1) 普通内存,适用于ddr// - 非安全状态 (NS)// - 特权读写权限 (AP_RW_PL1)// - 内部可共享 (SH_INNER)// - 访问标志 (AF)// - 非全局映射 (nG)ldr x3, =(0x00000000	   | \TT_S1_ATTR_BLOCK | \(1 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)mov x4, x21                // x4 = L1 页表基址指针 (x21 来自前段代码)#if 1	// enable after ddr ready
loop1:str x3, [x4], #8         // 存储每次的x3描述符到 L1 页表并后移指针add x3, x3, x2           // 物理地址增加 1GB (0x40000000)subs x1, x1, #1           // 递减计数器bne loop1                 // 循环直到 3 个条目配置完成
#else
loop1:add x4, x4, #8           // 仅移动指针 (不存储)add x3, x3, x2          // 物理地址增加 1GBsubs x1, x1, #1bne loop1
#endif// 配置 L1 页表中 C0000000-FFFFFFFF 区域的条目// C000 0000 - FFFF FFFF, point to level2 tabel, write to l1 tableorr x1, x22, #TT_S1_ATTR_PAGE  // 将 L2 表基址(x22)与页表描述符属性组合。TT_S1_ATTR_PAGE:页表描述符 (指向下级页表)str x1, [x4]              // 存储到 L1 页表 (指向 L2 页表)// 配置 L2 页表:DDR 区域 (C0000000-DFFFFFFF, 512MB)// level 2 table: C000 0000 - DFFF FFFF, 256 entries, 512MB DDR, 2MB blockldr x1, =256              // 256 个条目 (256 * 2MB = 512MB)ldr x2, =0x200000         // x2 = 2MB 地址增量 (块大小)// 构建 DDR 区域的 L2 块描述符:// - 物理地址基址: 0xC0000000// - 块描述符类型// - 内存属性索引 1 (普通内存)ldr x3, =(0xC0000000	   | \TT_S1_ATTR_BLOCK | \(1 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)mov x4, x22              // x4 = L2 页表基址指针 (x22)
loop2_ddr:str x3, [x4], #8          // 存储每次的x3到描述符到 L2 页表并后移指针add x3, x3, x2           // 物理地址增加 2MBsubs x1, x1, #1          // 递减计数器bne loop2_ddr            // 循环配置 256 个条目// 配置 L2 页表:OSPI0 Flash 区域 (E0000000-EFFFFFFF, 256MB)// level 2 table: E000 0000 - EFFF FFFF, 64 entries, 128MB OSPI0 flash, 2MB blockldr x1, =128              // 128 个条目 (128 * 2MB = 256MB)ldr x2, =0x200000         // 2MB 块大小// 构建 OSPI Flash 的 L2 块描述符:// - 物理地址基址: 0xE0000000// - 内存属性索引TT_S1_ATTR_MATTR_LSB 2 (通常用于设备内存)//AP_RW_PL1:特权读写权限//SH_INNER:内部可共享//AF:访问标志 (Access Flag)//nG:非全局映射ldr x3, =(0xE0000000	   | \TT_S1_ATTR_BLOCK | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop2_ospi0:str x3, [x4], #8         // 继续在 L2 页表存储 (紧接 DDR 区域之后)add x3, x3, x2         	 // 物理地址增加 2MBsubs x1, x1, #1           // 递减计数器bne loop2_ospi0           // 循环配置 128 个条目/*0x00000000 ~ 0xc0000000                          ----l10xc0000000 ~ 0xe0000000                          ----l20xe0000000 ~ 0xe8000000                          ----l2  DDR MEM0xe8000000 ~ 0xf0000000                          ----l2  DEVICE MEM0xf2200000 ~ 0xf23fffff rne_cfg                    ----l20xf4000000 ~ 0xf403ffff rne_mem 256kB             ----l20xf5000000 ~ 0xf5007fff GIC 32kB                   ----l20xf0000000 ~ 0xf0ffffff  rsv0xf1000000 ~ 0xf11fffff  peri                   -----2MB : l2 -> l3 3_10xf2000000 ~ 0xf21fffff  usb                    -----2MB : l2 -> l3 3_20xf2400000 ~ 0xf25fffff peri                     -----2MB : l2 -> l3 3_30xf2600000 ~ 0xf27fffff ddr gic noc acodec      -----0xf2600000 ~ 0xf26fffff 1MB : l2 -> l3 3_4// x21 = address of L1 tables// x22 = address of L2 tables// x23 = address of L3_1 tables// x24 = address of L3_2 tables// x25 = address of L3_3 tables// x26 = address of L3_4 tables地址转换:L2 索引:ubfx 提取位[29:21] (#21, #9)L3 索引:ubfx 提取位[20:12] (#12, #9)页表项位置:基址 + 索引 × 8 (lsl #3)*//*虚拟地址 (x2):31       21        12        0┌────────┬────────┬────────┐│  L2索引 │ L3索引 │  页内偏移 │└────────┴────────┴────────┘9位     9位     12位页表结构 (L2):x22 → ┌───────────┐ 基址│ 条目0      │├───────────┤│ 条目1      │├───────────┤│    ...    │├───────────┤│ 条目480    │ ← x22 + 480×8├───────────┤│    ...    │└───────────┘*/// 0xf4000000 ~ 0xf403ffff 区域:2MB 块映射 (普通内存)// F400 0000 - F403 FFFF, 1 entries, 2MB block, normal memory, RNE_MEM, 256KB acture, SRAM// 物理地址 + 属性ldr x1, =(0xF4000000	   | \TT_S1_ATTR_BLOCK | \(1 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)ldr x2, =0xF4000000  // 目标虚拟地址ubfx x3, x2, #21, #9            // 提取 L2 索引 (位[29:21]) ?str x1, [x22, x3, lsl #3]      // 写入 L2 页表 (x22) ?// 0xf2200000 ~ 0xf23fffff 区域:2MB 块映射 (设备内存)// F220 0000 - F23F FFFF, 1 entries, 2MB block, device, RNE_CFG1// 物理地址 + 属性ldr x1, =(0xF2200000	   | \TT_S1_ATTR_BLOCK | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)ldr x2, =0xF2200000            // 目标虚拟地址ubfx x3, x2, #21, #9         // 提取 L2 索引str x1, [x22, x3, lsl #3]      // 写入 L2 页表// 设置 L2 页表项:0xf1000000 ~ 0xf11fffff 指向 L3 页表 (x23)// level 2 table: 0xf1000000 ~ 0xf11fffff, 1 entry, point to level 3_1orr x1, x23, #TT_S1_ATTR_TABLE  // 组合 L3 基址和表描述符属性ldr x2, =0xF1000000             // 虚拟地址范围起始/*从 x2 的位 [21] 开始连续提取 9 位(位 [21] 到 [29])	将提取的 9 位值存入 x3,高位补零扩展在页表上下文中的意义:在 ARM64 页表系统中:	虚拟地址位 [29:21] 对应 L2 页表索引, 9 位索引可寻址 512 个条目 (2⁹ = 512)	, 该指令提取虚拟地址中的 L2 页表索引号*/ubfx x3, x2, #21, #9           // 提取 L2 索引str x1, [x22, x3, lsl #3]       // 写入 L2 页表// 设置 L2 页表项:0xf2000000 ~ 0xf21fffff 指向 L3 页表 (x24)// level 2 table: 0xf2000000 ~ 0xf21fffff, 1 entry, point to level 3_2orr x1, x24, #TT_S1_ATTR_TABLE  // 组合 L3 基址和表描述符属性ldr x2, =0xF2000000            // 虚拟地址范围起始ubfx x3, x2, #21, #9           // 提取 L2 索引str x1, [x22, x3, lsl #3]       // 写入 L2 页表 //目标地址 = x22 + (x3 << 3)// 设置 L2 页表项:0xf2400000 ~ 0xf25fffff 指向 L3 页表 (x25)// level 2 table: 0xf2400000 ~ 0xf25fffff, 1 entry, point to level 3_3orr x1, x25, #TT_S1_ATTR_TABLE  // 组合 L3 基址和表描述符属性ldr x2, =0xF2400000            // 虚拟地址范围起始ubfx x3, x2, #21, #9           // 提取 L2 索引str x1, [x22, x3, lsl #3]      // 写入 L2 页表// 设置 L2 页表项:0xf2600000 ~ 0xf27fffff 指向 L3 页表 (x26)// level 2 table: 0xf2600000 ~ 0xf27fffff, 1 entry, point to level 3_4orr x1, x26, #TT_S1_ATTR_TABLE  // 组合 L3 基址和表描述符属性ldr x2, =0xF2600000            // 虚拟地址范围起始ubfx x3, x2, #21, #9           // 提取 L2 索引str x1, [x22, x3, lsl #3]      // 写入 L2 页表// 设置 L2 页表项:F500 0000 - F500 7FFF 指向 L3 页表 (x27)// level 2 table: F500 0000 - F500 7FFF, 1 entry, point to level 3_5orr x1, x27, #TT_S1_ATTR_TABLE  // 组合 L3 基址和表描述符属性ldr x2, =0xF5000000            // 虚拟地址范围起始ubfx x3, x2, #21, #9           // 提取 L2 索引str x1, [x22, x3, lsl #3]      // 写入 L2 页表/*0xf1000000 ~ 0xf11fffff  peri                   -----2MB : l2 -> l3 3_10xf2000000 ~ 0xf21fffff  usb                    -----2MB : l2 -> l3 3_20xf2400000 ~ 0xf25fffff peri                     -----2MB : l2 -> l3 3_30xf2600000 ~ 0xf27fffff ddr gic noc acodec      -----0xf2600000 ~ 0xf26fffff 1MB : l2 -> l3 3_4
*/// 填充 L3 页表 (x23):0xf1000000 ~ 0xf11fffff 区域 (512 个 4KB 页)// level 3 table: 0xf1000000 ~ 0xf11fffff, 512 entry, x23// valid addr  0xf1000000 ~ 0xf11fffffldr x1, =0x1000                // 页大小:4KBldr x2, =((0xF11FFFFF + 1 - 0xF1000000) >> 12) // 计算页数ldr x3, =0xF1000000                        // 物理地址起始// 页描述符属性// 设备内存属性ldr x4, = (TT_S1_ATTR_PAGE | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop3_1:ubfx x5, x3, #12, #9            // 提取页内索引 (位[20:12])orr x6, x3, x4                // 组合物理地址和属性str x6, [x23, x5, lsl #3]       // 存储到 L3 页表 (x23)add x3, x3, x1                 // 移动到下一页subs x2, x2, #1               // 递减页计数器bne loop3_1                    // 循环直到所有页映射完成// 填充 L3 页表 (x24):0xf2000000 ~ 0xf21fffff 区域 (512 个 4KB 页)// level 3 table: 0xf2000000 ~ 0xf21fffff,, 512 entry, x24// valid addr  0xf2000000 ~ 0xf21fffffldr x1, =0x1000                 // 页大小:4KBldr x2, =((0xF21FFFFF + 1 - 0xF2000000) >> 12) // 计算页数ldr x3, =0xF2000000             // 物理地址起始// 设备内存属性ldr x4, = (TT_S1_ATTR_PAGE | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop3_2:ubfx x5, x3, #12, #9        // 提取页内索引orr x6, x3, x4              // 组合物理地址和属性str x6, [x24, x5, lsl #3]      // 存储到 L3 页表 (x24)add x3, x3, x1               // 下一页subs x2, x2, #1               // 递减页计数器bne loop3_2               // 循环// 填充 L3 页表 (x25):0xf2400000 ~ 0xf25fffff 区域 (512 个 4KB 页)// level 3 table: 0xf2400000 ~ 0xf25fffff, 512 entry, x25// valid addr  0xf2400000 ~ 0xf25fffffldr x1, =0x1000               // 页大小:4KBldr x2, =((0xF25FFFFF + 1 - 0xF2400000) >> 12) // 计算页数ldr x3, =0xF2400000             // 物理地址起始// 设备内存属性ldr x4, = (TT_S1_ATTR_PAGE | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop3_3:ubfx x5, x3, #12, #9          // 提取页内索引orr x6, x3, x4               // 组合物理地址和属性str x6, [x25, x5, lsl #3]      // 存储到 L3 页表 (x25)add x3, x3, x1            	// 下一页subs x2, x2, #1             // 递减页计数器bne loop3_3           		// 循环// 填充 L3 页表 (x26):0xf2600000 ~ 0xf27fffff 区域 (512 个 4KB 页)// level 3 table: 0xf2600000 ~ 0xf27fffff, 512 entry, x26// valid addr  0xf2600000 ~ 0xf27fffffldr x1, =0x1000               // 页大小:4KBldr x2, =((0xF27FFFFF + 1 - 0xF2600000) >> 12) // 计算页数ldr x3, =0xF2600000             // 物理地址起始// 设备内存属性ldr x4, = (TT_S1_ATTR_PAGE | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop3_4:ubfx x5, x3, #12, #9          // 提取页内索引orr x6, x3, x4               // 组合物理地址和属性str x6, [x26, x5, lsl #3]      // 存储到 L3 页表 (x26)add x3, x3, x1            	// 下一页subs x2, x2, #1             // 递减页计数器bne loop3_4           		// 循环// 填充 L3 页表 (x27):0xf5000000 ~ 0xf5007fff 区域 (512 个 4KB 页)// level 3 table: 0xf5000000 ~ 0xf5007fff, 512 entry, x27// valid addr  0xf5000000 ~ 0xf5007fffldr x1, =0x1000               // 页大小:4KBldr x2, =((0xF5007FFF + 1 - 0xF5000000) >> 12) // 计算页数ldr x3, =0xF5000000             // 物理地址起始// 设备内存属性ldr x4, = (TT_S1_ATTR_PAGE | \(2 << TT_S1_ATTR_MATTR_LSB) | \TT_S1_ATTR_NS | \TT_S1_ATTR_AP_RW_PL1 | \TT_S1_ATTR_SH_INNER | \TT_S1_ATTR_AF | \TT_S1_ATTR_nG)
loop3_5:ubfx x5, x3, #12, #9          // 提取页内索引orr x6, x3, x4               // 组合物理地址和属性str x6, [x27, x5, lsl #3]      // 存储到 L3 页表 (x27)add x3, x3, x1            	// 下一页subs x2, x2, #1             // 递减页计数器bne loop3_5           		// 循环ret.cfi_endproc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87812.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迁港战平 精神可胜国足

迁港战平可胜国足 江苏省城市足球联赛第6轮&#xff0c;宿迁队主场迎战连云港队。比赛中&#xff0c;宿迁队由张栋和高驰各入一球&#xff0c;连云港队则凭借穆家鑫与李团杰的进球连扳两城。最终双方以2比2握手言和。 第38分钟&#xff0c;张栋角球进攻中无人盯防推射破门&…

408第三季part2 - 计算机网络 - ip分布首部格式与分片

理解 好好看一下这个图 每行是4B&#xff0c;首部也不一定是20B&#xff0c;还有可选字段&#xff0c;可以变的更大 然后我们先看一下概念 然后这个生存时间每路过一个路由器就会扣1滴血 比如一开始是13&#xff0c;经过r1r2r3到B会变成10 但如果是2&#xff0c;经过第二个路…

详解String类不可变的底层原理

String类 String的基本特性 不可变性: String 对象一旦创建就不能被修改&#xff0c;所有看似修改的操作实际上都是创建新的 String 对象final类: String 类被声明为 final&#xff0c;不能被继承基于字符数组: 内部使用final char value[]存储字符数据(Java9以后改为byte[] …

GIT: 一个用于视觉与语言的生成式图像到文本转换 Transformer

摘要 在本文中&#xff0c;我们设计并训练了一个生成式图像到文本转换 Transformer——GIT&#xff0c;以统一视觉-语言任务&#xff0c;如图像/视频字幕生成和问答。虽然生成式模型在预训练和微调之间提供了一致的网络架构&#xff0c;但现有工作通常包含复杂的结构&#xff…

20250706-9-Docker快速入门(下)-Docker在线答疑_笔记

一、Kubernetes核心概念与集群搭建 1. 在线答疑 &#xfeff; 1&#xff09;答疑Docker需要掌握到什么程度 学习目标&#xff1a;达到入门水平即可&#xff0c;重点掌握第一章Docker入门视频内容学习建议&#xff1a;预习时间约3-4小时&#xff0c;建议吸收视频内容的80%学…

Node.js-http模块

HTTP 协议 概念 HTTP&#xff08;hypertext transport protocol&#xff09;协议&#xff1b;中文叫超文本传输协议,是一种基于TCP/IP的应用层通信协议这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。协议中主要规定了两个方面的内容 客户端&#xff1a;用来…

Java JDBC的初步了解

文章目录 基本流程注册驱动的两种方法DriverManagerDriverManager 的核心作用核心原理自动注册驱动的机制关键方法 示例代码: 连接Mysql数据库StatementPreparedStatement JDBC全称Java DataBase Connectivity。 定义: JDBC 是 Java 语言中用于连接和执行 SQL 操作的标准接口。…

[netty5: ChunkedInput ChunkedWriteHandler]-源码分析

ChunkedInput ChunkedInput<B> 是 Netty 中用于按块读取不定长数据流的接口&#xff0c;常配合 ChunkedWriteHandler 实现流式写入&#xff0c;支持如文件、流、HTTP 和 WebSocket 等多种数据源。 实现类简要说明ChunkedFile用于将常规文件按块传输&#xff08;使用传统…

QT 第十二讲 --- 控件篇 LineEdit,TextEdit与ComboBox

前言&#xff1a;欢迎进入 QT 控件世界的第十二讲&#xff01;在上一讲《QT 第十一讲 --- 控件篇 LCDnumber&#xff0c;ProgressBar与CalenderWidget》中&#xff0c;我们探索了用于信息展示和状态反馈的控件&#xff1a;精准的数字显示器 LCD Number、直观的进度指示器 Progr…

VSCode遇到的一些小毛病(自动保存、运行后光标不再处于编辑区)

1. 右键点击Run Code没有触发自动保存 1. 打开 VS Code 设置&#xff08;Ctrl ,&#xff09; 2. 搜索&#xff1a;code runner save 3. 勾选你需要的 2. 运行后光标仍然处于编辑区&#xff08;容易误输入&#xff09; 1. 打开 VS Code 设置&#xff08;Ctrl ,&#xff09; 2.…

Maixcam的使用2

1.单文件和项目&#xff08;多个 py 文件项目/模块化&#xff09;# 在编写代码时&#xff0c;一般两种模式&#xff0c;执行单个文件&#xff0c;或者执行一个完成项目&#xff08;包含多个 py 文件或者其它资源文件&#xff09;。 单文件模式&#xff1a;MaixVision 创建或者…

征信系统架构思想:打造商业信任基石_东方仙盟—仙盟创梦IDE

一、建设必要性在复杂的商业环境中&#xff0c;企业面临多元交易对象与业务场景&#xff0c;准确评估合作方信用状况及潜在价值的难度显著增加。传统经验判断和简单背景调查存在局限性&#xff0c;难以满足现代商业决策需求&#xff0c;因此构建科学的征信体系具有现实必要性。…

网安-XSS-pikachu

介绍 XSS&#xff0c;即跨站脚本攻击&#xff0c;是指攻击者利用Web服务器中的代码漏洞&#xff0c;在页面中嵌入客户端脚本&#xff08;通常是一段由JavaScript编写的恶意代码&#xff09;&#xff0c;当信任此Web服务器的用户访问 Web站点中含有恶意脚本代码的页面&#xff…

算法入门——字典树(C++实现详解)

字典树&#xff08;Trie&#xff09;是处理字符串匹配的高效数据结构&#xff0c;广泛应用于搜索提示、拼写检查等场景。本文将带你从零掌握字典树的原理与实现&#xff01; 一、什么是字典树&#xff1f; 字典树&#xff08;Trie&#xff09;是一种树形数据结构&#xff0c;…

SpringBoot整合SpringCache缓存

SpringBoot整合SpringCache使用缓存 文章目录SpringBoot整合SpringCache使用缓存1.介绍2.SpringBoot整合1.导入xml依赖2.配置yml3.使用EnableCaching启用SpringCache4.Cacheable5.CachePut6.CacheEvict7. Caching8.CacheConfig3.其他属性配置1.keyGenerator 属性2. cacheManage…

WPF学习笔记(20)Button与控件模板

Button与控件模板一、 Button默认控件模板详解二、自定义按钮模板一、 Button默认控件模板详解 WPF 中的大多数控件都有默认的控件模板。 这些模板定义了控件的默认外观和行为&#xff0c;包括控件的布局、背景、前景、边框、内容等。 官方文档&#xff1a;https://learn.mic…

蓝天居士自传(1)

蓝天居士何许人&#xff1f; 蓝天居士是我的笔名&#xff0c;也可以说是号。就好像李白号青莲居士、欧阳修号六一居士一样。笔者本名彭昊 —— 一个有不少重名重姓者的名字。 笔者小的时候上语文课&#xff0c;无论是小学、初中抑或是高中&#xff0c;都会有鲁迅&#xff08;…

短剧系统开发定制全流程解析:从需求分析到上线的专业指南

一、短剧行业数字化趋势与系统开发必要性在短视频内容爆发式增长的时代背景下&#xff0c;短剧作为一种新兴的内容形式正在迅速崛起。数据显示&#xff0c;2023年中国短剧市场规模已突破300亿元&#xff0c;用户规模达到4.5亿&#xff0c;年增长率超过200%。这一迅猛发展的市场…

getBoundingClientRect() 详解:精准获取元素位置和尺寸

getBoundingClientRect() 是 JavaScript 中一个强大的 DOM API&#xff0c;用于获取元素在视口中的精确位置和尺寸信息。它返回一个 DOMRect 对象&#xff0c;包含元素的坐标、宽度和高度等关键几何信息。 基本用法 const element document.getElementById(myElement); cons…

EXCEL 基础技巧

来源&#xff1a;WPS 官网 初步了解WPS表格-WPS学堂https://www.wps.cn/learning/course/detail/id/635.html 1、格式刷 1.1使用格式刷隔行填充颜色。 首先设置部分表格颜色&#xff0c;选中此区域&#xff0c;双击点击格式刷&#xff0c;然后选中其他表格区域。 这样就可以…