當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式與Linux那些事
[導(dǎo)讀]secure boot 和FIT Image是前段時(shí)間接觸到的,其實(shí)早就該總結(jié)下了,奈何懶癌犯了,拖了好久才寫出來。之前也有人問我,工作后最大的感受是什么?我的回答是:“快速學(xué)習(xí)”。

前言

secure boot 和FIT Image是前段時(shí)間接觸到的,其實(shí)早就該總結(jié)下了,奈何懶癌犯了,拖了好久才寫出來。

之前也有人問我,工作后最大的感受是什么?我的回答是:“快速學(xué)習(xí)”。

就嵌入式來講,大多數(shù)應(yīng)屆生在校期間可能都沒做過完整的項(xiàng)目,僅憑在校期間學(xué)習(xí)的內(nèi)容很難勝任公司的要求。

就底層驅(qū)動來講,雖然我之前也學(xué)習(xí)過韋東山老師的上s3c2440的課程,但是到了公司才發(fā)現(xiàn),這些內(nèi)容其實(shí)都已經(jīng)過時(shí)了。

但并不是說這些內(nèi)容都沒有必要去學(xué)習(xí)了。在學(xué)習(xí)的過程中,認(rèn)為最重要的是培養(yǎng)我們的自學(xué)能力。

很多初學(xué)者在剛開始學(xué)習(xí)時(shí),可能就敗在了搭建環(huán)境上。搭建環(huán)境時(shí)遇到問題不知道怎么辦?

我們?nèi)粘i_發(fā)中遇到的90%的問題,在網(wǎng)上都有人遇到過,也有相應(yīng)的解決辦法。學(xué)會利用bing,google,stackoverflow等搜索工具是一項(xiàng)很重要的技能。

如果遇到了網(wǎng)上沒有的問題怎么辦?軟件問題要先搞清楚原理,再去看代碼邏輯。硬件問題看官方手冊。像Linux kernel,ARM等都提供了完善的手冊,大部分問題在手冊中都有相應(yīng)說明。

好了,扯遠(yuǎn)了。下面回歸正題。

本文主要介紹了FIT Image起源,制作方法,its的語法結(jié)構(gòu),bootm 啟動FIT Image的方式。

本文這篇文章是對后面介紹的secure boot做鋪墊。ARMv8 secure boot一種實(shí)現(xiàn)的方式就是利用了FIT Image的特性。

zImage,uImage, Legacy uImage 和 FIT uImage

內(nèi)核經(jīng)過編譯后,會生成一個(gè)elf的可執(zhí)行程序,叫vmlinux,這個(gè)就是原始的未經(jīng)任何處理加工的原版內(nèi)核elf文件。不過,最終燒寫在嵌入式設(shè)備上的并不是這個(gè)文件。而是經(jīng)過objcopy工具加工后的專門用于燒錄的鏡像格式Image。

原則上Image就可以直接被燒錄到Flash上進(jìn)行啟動執(zhí)行,但linux的內(nèi)核開發(fā)者覺得Image還是太大了,因此對Image進(jìn)行了壓縮,并且在Image壓縮后的文件的前端附加了一部分解壓縮代碼,構(gòu)成了一個(gè)壓縮格式的鏡像文件就叫zImage。

解壓的時(shí)候,通過zImage鏡像頭部的解壓縮代碼進(jìn)行自解壓,然后執(zhí)行解壓出來的內(nèi)核鏡像。

Uboot要正確啟動Linux內(nèi)核,就需要知道內(nèi)核的一些信息,比如鏡像的類型(kernel image,dtb,ramdisk image),鏡像在內(nèi)存的位置,鏡像的鏈接地址,鏡像文件是否有壓縮等等。

Uboot為了拿到這些信息,發(fā)明了一種內(nèi)核格式叫uImage,也叫Legacy uImage。uImage是由zImage加工得到的,uboot中有一個(gè)工具mkimage,該工具會給zImage加一個(gè)64字節(jié)的header,將啟動內(nèi)核所需的信息存儲在header中。uboot啟動后,從header中讀取所需的信息,按照指示,進(jìn)行相應(yīng)的動作即可。

