【U-Boot笔记整理】U-Boot 完全分析与移植

1. 大纲

大概内容如下:

  • u-boot功能概述
    • 目的
    • 功能细分
  • u-boot源码结构
  • u-boot的配置、编译、连接过程
    • Makefile深入练习
    • 分析u-boot的Makefile
    • u-boot可执行程序的组成
  • u-boot源码分析
    • SPL与第1阶段
    • 第2阶段
    • 核心:命令
    • 让u-boot的使用更加便利:env
  • u-boot的设备树
  • u-boot实战
    • 移植其他版本的u-boot
    • 修改设备树支持网卡

2. u-boot核心功能

就是启动内核:

  • 读Flash,把内核读入内存
  • 启动内核

3. 配置u-boot的过程分析

3.1 源码结构

在u-boot目录下执行"tree . -d > 1.txt",可以得到目录的结构,精简如下:

├── arch    
│   ├── arm              // 1. 架构相关
│   │   ├── cpu
│   │   │   ├── armv7
│   │   │   │   ├── mx6
│   │   ├── dts
│   │   │   └── include
│   │   │       └── dt-bindings -> ../../../../include/dt-bindings
│   │   ├── include
│   │   │   ├── asm
│   │   │   │   ├── arch-imx
│   │   │   │   ├── arch-imx8
│   │   │   │   ├── arch-imx8m
│   │   │   │   ├── imx-common
│   │   │   └── debug
│   │   ├── lib
│   │   ├── mach-rockchip
│   │   │   ├── rk3036
│   │   │   ├── rk3288
│   │   │   └── rk3399
│   │   ├── lib
├── board             // 单板相关
│   ├── freescale
│   │   ├── common
│   │   │   └── p_corenet
│   │   ├── corenet_ds
│   │   ├── mx6ul_14x14_ddr3_arm2
│   │   ├── mx6ul_14x14_evk
│   │   ├── mx6ul_14x14_lpddr2_arm2
│   │   ├── mx6ull_ddr3_arm2
│   │   ├── mx6ullevk
├── cmd                   // 通用的命令
│   ├── fastboot
│   └── mvebu
├── common                // 通用的
│   ├── eeprom
│   ├── init
│   └── spl
├── configs
├── disk
├── drivers               // 各类驱动
├── fs                    // 文件系统
│   ├── cbfs
│   ├── cramfs
│   ├── ext4
│   ├── fat
│   ├── jffs2
│   ├── reiserfs
│   ├── sandbox
│   ├── ubifs
│   ├── yaffs2
│   └── zfs
├── include
├── lib                  // 库
├── net                  // 网络协议

3.2 Makefile分析

3.2.1 基础知识

文档:本Git仓库01_all_series_quickstart\04_嵌入式Linux应用开发基础知识\doc_pic\04.2018_Makefile

3.2.2 make的技巧

打印Makefile的规则和变量:make -p

可以把make命令规则和变量存入文件:make -p > 1.txt

然后执行vi 1.txt,使用vi命令删除注释::g/^#/d

3.3 u-boot的默认配置

3.3.1 默认配置的过程

IMX6ULL: make mx6ull_14x14_evk_defconfig

STM32MP157: make stm32mp15_trusted_defconfig

执行过程:

  • 制作工具:scripts/kconfig/conf
  • 把默认配置信息写入文件".config"
    在这里插入图片描述

分析过程:

mx6ull_14x14_evk_defconfig: scripts/kconfig/conf$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

就是:

UBOOTVERSION=2017.03 scripts/kconfig/conf --defconfig=arch/../configs/mx6ull_14x14_evk_defconfig Kconfig

3.3.2 conf命令概述

总体分析:scripts/kconfig/conf.c

更详细的配置过程:make mx6ull_14x14_evk_defconfig V=1

在这里插入图片描述

