【嵌入式Linux】编译应用和ko内核模块Makefile使用记录

news2024/11/19 18:32:11

文章目录

  • 一、常用的语法
    • 1.1 `=, :=, +=, ?=`的区别
    • 1.2 命名模式:target-objs 和 target-y 的区别
  • 二、编译KO
    • 2.1 难度0:一个.c文件编译成一个.ko文件
      • 2.1.1 改进一下Makefile使得编译命令只需要make就可以
    • 2.2 难度1:多个.c,.h文件编译成一个.ko文件
    • 风格二
  • 三、编译应用
    • 3.1 最简单的:只有一个.c文件编译没有必要写Makefile
    • 3.2 风格一:编译时直接make
  • 四、错误记录
    • 4.1 编译内核模块报错1:cc1: some warnings being treated as errors
    • 4.2 编译内核模块报错2

一、常用的语法

1.1 =, :=, +=, ?=的区别

在Makefile中,变量的赋值可以使用以下几种方式:

  1. =:最基本的赋值符号,表示简单的延迟展开(lazy expansion)方式。变量的值将会在使用变量的时候进行展开。

  2. :=:立即展开(immediate expansion)的赋值方式。变量的值在赋值的时候立即展开,并且在后续的使用中不再改变。

  3. +=:追加赋值符号,用于将值追加到变量的原有值的末尾。

  4. ?=:条件赋值符号,用于在变量未定义或为空时才进行赋值。

下面是每种符号的示例和解释:

VARIABLE1 = Hello $(VARIABLE2)
VARIABLE2 = World

VARIABLE3 := Hello $(VARIABLE4)
VARIABLE4 := World

VARIABLE5 += Good
VARIABLE5 += Morning

VARIABLE6 ?= Default Value

all:
    @echo "VARIABLE1:" $(VARIABLE1)
    @echo "VARIABLE3:" $(VARIABLE3)
    @echo "VARIABLE5:" $(VARIABLE5)
    @echo "VARIABLE6:" $(VARIABLE6)

输出结果为:

VARIABLE1: Hello $(VARIABLE2)
VARIABLE3: Hello
VARIABLE5: Good Morning
VARIABLE6: Default Value

可以看到,= 进行简单赋值,使用时才展开。:= 进行立即展开,赋值时就展开为确定的值。+= 用于追加值,变量值累加。?= 用于条件赋值,只在变量未定义或为空时进行赋值。

1.2 命名模式:target-objs 和 target-y 的区别

  • target-objs:都可以,应用程序和内核模块
  • target-y:常用于内核模块

通常,内核驱动有两种编译和加载方式:第一种是直接把驱动程序编译进内核中,对应obj-y变量;第二种是将驱动程序作为模块单独编译成.ko文件,而不编译进内核中,然后手动加载,即obj-m变量

在Makefile中,main-objsmain-y是用于定义目标文件(object files)的变量。

  1. main-objs是一种目标文件的变量约定,用于指定构建某个目标的源文件列表。通常,当你的目标(如可执行文件、模块)由多个源文件组成时,你可以使用target-objs的命名模式,其中target是你的目标名称。使用target-objs,你可以列出构成目标的所有源文件,例如:
main-objs := file1.o file2.o file3.o
  1. main-y是另一种目标文件的变量约定,用于指定构建某个目标的源文件列表,类似于target-objs。但是,main-y常用于内核模块(kernel module)的构建。在内核模块编译构建时,main-y变量指定要包含在模块中的所有源文件。例如:
main-y := file1.o file2.o file3.o

这样,当你构建目标时,Makefile将使用所定义的target-objstarget-y变量来确定哪些源文件应该编译为目标文件,并将其链接到最终的目标(如可执行文件、模块)中。

请注意,target-objstarget-y只是约定的变量名,你可以根据自己的需要和习惯为目标定义适当的变量名。

二、编译KO

2.1 难度0:一个.c文件编译成一个.ko文件

这几乎就是最简单的内核模块了!