header格式可以參考:include/image.h。mkimage源碼在tools/mkimage

FIT image的來源

有了Legacy uImage后,為什么又搞出來一個(gè)FIT uImage呢?

在Linus Torvalds 看來,內(nèi)核中arch/arm/mach-xxx充斥著大量的垃圾代碼。因?yàn)閮?nèi)核并不關(guān)心板級細(xì)節(jié),比如板上的platform設(shè)備、resource、i2c_board_info、spi_board_info等等。大家有興趣可以看下s3c2410的板級目錄,代碼量在數(shù)萬行。

因此,ARM社區(qū)引入了Device Tree,使用Device Tree后,許多硬件的細(xì)節(jié)可以直接透過它傳遞給Linux,而不再需要在kernel中進(jìn)行大量的冗余編碼。

為了更好的支持單個(gè)固件的通用性,Uboot也需要對這種uImage固件進(jìn)行支持。FIT uImage中加入多個(gè)dtb文件 和ramdisk文件,當(dāng)然如果需要的話,同樣可以支持多個(gè)kernel文件。

內(nèi)核中的FDT全程為flattened device tree,F(xiàn)IT全稱叫flattened image tree。FIT利用了Device Tree Source files(DTS)的語法,生成的Image文件也和dtb文件類似(稱作itb)。

這樣的目的就是能夠使同一個(gè)uImage能夠在Uboot中選擇特定的kernel/dtb和ramdisk進(jìn)行啟動了,達(dá)成一個(gè)uImage可以通用多個(gè)板型的目的。

制作FIT Image

制作FIT Image需要用到兩個(gè)工具,mkimage和的dtc。dtc要導(dǎo)入到環(huán)境變量$PATH中,mkimage會調(diào)用dtc。

mkimage的輸入為 image source file,它定義了啟動過程中image的各種屬性,擴(kuò)展名為.its。its只是描述了Image的屬性,實(shí)際的Image data 是在uImage中,具體路徑由its指定。

如下是kernel 的its文件,后面會介紹各項(xiàng)內(nèi)容的含義。

/*
 * Simple U-Boot uImage source file containing a single kernel
 */

/dts-v1/;

/ {
 description = "Simple image with single Linux kernel"; #address-cells =; images {
  kernel@1 {
   description = "Vanilla Linux kernel";
   data = /incbin/("./vmlinux.bin.gz"); # Image data 具體路徑 type = "kernel";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "crc32";
   }; hash@2 {
    algo = "sha1";
   };
  };
 };

 configurations {
  default = "config@1";
  config@1 {
   description = "Boot Linux kernel";
   kernel = "kernel@1";
  };
 };
};

mkimage的輸出是一個(gè)后綴為.itb的二進(jìn)制文件,包含了所有需要的數(shù)據(jù)(kernel,dtb,ramdisk)。itb文件制作好之后,就可以直接加載到嵌入式設(shè)備上,通過bootm命令啟動。

總結(jié)下制作FIT Image的4個(gè)必要文件:

  • mkimage,
  • dtc
  • its(image source file (*.its))
  • image data file(s)。

its語法結(jié)構(gòu)

uImage Tree 的根節(jié)點(diǎn)結(jié)構(gòu)

/ o image-tree
    |- description = "image description" |- timestamp =|- #address-cells = |
    o images
    | |
    | o image@1 {...}
    | o image@2 {...}
    | ...
    |
    o configurations
      |- default = "conf@1" |
      o conf@1 {...}
      o conf@2 {...}
      ...
  • description:描述uImage的文本。

  • timestamp:修改Image鏡像的時(shí)間,由mkimage工具自動生成。在security boot中,timestamp不同也會被認(rèn)為是不同的Image。

  • images:子鏡像,如kernel Image,ramdisk Image。

  • configurations:配置項(xiàng)節(jié)點(diǎn),可以將不同類型的二進(jìn)制文件,根據(jù)不同的場景,組合起來,形成一個(gè)個(gè)的配置項(xiàng)。u-boot在boot的時(shí)候,以配置項(xiàng)為單位加載、執(zhí)行,這樣就可以根據(jù)不同的場景,方便的選擇不同的配置。