defconfig_file = "arch/../configs/mx6ull_14x14_evk_defconfig";
name = "Kconfig"conf_parse(name);  // 解析uboot根目录下的Kconfig文件conf_read(defconfig_file); // 读配置文件conf_set_all_new_symbols(def_default); // 设置new_symbols为默认值conf_write(NULL); // 写到.config
  • Kconfig:这是一个通用文件,里面规定了一些依赖,比如:
    • 如果是ARM架构,就默认选中A、B、C配置
    • 如果是RISC-V架构,就默认选中a、b、c配置
  • defconfig_file:这是厂家提供的,里面定义了
    • ARM架构
    • 自己的一些配置项
  • 怎么处理呢?
    • 使用defconfig_file的内容去解析Kconfig,确定各个依赖的配置项
    • 其他未涉及的配置项,给它们指定默认值
    • 写入.config

3.3.3 conf命令详解

深入分析:scripts/kconfig/conf.c

3.4. Kconfig介绍

参考文档:

任一个Linux内核的Documentation\kbuild\kconfig-language.rsthttps://www.rt-thread.org/document/site/programming-manual/kconfig/kconfig/

对于各类内核,只要支持menuconfig配置界面,都是使用Kconfig。
在配置界面中,可以选择、设置选项,这些设置会保存在.config文件里。
编译脚本会包含.config,根据里面的值决定编译哪些文件、怎么编译文件。
.config文件也会被转换为头文件,C程序可以从头文件中获得配置信息。

1.1 配置界面示例

在这里插入图片描述

问题:

  • 这个界面里,各个配置项来自哪里
  • 这个界面里,这些配置项是怎么组织的
  • 这个界面里,我们的选择、设置,结果保存在哪里
  • 这些配置结果,怎么使用

1.2 配置结果的保存

1.2.1 示例

在配置界面中操作的结果保存在.config文件中,示例如下:

#
# Automatically generated file; DO NOT EDIT.
# U-Boot  Configuration
#
CONFIG_CREATE_ARCH_SYMLINK=y
# CONFIG_ARC is not set
CONFIG_ARM=y
# CONFIG_AVR32 is not set
# CONFIG_BLACKFIN is not set
# CONFIG_M68K is not set
# CONFIG_MICROBLAZE is not set
# CONFIG_MIPS is not set
# CONFIG_NDS32 is not set
# CONFIG_NIOS2 is not set
# CONFIG_OPENRISC is not set
# CONFIG_PPC is not set
# CONFIG_SANDBOX is not set
# CONFIG_SH is not set
# CONFIG_SPARC is not set
# CONFIG_X86 is not set
# CONFIG_XTENSA is not set
CONFIG_SYS_ARCH="arm"
CONFIG_SYS_CPU="armv7"
CONFIG_SYS_SOC="mx6"
CONFIG_SYS_VENDOR="freescale"
CONFIG_SYS_BOARD="mx6ullevk"
CONFIG_SYS_CONFIG_NAME="mx6ullevk"#
# ARM architecture
#
CONFIG_HAS_VBAR=y
CONFIG_HAS_THUMB2=y
CONFIG_CPU_V7=y
CONFIG_SYS_ARM_ARCH=7
CONFIG_SYS_CACHE_SHIFT_6=y
CONFIG_SYS_CACHELINE_SIZE=64

编译脚本会包含.config文件,它会根据里面的变量比如CONFIG_CPU_V7选择u-boot特性。

1.2.2 配置项的前缀

在Kconfig文件中,假设配置项的名字是XXX,在.config文件中:

  • 默认情况下,它对应的变量名为CONFIG_XXX
  • 如果设置了环境变量CONFIG_=ABC,则对应的变量名为ABC_XXX

1.3 描述单个配置项config

1.3.1 示例

menuconfig界面,可以看到这个配置项:

在这里插入图片描述

在配置界面,使用方向箭头游走到Display information about the CPU during start up后,可以:

  • 输入Y,选择配置项,在.config中对应CONFIG_DISPLAY_CPUINFO=y

  • 输入N,不选择配置项,在.config中对应# CONFIG_DISPLAY_CPUINFO is not set

上图中的配置项怎么实现的?
在common/Kconfig文件中,它对应下列代码:

在这里插入图片描述

1.3.2 语法

上面是一个精简的例子,完整的例子可以从Linux中获得,如下:

config SGI_SNSCbool "SGI Altix system controller communication support"depends on (IA64_SGI_SN2 || IA64_GENERIC)default yhelpIf you have an SGI Altix and you want to enable systemcontroller communication from user space (you want this!),say Y.  Otherwise, say N.