# 指定你的内核源码目录
KERNEL_DIR := /home/liefyuan/Liefyuan/cherry-pi/linux-zero-5.2.y
# 指定你的模块源码目录:会把该目录下的文件编译成.ko文件
CURRENT_PATH := $(shell pwd)
# 驱动名称: led.ko
obj-m := led.o

build: kernel_modules

kernel_modules:
	$(MAKE) -C $(KERNEL_DIR ) M=$(CURRENT_PATH) modules

clean:
	$(MAKE) -C $(KERNEL_DIR ) M=$(CURRENT_PATH) clean

编译命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

一般没啥问题就会在本目录下生成一个led.ko文件

2.1.1 改进一下Makefile使得编译命令只需要make就可以

Makefile

ARCH := arm
CROSS_COMPILE := arm-linux-gnueabihf-
KERN_DIR = /home/liefyuan/Liefyuan/cherry-pi/linux-zero-5.2.y

obj-m += led.o

#cc1: all warnings being treated as errors解决办法
CFLAGS = -Wall -Wpointer-arith -Wno-unused
KBUILD_CFLAGS += -w

all:
	make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(shell pwd) modules 
clean:
	rm -rf *.order *o *.symvers *.mod.c *.mod *.ko

编译命令:

make

2.2 难度1:多个.c,.h文件编译成一个.ko文件

MODULE_NAME = hci_uart

ifneq ($(KERNELRELEASE),)
	obj-m :=$(MODULE_NAME).o
	$(MODULE_NAME)-y := hci_ldisc.o hci_h4.o hci_rtk_h5.o rtk_coex.o
	#cc1: all warnings being treated as errors解决办法
	CFLAGS = -Wall -Wpointer-arith -Wno-unused
	KBUILD_CFLAGS += -w
else
	PWD := $(shell pwd)
	KDIR := /home/liefyuan/luckfox-pico-main/sysdrv/source/kernel

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	rm -rf *.o *.mod *.mod.c *.mod.o *.ko *.symvers *.order *.a
endif

解释一下Makefile文件。KERNELRELEASE是在内核源码的上层Makefile中定义的一个变量。在该模块未被动到内核源代码中时,这个变量不会被定义。该模块移动到内核源代码后,这个变量就有定义了。

KDIR变量表示的这个目录下存放该版本linux内核源码,其中调用的shell指令uname -r用来打印该内核的版本号。PWD是当前目录所在的路径。

在终端输入make指令后,对.c文件编译进行编译。这个过程比较复杂。首先,初次编译前变量KERNELRELEASE为空,因此执行else后面的程序,即

make -C $(KDIR) M=$(PWD) modules

-C参数的作用是指定跳转目录,-C $(KDIR)指明跳转到内核源码所在的目录并读取那里的Makefile,启动kbuild机制。M=$(PWD)再返回到当前目录继续执行当前的Makefile。

kbuild即kernel build,用于编译Linux内核文件,对Makefile进行功能上的扩展。大部分内核中的Makefile都使用kbuild进行组织,它能使原本的Makefile代码变得更简洁、高效。kbuild中会预定义一些变量,如obj-y、obj-m,用来指定要生成的.o目标文件。只需要对该变量进行赋值,kbuild就会自动把代码编译到内核或编译成模块。

通常,内核驱动有两种编译和加载方式:第一种是直接把驱动程序编译进内核中,对应obj-y变量;第二种是将驱动程序作为模块单独编译成.ko文件,而不编译进内核中,然后手动加载,即obj-m变量。本例中将DriverFramework.o赋值给obj-m变量,就是采用第二种模式,单独生成一个独立的DriverFramework.ko文件。
————————————————
版权声明:本文为CSDN博主「精致的螺旋线」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/baidu_38797690/article/details/122116281

编译命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

风格二

obj-m := ch36x.o

#交叉编译需要指定内核在ubuntu的位置,内核源代码路径
KERNELDIR= /home/ht/rk3588/nvr_v1.3/kernel_rk_demo

#cc1: all warnings being treated as errors解决办法
CFLAGS = -Wall -Wpointer-arith -Wno-unused
KBUILD_CFLAGS += -w

#交叉编译器路径
CROSS_PATH = /opt/rk_linux/rv1126_1109/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-