'/images' node

該節(jié)點(diǎn)中描述了Image鏡像必要的信息.

o image@1
   |- description = "component sub-image description" |- data = /incbin/("path/to/data/file.bin")
   |- type = "sub-image type name" |- arch = "ARCH name" |- os = "OS name" |- compression = "compression name" |- load =|- entry =|
   o hash@1 {...}
   o hash@2 {...}
   ...
  • description:子鏡像的文本描述,可以隨便寫。

  • type:子鏡像的類型,比如standalone,kernel,ramdisk,firmware等等。

  • data:包含該節(jié)點(diǎn)二進(jìn)制文件的路徑。

  • compression:壓縮方式,比如none,gzip,bzip2。

  • os:操作系統(tǒng)的名稱,如solaris,uboot,qnx等。

  • arch:平臺架構(gòu),如arm,mips,i386等。

  • entry:二進(jìn)制文件入口地址,即鏈接地址。

  • load:二進(jìn)制文件的加載位置。

  • hash@1:鏡像使用的校驗(yàn)算法,如sha256,crc32等。

Hash nodes

o hash@1
  |- algo = "hash or checksum algorithm name" |- value = [hash or checksum value]
  • algo:算法名稱,如crc32,md5,sha256等。

  • value:算法校驗(yàn)值,即algo計(jì)算后的數(shù)值。

'/configurations' node

o configurations
  |- default = "default configuration sub-node unit name" |
  o config@1 {...}
  o config@2 {...}
  ...
  • default:默認(rèn)的子節(jié)點(diǎn)的配置

  • config@1: 該配置具體使用那些kernel Image,ramdisk Image等。

Configuration nodes

o config@1
  |- description = "configuration description" |- kernel = "kernel sub-node unit name" |- ramdisk = "ramdisk sub-node unit name" |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", ...]
  |- fpga = "fpga sub-node unit-name" |- loadables = "loadables sub-node unit-name" 
  • description:該配置的名稱。

  • kernel:鏡像類型為kernel的單元的名稱。

  • ramdisk:鏡像類型為ramdisk的單元的名稱。

  • fdt:鏡像類型為fdt的單元的名稱。

  • loadables:額外的可加載的二進(jìn)制文件的列表,U-Boot將在給定的起始地址加載每個(gè)二進(jìn)制文件。

舉例

如下是一個(gè)有多種kernels, ramdisks and FDT blobs鏡像多套配置的its文件。它包含了3種配置,每種配置使用了不同的kernel、ramdisk和fdt,默認(rèn)配置項(xiàng)由“default”指定,當(dāng)然也可以在運(yùn)行時(shí)指定。

/*
 * U-Boot uImage source file with multiple kernels, ramdisks and FDT blobs
 */

/dts-v1/;

/ {
 description = "Various kernels, ramdisks and FDT blobs"; #address-cells =; images {
  kernel@1 {
   description = "vanilla-2.6.23";
   data = /incbin/("./vmlinux.bin.gz"); type = "kernel";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "md5";
   }; hash@2 {
    algo = "sha1";
   };
  };

  kernel@2 {
   description = "2.6.23-denx";
   data = /incbin/("./2.6.23-denx.bin.gz"); type = "kernel";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "sha1";
   };
  };

  kernel@3 {
   description = "2.4.25-denx";
   data = /incbin/("./2.4.25-denx.bin.gz"); type = "kernel";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "md5";
   };
  };

  ramdisk@1 {
   description = "eldk-4.2-ramdisk";
   data = /incbin/("./eldk-4.2-ramdisk"); type = "ramdisk";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "sha1";
   };
  };

  ramdisk@2 {
   description = "eldk-3.1-ramdisk";
   data = /incbin/("./eldk-3.1-ramdisk"); type = "ramdisk";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "crc32";
   };
  };

  fdt@1 {
   description = "tqm5200-fdt";
   data = /incbin/("./tqm5200.dtb"); type = "flat_dt";
   arch = "ppc";
   compression = "none"; hash@1 {
    algo = "crc32";
   };
  };

  fdt@2 {
   description = "tqm5200s-fdt";
   data = /incbin/("./tqm5200s.dtb"); type = "flat_dt";
   arch = "ppc";
   compression = "none";
   load =; hash@1 {
    algo = "sha1";
   };
  };

 };

 configurations {
  default = "config@1";

  config@1 {
   description = "tqm5200 vanilla-2.6.23 configuration";
   kernel = "kernel@1";
   ramdisk = "ramdisk@1";
   fdt = "fdt@1";
  };

  config@2 {
   description = "tqm5200s denx-2.6.23 configuration";
   kernel = "kernel@2";
   ramdisk = "ramdisk@1";
   fdt = "fdt@2";
  };

  config@3 {
   description = "tqm5200s denx-2.4.25 configuration";
   kernel = "kernel@3";
   ramdisk = "ramdisk@2";
  };
 };
};