解释如下:

  • config
    表示config option,这是Kconfig的基本entry;其他entry是用来管理config的。
    config 表示一个配置选项的开始,紧跟着的 SGI_SNSC 是配置选项的名称。
    config 下面几行定义了该配置选项的属性。
    属性可以是该配置选项的:类型、输入提示、依赖关系、默认值、帮助信息。
    • bool 表示配置选项的类型,每个 config 菜单项都要有类型定义,变量有5种类型
      • bool 布尔类型
      • tristate 三态类型
      • string 字符串
      • hex 十六进制
      • int 整型
    • “SGI Altix system controller communication support”:提示信息
    • depends on:表示依赖关系,只有(IA64_SGI_SN2 || IA64_GENERIC)被选中,才可以选择SGI_SNSC
    • select XXX:表示反向依赖关系,即当前配置选项被选中后,XXX选项就会被选中。
    • default 表示配置选项的默认值,bool 类型的默认值可以是 y/n。
    • help 帮助信息,在menuconfig界面输入H键时,就会提示帮助信息。

1.4 实现菜单menu/endmenu

1.4.1 示例

示例代码:rt-smart/kernel/src/Kconfig,代码如下:

menu "Boot media"config NOR_BOOTbool "Support for booting from NOR flash"depends on NORhelpEnabling this will make a U-Boot binary that is capable of beingbooted via NOR.  In this case we will enable certain pinmux earlyas the ROM only partially sets up pinmux.  We also default to usingNOR for environment.config NAND_BOOTbool "Support for booting from NAND flash"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via NAND flash. This is not a must, some SoCs need this,some not.config ONENAND_BOOTbool "Support for booting from ONENAND"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via ONENAND. This is not a must, some SoCs need this,some not.config QSPI_BOOTbool "Support for booting from QSPI flash"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via QSPI flash. This is not a must, some SoCs need this,some not.config SATA_BOOTbool "Support for booting from SATA"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via SATA. This is not a must, some SoCs need this,some not.config SD_BOOTbool "Support for booting from SD/EMMC"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via SD/EMMC. This is not a must, some SoCs need this,some not.config SPI_BOOTbool "Support for booting from SPI flash"default nhelpEnabling this will make a U-Boot binary that is capable of beingbooted via SPI flash. This is not a must, some SoCs need this,some not.endmenu

界面如下:

在这里插入图片描述

1.4.2 语法

解释如下:

  • menu “xxx"表示一个菜单,菜单名是"xxx”

  • menu和endmenu之间的entry都是"xxx"菜单的选项

  • 在上面的例子中子菜单有6个选项:

    在这里插入图片描述

1.5 实现单选choice/endchoice

1.5.1 示例

示例代码:rt-smart/kernel/src/Kconfig,代码如下:

config DEBUG_UARTbool "Enable an early debug UART for debugging"helpThe debug UART is intended for use very early in U-Boot to debugproblems when an ICE or other debug mechanism is not available.choiceprompt "Select which UART will provide the debug UART"depends on DEBUG_UARTdefault DEBUG_UART_NS16550config DEBUG_UART_ALTERA_JTAGUARTbool "Altera JTAG UART"helpSelect this to enable a debug UART using the altera_jtag_uart driver.You will need to provide parameters to make this work. The driver willbe available until the real driver model serial is running.config DEBUG_UART_ALTERA_UARTbool "Altera UART"helpSelect this to enable a debug UART using the altera_uart driver.You will need to provide parameters to make this work. The driver willbe available until the real driver model serial is running.endchoice

界面如下:

在这里插入图片描述

在上述界面中,设置了DEBUG_UART,才有后续的"选择菜单"。

1.5.2 语法

解释如下:

  • choice表示"选择"
  • choice和endchoice之间的entry是可以选择的项目
    • 它们之间,只能有一个被设置为"y":表示编进内核
    • 它们之间,可以设置多个为"m":表示编译为模块
    • 比如一个硬件有多个驱动程序
      • 同一时间只能有一个驱动能编进内核
      • 但是多个驱动都可以单独编译为模块

1.6 menuconfig

menuconfig XXXconfig XXX类似,
唯一不同的是该选项除了能设置y/m/n外,还可以实现菜单效果(能回车进入该项内部)。