#驱动模块源代码路径
PWD	:= $(shell pwd)

#交叉编译
modules:
	$(MAKE) ARCH=arm64 $(CFLAGS) LOCALVERSION="sun50iw6" CROSS_COMPILE=$(CROSS_PATH) -C $(KERNELDIR) M=$(PWD) modules
clean:
	rm -rf *.o *~ core .depend .*.cmd *.mod *.mod.c .tmp_versions modules.order Module.symvers Module.markers built-in.o ch36x.ko *.ko.*

三、编译应用

3.1 最简单的:只有一个.c文件编译没有必要写Makefile

假设文件是main.c,交叉编译成main.elf,就直接命令行输入:

arm-linux-gnueabihf-gcc main.c -o main.elf

然后本目录下就可以生成main.elf,拷贝到目标平台上就可以运行了。

3.2 风格一:编译时直接make

要想编译时直接make,就得在Makefile里面指定编译器/交叉编译器。

一个使用过的例子:
Makefile文件

rtk_hciattach:hciattach.c hciattach_rtk.o  
	arm-linux-gnueabihf-gcc -o rtk_hciattach hciattach.c hciattach_rtk.o  

hciattach_rtk.o:hciattach_rtk.c
	arm-linux-gnueabihf-gcc -c hciattach_rtk.c

clean:
	rm -f *.o  rtk_hciattach

编译:

make

然后本目录下就可以生成rtk_hciattach可执行文件了。

四、错误记录

4.1 编译内核模块报错1:cc1: some warnings being treated as errors

make -C /home/liefyuan/luckfox-pico-main/sysdrv/source/kernel M=/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver modules
make[1]: Entering directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_ldisc.o
/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_ldisc.c: In function 'hci_uart_init':
/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_ldisc.c:1149:22: error: assignment to 'ssize_t (*)(struct tty_struct *, struct file *, unsigned char *, size_t,  void **, long unsigned int)' {aka 'int (*)(struct tty_struct *, struct file *, unsigned char *, unsigned int,  void **, long unsigned int)'} from incompatible pointer type 'ssize_t (*)(struct tty_struct *, struct file *, unsigned char *, size_t)' {aka 'int (*)(struct tty_struct *, struct file *, unsigned char *, unsigned int)'} [-Werror=incompatible-pointer-types]
  hci_uart_ldisc.read = hci_uart_tty_read;
                      ^
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:273: /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_ldisc.o] Error 1
make[1]: *** [Makefile:1917: /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver] Error 2
make[1]: Leaving directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'
make: *** [Makefile:12: all] Error 2

解决办法:

编译驱动的makefile中加入下面两句

#cc1: all warnings being treated as errors解决办法
CFLAGS = -Wall -Wpointer-arith -Wno-unused
KBUILD_CFLAGS += -w

为了避免内核继续将警告提示错误导致的编译失败

4.2 编译内核模块报错2

root@DESKTOP-2CFURMS:/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver# make ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf-
make -C /home/liefyuan/luckfox-pico-main/sysdrv/source/kernel M=/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver modules
make[1]: Entering directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'
  MODPOST /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/Module.symvers
ERROR: modpost: "hci_register_dev" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "hci_recv_frame" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "hci_unregister_dev" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "bt_err" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "bt_info" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "hci_alloc_dev" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
ERROR: modpost: "hci_free_dev" [/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko] undefined!
make[2]: *** [scripts/Makefile.modpost:169: /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/Module.symvers] Error 1
make[2]: *** Deleting file '/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/Module.symvers'
make[1]: *** [Makefile:1819: modules] Error 2
make[1]: Leaving directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'
make: *** [Makefile:12: all] Error 2

来源:https://github.com/espressif/esp-hosted/issues/110
kernel没有编译支持Bluetooth的功能,建议通过make menuconfig来配置蓝牙相关功能后再编译内核,最后再来编译.ko。
在这里插入图片描述

浑身通透。我居然理解了他的意思。
卧槽,牛逼!!!试了一下,KO编译出来了!!!