FIT Image的編譯和啟動

在服務(wù)器上,可以使用mkimage工具制作 FIT Image。

如下是kernel_fdt.its,下面將使用該文件制作itb。

/*
 * Simple U-Boot uImage source file containing a single kernel and FDT blob
 */

/dts-v1/;

/ {
 description = "Simple image with single Linux kernel and FDT blob"; #address-cells =; images {
  kernel@1 {
   description = "Vanilla Linux kernel";
   data = /incbin/("./vmlinux.bin.gz"); type = "kernel";
   arch = "ppc";
   os = "linux";
   compression = "gzip";
   load =;
   entry =; hash@1 {
    algo = "crc32";
   }; hash@2 {
    algo = "sha1";
   };
  };
  fdt@1 {
   description = "Flattened Device Tree blob";
   data = /incbin/("./target.dtb"); type = "flat_dt";
   arch = "ppc";
   compression = "none"; hash@1 {
    algo = "crc32";
   }; hash@2 {
    algo = "sha1";
   };
  };
 };

 configurations {
  default = "conf@1";
  conf@1 {
   description = "Boot Linux kernel with FDT blob";
   kernel = "kernel@1";
   fdt = "fdt@1";
  };
 };
};
$ mkimage -f kernel_fdt.its kernel_fdt.itb
DTC: dts->dtb  on file "kernel_fdt.its" $
$ mkimage -l kernel_fdt.itb
FIT description: Simple image with single Linux kernel and FDT blob
Created:  Tue Mar 11 16:29:22 2008
 Image 0 (kernel@1)
  Description: Vanilla Linux kernel
  Type:  Kernel Image
  Compression: gzip compressed
  Data Size: 1092037 Bytes = 1066.44 kB = 1.04 MB
  Architecture: PowerPC
  OS:  Linux
  Load Address: 0x00000000
  Entry Point: 0x00000000
  Hash algo: crc32
  Hash value: 2c0cc807
  Hash algo: sha1
  Hash value: 264b59935470e42c418744f83935d44cdf59a3bb
 Image 1 (fdt@1)
  Description: Flattened Device Tree blob
  Type:  Flat Device Tree
  Compression: uncompressed
  Data Size: 16384 Bytes = 16.00 kB = 0.02 MB
  Architecture: PowerPC
  Hash algo: crc32
  Hash value: 0d655d71
  Hash algo: sha1
  Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def
 Default Configuration: 'conf@1' Configuration 0 (conf@1)
  Description: Boot Linux kernel with FDT blob
  Kernel: kernel@1
  FDT:  fdt@1

在當(dāng)前目錄下就可以找到kernel_fdt.itb,itb文件就可以加載到設(shè)備上啟動。