1.6.1 示例

示例代码:Kconfig

menuconfig EXPERTbool "Configure standard U-Boot features (expert users)"default yhelpThis option allows certain base U-Boot options and settingsto be disabled or tweaked. This is for specializedenvironments which can tolerate a "non-standard" U-Boot.Use this only if you really know what you are doing.if EXPERTconfig SYS_MALLOC_CLEAR_ON_INITbool "Init with zeros the memory reserved for malloc (slow)"default yhelpThis setting is enabled by default. The reserved mallocmemory is initialized with zeros, so first malloc callswill return the pointer to the zeroed memory. But thisslows the boot time.It is recommended to disable it, when CONFIG_SYS_MALLOC_LENvalue, has more than few MiB, e.g. when uses bzip2 or bmp logo.Then the boot time can be significantly reduced.Warning:When disabling this, please check if malloc calls, maybeshould be replaced by calloc - if one expects zeroed memory.config TOOLS_DEBUGbool "Enable debug information for tools"helpEnable generation of debug information for tools such as mkimage.This can be used for debugging purposes. With debug informationit is possible to set breakpoints on particular lines, single-stepdebug through the source code, etc.endif # EXPERT

界面如下:

在这里插入图片描述

1.6.2 语法

menuconfig常用格式有2种:

  menuconfig Mif Mconfig C1config C2endif

或:

  menuconfig Mconfig C1depends on Mconfig C2depends on M

第1项menuconfig Mconfig M语法是一样的,
不同之处在于menuocnfig M后面可以跟着好几个依赖于M的config C1config C2等子配置项。

1.7 if/endif

1.7.1 语法

在上面的menuconfig中就有if/endif的使用,它的语法如下:

"if" <expr>
<if block>
"endif"
1.7.2 示例

示例如下,只有定义了的EXPERT项,SYS_MALLOC_CLEAR_ON_INIT等才会显示出来:

if EXPERTconfig SYS_MALLOC_CLEAR_ON_INITbool "Init with zeros the memory reserved for malloc (slow)"default yhelpThis setting is enabled by default. The reserved mallocmemory is initialized with zeros, so first malloc callswill return the pointer to the zeroed memory. But thisslows the boot time.It is recommended to disable it, when CONFIG_SYS_MALLOC_LENvalue, has more than few MiB, e.g. when uses bzip2 or bmp logo.Then the boot time can be significantly reduced.Warning:When disabling this, please check if malloc calls, maybeshould be replaced by calloc - if one expects zeroed memory.config TOOLS_DEBUGbool "Enable debug information for tools"helpEnable generation of debug information for tools such as mkimage.This can be used for debugging purposes. With debug informationit is possible to set breakpoints on particular lines, single-stepdebug through the source code, etc.endif # EXPERT

1.8 source

source 语句用于读取另一个文件中的 Kconfig 文件,
比如Kconfig中就包含了其他Kconfig:

source "arch/Kconfig"

1.9 comment

comment 语句出现在界面的第一行,用于定义一些提示信息,如cmd/Kconfig

comment "Commands"

界面如下:
在这里插入图片描述

1.10 测试代码

1.10.1 config
config 100ASKbool "test for 100ask"default yhelpjust for Kconfig test
1.10.2 menu(多选)
menu "100ASK menu"config IMX6ULL_TESTtristate "menu test item 1 IMX6ULL"helpjust for test menu.config STM32MP157_TESTtristate "menu test item 2 IMX6ULLh"helpjust for test menu.
endmenu
1.10.3 choice(单选)
config CHOICE_ON_100ASKbool "Enable choice for 100ask"helpEnable choice for 100askchoiceprompt "choice test for 100ask"depends on CHOICE_ON_100ASKconfig CHOICE_ITEM1bool "CHOICE_ITEM1"helpCHOICE_ITEM1.config CHOICE_ITEM2bool "CHOICE_ITEM2"helpCHOICE_ITEM2.endchoice
1.10.4 menuconfig
menuconfig 100ASK_MENUCFGbool "test for menuconfig of 100ask"if 100ASK_MENUCFG
config IMX6ULL_TEST_MENUCFGtristate "menuconfig test item 1 IMX6ULL"helpjust for test menuconfig.config STM32MP157_MENUCFGtristate "menuconfig test item 2 IMX6ULLh"helpjust for test menuconfig.
endif
menu "test menu"
config TEST_Abool "TEST A"default yconfig TEST_Bbool "TEST B"default yendmenuchoiceprompt "test choise"default TEST_Cconfig TEST_Cbool "TEST C"default yconfig TEST_Dbool "TEST D"default yendchoice        menuconfig TEST_MENUCONFIGbool "test menuconfig"default nif TEST_MENUCONFIG
config TEST_Ebool "TEST E"default yconfig TEST_Fbool "TEST F"default yendif

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

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