root@DESKTOP-2CFURMS:/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver# make ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf-
make -C /home/liefyuan/luckfox-pico-main/sysdrv/source/kernel M=/home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver modules
make[1]: Entering directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_ldisc.o
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_h4.o
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_rtk_h5.o
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/rtk_coex.o
  LD [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.o
  MODPOST /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/Module.symvers
  CC [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.mod.o
  LD [M]  /home/liefyuan/luckfox-pico-main/project/app/rkwifibt-1.0.0/realtek/bluetooth_uart_driver/hci_uart.ko
make[1]: Leaving directory '/home/liefyuan/luckfox-pico-main/sysdrv/source/kernel'

Makefile文件

MODULE_NAME = hci_uart

ifneq ($(KERNELRELEASE),)
	obj-m :=$(MODULE_NAME).o
	$(MODULE_NAME)-y := hci_ldisc.o hci_h4.o hci_rtk_h5.o rtk_coex.o
	CFLAGS = -Wall -Wpointer-arith -Wno-unused
	KBUILD_CFLAGS += -w
else
	PWD := $(shell pwd)
	KDIR := /home/liefyuan/luckfox-pico-main/sysdrv/source/kernel

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	rm -rf *.o *.mod *.mod.c *.mod.o *.ko *.symvers *.order *.a
endif

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

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

相关文章

在Java中使用FileReader.read()进行读取文件时,为什么乱码?两个方法解决

public class FileReader_ {public static void main(String[] args) {}Testpublic void m1() {String filePath "e:\\hello.txt";FileReader fileReader null;try {fileReader new FileReader(filePath);//循环读取 使用readwhile (fileReader.read()!-1){System…

使用dlib,OpenCV和Python进行人脸识别—人眼瞌睡识别

前期文章我们分享了如何使用python与dlib来进行人脸识别,以及来进行人脸部分的识别, 如下图,dlib人脸数据把人脸分成了68个数据点,从图片可以看出,人脸识别主要是识别:人眉,人眼,人鼻,人嘴以及人脸下颚边框,每个人脸的部位都有不同的数据标签从1-68 当我们识别出人脸…

伦敦银现货白银走势如何应对

伦敦银是国际现货白银交易的别称,它每天的价格走势受到全球投资者广泛的关注,也是全球各个白银市场的价格指标。白银投资者要了解伦敦银走势的特点,才能更好地进行分析,实现自己的所预期的收益。 整体来说,伦敦银价格的…

Java工具库——Hutool的50个常用方法

爱一辈子也好,恨一辈子也罢,终究是要让你记我一辈子… 工具库介绍 Hutool-All(或简称Hutool)是一个功能强大的Java编程工具库,旨在简化Java应用程序的开发。它提供了大量的工具类和方法,涵盖了各种常见任务…

创建个人github.io主页(基础版)//吐槽:很多国内教程已经失效了

一、就跟着官网教程来很快就好了 官方文档的教程 GitHub Pages | Websites for you and your projects, hosted directly from your GitHub repository. Just edit, push, and your changes are live. // 简单跑通为例,第一个链接直接能行了,如果不想…

数据泄露高达7 TB ,这家医疗巨头数据库无任何密码保护

该数据库由Redcliffe Labs拥有,Redcliffe Labs是一家位于北方邦诺伊达的印度医疗公司。 网络安全研究员杰里迈亚-福勒(Jeremiah Fowler)发现了一个无密码保护的数据库,其中包含 1200 多万条记录。这些数据包括敏感的患者数据&…

本地存储 sessionStoragelocalStorage

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。 本地存储特性 数据存储在用户浏览器中 设置、读取方便、…

自监督学习应用

1 自监督学习 自监督学习主要是利用辅助任务(pretext)从大规模的无监督数据中挖掘自身的监督信息,通过这种构造的监督信息对网络进行训练,从而可以学习到对下游任务有价值的表征。(也就是说自监督学习的监督信息不是人…

涨幅25%,2023全球电动车销量将飙升至2000万辆 | 百能云芯

近日,工研院在「眺望2024产业发展趋势研讨会」上发布消息,预测随着全球晶片短缺的逐渐缓解,以及俄乌地区供应链产能向其他国家的部分转移,全球汽车市场在疫情的影响下逐渐回暖。根据工研院的数据,2023年全球汽车销量预…

DSP_控制程序框架有感

本文仅代表个人观点,若有不同意见,请评论区讨论或私信留言。 中心思想: 基于DSP的控制程序可分为两个部分,① 对实时性要求高的部分,②对实时性要求不高的部分。 ① 对实时性要求高的程序,建议采用中断处理…

Ubuntu22.04本地部署PaddleSpeech实验代码(GPU版)

前言 之前做了一个Ubuntu18.04.6本地部署PaddleSpeech实验代码(CPU版)的相关项目,因为是CPU版的,合成/训练等方面的耗时真的是非常感人,有了之前的经验,又部署了一个GPU版的,说实话虽然时间用的…

CVE-2022-22963 Spring Cloud Function SpEL命令注入

一、简介 Spring Cloud Function 是基于 Spring Boot的函数计算框架。该项目致力于促进函数为主的开发单元,它抽象出所有传输细节和基础架构,并提供一个通用的模型,用于在各种平台上部署基于函数的软件。在Spring Cloud Function相关版本&am…

Pytest框架之fixture详解

本文详细讲解了Pytest框架之fixture,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 相关文章 pytest作为python语言的测试框架,它的fixture有2种实现方式。 一种是xunit-style&#xf…

OpenLayers实战,OpenLayers获取用户定位位置并高亮显示用户所在行政区划边界

专栏目录: OpenLayers实战进阶专栏目录 前言 本篇文章通过国内的省、自治区和直辖市的GeoJson数据作为行政区划边界数据,然后根据用户定位位置,通过OpenLayers计算得到用户所在行政区划,并使用OpenLayers高亮显示用户所在行政区划边界。 本章是综合应用场景,所以代码稍…

ESP32 ESP-IDF LVGL移植和Wokwi仿真

陈拓 2023/10/21-2023/10/25 1. ESP-IDF开发环境 ESP-IDF的LVGL移植包括2个组件: lvgllvgl_esp32_drivers 目前lvgl_esp32_drivers在ESP-IDF 5.0以上版本编译通不过,所以我们安装ESP-IDF 4.4.5。 从https://dl.espressif.cn/dl/esp-idf/下载 安装说明…

纳米软件分享:芯片电学测试及测试参数指标介绍

电学测试是芯片测试的一个重要环节,用来描述和评估芯片的电性能、稳定性和可靠性。芯片电学测试包括直流参数测试、交流参数测试和高速数字信号性能测试等。 什么是芯片电学测试? 芯片电学测试就是检测芯片、元件等电性能参数是否满足设计的要求。检测的项目有电压…

【uniapp】短信验证码输入框

需求是短信验证码需要格子输入框 如图 网上找了一个案例改吧改吧 直接上代码 结构 <template><view class"verify-code"><!-- 输入框 --><input id"input" :value"code" class"input" :focus"isFocus"…

Ubuntu安装Jitsi Meet详细教程

文章目录 Ubutu系统安装启用root账户切换Ubuntu源设置DNS 主机名和域名配置安装open JDK安装Nginx安装 Jitsi Meetjitsi本地测试使用一个奇怪的BUG Jist服务管理 Ubutu系统安装 官方推荐用Ubuntu&#xff0c;网上很多教程也都是基于Ubuntu的&#xff0c;所以选择这个系统。 其…

【Python Numpy】Ndarray属性

文章目录 前言一、NumPy数组的常用属性1.1 常用属性1.2 示例代码 总结 前言 NumPy&#xff08;Numerical Python&#xff09;是Python中用于科学计算的一个重要库&#xff0c;它提供了一个强大的多维数组对象&#xff08;ndarray&#xff09;以及一系列用于处理这些数组的函数…

从0到1:CTFer成长之路——死亡 Ping 命令

死亡 ping 命令 绕过探测 手动尝试 慢 脚本生成转义后的字符&#xff0c;后面拼接命令 import urllib.parsewith open(r"C:\Users\LEGION\Desktop\RCE.txt", "w", encoding"utf-8") as f:for i in range(0, 255):encoded_str urllib.parse…