> tftp 900000 /path/to/tftp/location/kernel_fdt.itb
Using FEC device
TFTP from server 192.168.1.1; our IP address is 192.168.160.5
Filename '/path/to/tftp/location/kernel_fdt.itb'.
Load address: 0x900000
Loading: ################################################################# ########### done Bytes transferred = 1109776 (10ef10 hex)
=> iminfo ## Checking Image at 00900000 ... FIT image found
   FIT description: Simple image with single Linux kernel and FDT blob
   Created:     2008-03-11 15:29:22 UTC
    Image 0 (kernel@1)
     Description:  Vanilla Linux kernel
     Type:    Kernel Image
     Compression:  gzip compressed
     Data Start:   0x009000ec
     Data Size:    1092037 Bytes =  1 MB
     Architecture: PowerPC
     OS:    Linux
     Load Address: 0x00000000
     Entry Point:  0x00000000
     Hash algo:    crc32
     Hash value:   2c0cc807
     Hash algo:    sha1
     Hash value:   264b59935470e42c418744f83935d44cdf59a3bb
    Image 1 (fdt@1)
     Description:  Flattened Device Tree blob
     Type:    Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x00a0abdc
     Data Size:    16384 Bytes = 16 kB
     Architecture: PowerPC
     Hash algo:    crc32
     Hash value:   0d655d71
     Hash algo:    sha1
     Hash value:   25ab4e15cd4b8a5144610394560d9c318ce52def
    Default Configuration: 'conf@1' Configuration 0 (conf@1)
     Description:  Boot Linux kernel with FDT blob
     Kernel:    kernel@1
     FDT:    fdt@1
=> bootm ## Booting kernel from FIT Image at 00900000 ... Using 'conf@1' configuration
   Trying 'kernel@1' kernel subimage
     Description:  Vanilla Linux kernel
     Type:    Kernel Image
     Compression:  gzip compressed
     Data Start:   0x009000ec
     Data Size:    1092037 Bytes =  1 MB
     Architecture: PowerPC
     OS:    Linux
     Load Address: 0x00000000
     Entry Point:  0x00000000
     Hash algo:    crc32
     Hash value:   2c0cc807
     Hash algo:    sha1
     Hash value:   264b59935470e42c418744f83935d44cdf59a3bb
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Uncompressing Kernel Image ... OK ## Flattened Device Tree from FIT Image at 00900000 Using 'conf@1' configuration
   Trying 'fdt@1' FDT blob subimage
     Description:  Flattened Device Tree blob
     Type:    Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x00a0abdc
     Data Size:    16384 Bytes = 16 kB
     Architecture: PowerPC
     Hash algo:    crc32
     Hash value:   0d655d71
     Hash algo:    sha1
     Hash value:   25ab4e15cd4b8a5144610394560d9c318ce52def
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0xa0abdc
   Loading Device Tree to 007fc000, end 007fffff ... OK
[    0.000000] Using lite5200 machine description
[    0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008 

bootm啟動不同的配置

對于FIT Image,bootm有多種啟動方式。

1. bootm2. bootm []:3. bootm []#[# 4. bootm []:[]:5. bootm []:[]:[]:6. bootm []:[]:7. bootm []:-     []:8. bootm []:-

對于有多種鏡像,多套配置的itb,都是以configurations 中default 指定的配置啟動。

bootm 200000

也可以手動指定使用那套配置

bootm 200000#cfg@1 

也可以手動搭配不同的鏡像節(jié)點(diǎn)啟動

bootm 200000:kernel@1 800000:ramdisk@2
bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1
bootm 200000:kernel@2 200000:ramdisk@2 600000
bootm 200000:kernel@2 - 200000:fdt@1

如果bootm的時(shí)候不指定地址,則會使用CONFIG_SYS_LOAD_ADDR配置的地址。

總結(jié)

本文對FIT Image作了簡單的介紹,更詳細(xì)的內(nèi)容可以參考官方文檔。后面有時(shí)間會動手制作一個(gè)FIT Image在板子上跑下。

FIT Image可以兼容于多種板子,而無需重新進(jìn)行編譯燒寫。對于有多個(gè)kernel節(jié)點(diǎn)或者fdt節(jié)點(diǎn)等等,兼容性更強(qiáng)。同時(shí),可以有多種configurations,來對kernel、fdt、ramdisk來進(jìn)行組合。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