相关文章

飞花令游戏(Python)

飞花令是古时候人们经常玩一种“行酒令”的游戏&#xff0c;是中国古代酒令之一&#xff0c;属雅令。“飞花”一词则出自唐代诗人韩翃《寒食》中 春城无处不飞花 一句。行飞花令时选用诗和词&#xff0c;也可用曲&#xff0c;但选择的句子一般不超过7个字。 在《中国诗词大会》…

便利店小程序可以做哪些营销活动呢

在当今这个数字化时代&#xff0c;微信小程序已经成为了人们日常生活的一部分。对于便利店来说&#xff0c;拥有一个优秀的小程序不仅可以提高销售&#xff0c;还可以扩大品牌影响力&#xff0c;增加客户粘性。本文将探讨便利店小程序可以做什么样的营销活动&#xff0c;如何利…

机器学习 - 混淆矩阵:技术与实战全方位解析

目录 一、引言1.1 什么是混淆矩阵&#xff1f;1.2 为什么需要混淆矩阵&#xff1f; 二、基础概念TP, TN, FP, FN解释True Positive (TP)True Negative (TN)False Positive (FP)False Negative (FN) 常见评价指标 三、数学原理条件概率与贝叶斯定理ROC与AUC敏感性与特异性阈值选…

专业课138,总分390+,西工大,西北工业大学827信号与系统考研分享

数学一 考研数学其实严格意义上已经没有难度大小年之分了&#xff0c;说21年难的会说22年简单&#xff0c;说22年简单的做23年又会遭重&#xff0c;所以其实只是看出题人合不合你的口味罢了&#xff0c;建议同学不要因偶数年而畏惧&#xff0c;踏踏实实复习。资料方面跟谁就用…

【算法1-4】递推与递归-P1002 [NOIP2002 普及组] 过河卒

## 题目描述 棋盘上 A 点有一个过河卒&#xff0c;需要走到目标 B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#…

关于导出的Excel文件的本质

上篇文章中提到关于xlsx改造冻结窗格的代码&#xff0c;我是怎么知道要加pane的呢&#xff0c;加下来就把我的心路历程记录一下。 我改造之前也是没有头绪的&#xff0c;我网上查了很多&#xff0c;只告诉我如何使用&#xff0c;但源码里没有针对!freeze的处理&#xff0c;所以…

探寻JWT的本质:它是什么?它有什么作用?

JWT&#xff08;JSON Web Token&#xff09;是一种基于 JSON 格式的轻量级令牌&#xff08;token&#xff09;协议&#xff0c;它被广泛应用于网络应用程序的身份验证和授权。相较于传统的 session-based 认证机制&#xff0c;JWT 具有更好的扩展性和互操作性&#xff0c;同时也…

压力山大题

找不到工作的面试者总结 提示&#xff1a;写文章的时候&#xff0c;我还在找工作&#xff01;&#xff01;&#xff01; 文章目录 找不到工作的面试者总结前言一、JAVA面死题1. OOP是什么2. 重载与重写的区别3. java基本类型4. String、StringBuffer、StringBuilder的区别5. 接…

word写论文遇到数字和文字中间空格删不掉

一、如何删除&#xff1f; 1、选中需要有数字和汉字那段文字 2、点击段落下拉 3、找到中文版式 4、将【自动调整中文与数字的间距】取消勾选&#xff08;不要勾选&#xff09; 5、点击确定即可删除啦

强化科技创新“辐射力”,中国移动的数智化大棋局

作者 | 曾响铃 文 | 响铃说 丝滑流畅的5G连接、每时每刻的数字生活服务、无处不在的智能终端、拟人交流的AI助手、梦幻般的XR虚拟现实、直接感受的裸眼3D…… 不知不觉&#xff0c;那个科幻片中的世界&#xff0c;越来越近。 数智化新世界的“气氛”&#xff0c;由一个个具…

VR太空舱体验馆VR神舟返回舱VR虚拟现实科技科普乐园

VR航天航空设备&#xff0c;寓教于乐 VR科技正成为航天航空领域的新宠。作为一种沉浸式的数字技术&#xff0c;VR(Virtual Reality&#xff0c;虚拟现实)能够为用户创造出逼真的虚拟环境&#xff0c;让人们仿佛身临其境。借助VR技术&#xff0c;我们可以带领学生和游客深入了解…

LangChain结合milvus向量数据库以及GPT3.5结合做知识库问答之一 --->milvus的docker compose安装

https://github.com/milvus-io/milvus/releaseshttps://github.com/milvus-io/milvus/releases 以下步骤均在Linux环境中进行&#xff1a; 将milvus-standalone-docker-compose.yml下载到本地。 1、新建一个目录milvus 2、将milvus-standalone-docker-compose.yml放到milvu…

Spring Cloud--Nacos+@RefreshScope实现配置的动态更新

原文网址&#xff1a;Spring Cloud--NacosRefreshScope实现配置的动态更新_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍SpringCloud整合Nacos使用RefreshScope实现动态更新配置。 官网 Nacos Spring Cloud 快速开始 动态更新的介绍 动态更新的含义&#xff1a;修改应…

2023_Spark_实验十八:安装FinalShell

下载安装包 链接&#xff1a;https://pan.baidu.com/s/14cOJDcezzuwUYowPsOA-sg?pwd6htc 提取码&#xff1a;6htc 下载文件名称&#xff1a;FinalShell.zip 二、安装 三、启动FinalShell 四、连接远程 linux 服务器 先确保linux系统已经开启&#xff0c;不然连接不上 左边…

一款优秀的文件外发控制软件 具备哪些优势?

随着越来越多的公司在网上开展业务&#xff0c;网络安全漏洞也相应增加。因此&#xff0c;企业需要保护自己的数据&#xff0c;防止数据泄露&#xff0c;给企业带来损失。近几年来&#xff0c;企业数据泄露事件频发&#xff0c;给许多企业都带来巨大创伤。 乌克兰电力公司在201…

3.Vue-在Vue框架中搭建路由

题记 以下是在vue框架中搭建路由的全过程&#xff0c;包括全部代码。 创建路由 如果你的文件中没有 router文件夹&#xff0c;可以使用以下命令创建&#xff1a; vue add router 注意&#xff1a;生成的路由文件会因为选择的自定义选项不同&#xff0c;而有所差异 生成的代码…

uni-app:本地缓存的使用

uni-app 提供了多种方法用于本地缓存的操作。下面是一些常用的 uni-app 本地缓存方法&#xff1a; uni.setStorageSync(key, data): 同步方式将数据存储到本地缓存中&#xff0c;可以使用对应的 key 来获取该数据。 uni.setStorage({key, data}): 异步方式将数据存储到本地缓存…

SpringCloud-Stream

一、介绍 &#xff08;1&#xff09;提供统一接口操作不同厂商的消息队列组件&#xff0c;降低学习成本 &#xff08;2&#xff09;生产者和消费者只需操作binder对象即可与消息队列交互&#xff0c;生产者output&#xff0c;消费者input &#xff08;3&#xff09;核心概念&a…

实现一个todoList可直接操作数据(上移、下移、置顶、置底)

演示 HTML部分 <!DOCTYPE html> <html> <head><title>表格示例</title> </head> <body><table border"1"><thead><tr><th>更新时间</th><th>操作</th></tr></thead&…

SOLIDWORKS PDM—2024版本新增

SOLIDWORKS产品数据管理 (PDM) 解决方案可帮助您控制设计数据&#xff0c;并且从本质上改进您的团队就产品开发进行管理和协作的方式。使用 SOLIDWORKS PDM Professional&#xff0c;您的团队能够&#xff1a;1. 安全地存储和索引设计数据以实现快速检索&#xff1b;2. 打消关于…