分类 操作系统 下的文章

64 位 Ubuntu 兼容 32 位程序

在 ubuntu 12.04 及之前的版本,如果需要在 64 位机上运行 32 位程序,可以直接安装 ia32-libs。 sudo apt-get install ia32-libs ubuntu 12.04 之后的版本不能直接安装 ia32-libs,已经没有该软件包。可以直接安装 gcc-multilib 解决问题。 sudo apt install gcc-multilib g++-multili...

Ubuntu 驱动开发简介

在 Ubuntu 上开发驱动通常并不需要下载内核的源码(不需要改内核源码的情况下),下载内核头文件就可以了。下载的头文件中自带内核的 Makefile 文件。 查询系统对应的内核头文件包: dpkg-query -s linux-headers-$(uname -r) 安装: sudo apt-get install linux-headers-$(uname -r) 内核头文件会被安装在 /usr/src 驱动的 Makefile 简例: obj-m := helloworld.o KDIR := /usr/src/linux-headers-4.15.0-36-generic PWD := $(shell pwd) all: modules modules: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -rf *.o *~ core .depend *.symvers .*.cmd *.ko *.mod.c .tmp_versions $(TARGET)...

Linux 内核打印 printk

内核中没有 C 库,所以不能使用 printf 打印。但它提供了类似的 printk 函数,printk 函数输出的字符串前加一个带尖括号的整数来控制打印级别,如 printk("<6>Hello, world!\n")。级别数值越小,优先级越高,其紧急和严重程度就越高。然而,需要注意的是,并不是所有级别的消息都会进行输出,而是根据 printk 的打印级别进行过滤。 printk 打印级别宏定义: #define KERN_EMERG KERN_SOH "0" /* system is unusable */ #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ #define KERN_CRIT KERN_SOH "2" /* critical conditions */ #define KERN_ERR KERN_SOH "3" /* error conditions */ #define KERN_WARNING KERN_SOH "4" /* warning conditions */ #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ #define KERN_INFO KERN_SOH "6" /* informational */ #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ #define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */ 内核日志打印级别查看: cat /proc/sys/kernel/printk 4 4 1 7 该文件包含四个数字值,分别表示: 控制台日志级别(Console log level):只有级别高于设定值的日志消息才会被显示在控制台上(值要小于该值)。 默认的消息日志级别(Default message log level):用于打印没有优先级的消息,即当 printk 没有指定消息级别时,将使用该默认级别。 最低的控制台日志级别(Minimum console log level):控制台日志级别可被设置的最小值,也就是最高的优先级。 默认的控制台日志级别(Default console log level):控制台日志级别的缺省值。 修改内核日志打印级别: echo "6 4 1 7" | sudo tee /proc/sys/kernel/printk 修改后的值重启后会恢复,如果要保持,可以将它添加到启动脚本中,以便在系统启动时重新设置。 printk 打印的是控制台,也就是 /dev/console。而图形界面中的终端,其实是把 stdin,stdout,stderr 三个文件重定向了一下。所以 printk 是不能在图形界面中的终端中显示的,当然可以在 /var/log/syslog 或者用 dmesg 查看。 不够打印级别的信息会被写到日志中可通过 dmesg 命令来查看。 dmesg 命令: 实时监控 dmesg 的日志输出: watch "dmesg | tail -20"...

创建一个 Linux 内核模块实例

源代码: #include <linux/init.h> //包含模块初始化、清除函数 #include <linux/module.h> //包含许多符号和函数的定义,模块的定义 #include <linux/kernel.h> static int __init hello_init(void) { printk(KERN_ALERT "Hello World!\n"); //内核中的打印只有printk,而且分打印级别 return 0; } static void __exit hello_exit(void) { printk(KERN_ALERT "Goodbye, see you again!\n"); } module_init(hello_init); //函数声明,把代码段放到init段;module_init是该程序的入口函数 //当系统启动init程序的时候,执行module_init()里的函数 module_exit(hello_exit); //当系统启动exit程序的时候,执行module_exi()里的函数 //没有module声明的函数(普通函数)会放到代码段(文本段) MODULE_AUTHOR("Matt <matt@mculoop.com>"); //声明作者 MODULE_DESCRIPTION("Linux Kernel Hello World Module (C) 2018"); //模块描述 MODULE_LICENSE("GPL"); //声明LICENSE Makefile: # To build modules outside of the kernel tree, we run "make" # in the kernel source tree; the Makefile these then includes this # Makefile once again. # This conditional selects whether we are being included from the # kernel Makefile or not. # called from kernel build system: just declare what our modules are obj-m := helloworld.o # Assume the source tree is where the running kernel was built # You should set KERNELDIR in the environment if it's elsewhere KERNELDIR ?= /home/matt/test/kernel/linux-3.2.0-psp04.06.00.11 # The current directory is passed to sub-makes as argument PWD := $(shell pwd) all: modules modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -rf *.o *~ core .depend *.symvers .*.cmd *.ko *.mod.c .tmp_versions $(TARGET) 编译: 编译前应当确保已经编译过内核,因为要使用内核的Makefile。 mak...

Linux 内核模块的相关操作命令

lsmod 查看已经安装的模块 lsmod Module Size Used by binfmt_misc 20480 1 vmw_vsock_vmci_transport 28672 2 vsock 36864 3 vmw_vsock_vmci_transport snd_ens1371 28672 2 snd_ac97_codec 131072 1 snd_ens1371 gameport 16384 1 snd_ens1371 ac97_bus 16384 1 snd_ac97_codec ... modinfo 显示模块信息 modinfo nfs.ko filename: /home/matt/test/kernel/linux-3.2.0-psp04.06.00.11/fs/nfs/nfs.ko license: GPL author: Olaf Kirch <okir@monad.swb.de> depends: sunrpc,lockd intree: Y vermagic: 3.2.0 mod_unload modversions ARMv7 p2v8 parm: cache_getent:Path to the client cache upcall program (string) parm: cache_getent_timeout:Timeout (in seconds) after which the cache upcall is assumed to have failed (ulong) parm: enable_ino64:bool parm: nfs4_disable_idmapping:Turn off NFSv4 idmapping when using 'sec=sys' (bool) depends 显示出了模块的依赖项 insmod 加载指定位置的模块 insmod /path-to-file/nfs.ko 如果依赖模块没有安装会提示 Unknown symbol... 使用时要指定模块的绝对路径。 rmmod 卸载驱动模块 rmmod <module_name> 注意其中 ”module_name” 是 lsmod 显示的模块名称,而不是对应的 ko 文件名 modprobe 用于挂载内核模块,挂载模块时不用指定模块文件的路径,也不用带文件的后缀。 modprobe nfs 相比 insmod 更智能些,不过限定了 ko 文件的位置。 实例: modprobe nfs [ 207.024183] RPC: Registered named UNIX socket transport module. [ 207.030461] RPC: Registered udp transport module. [ 207.035397] RPC: Registered tcp transport module. [ 207.040317] RPC: Registered tcp NFSv4.1 backchannel transport module. 卸载模块: modprobe -r nfs modprobe: remove[ 145.687621] RPC: Unregistered named UNIX socket transport module. 'sunrpc': Resou[ 145.694428] RPC: Unregistered udp transport module. rce temporarily [ 145.700954] RPC: Unregistered tcp transport module. unavailable [ 145.707460] RPC: Unregistered tcp NFSv4.1 backchannel transport module. depmod 用于分析可载入模块的相依性,供 modprobe 在安装模块时使用。 depmod 通过读取 /lib/modules/$(uname -r) 目录下的每一个模块来创建一个记录模块相依性的列...

Linux 查看 flash 分区命令

/proc/mtd 可以显示出所有挂载和未挂载的分区,但不显示文件系统类型。 cat /proc/mtd mtd0: 00080000 00020000 "MLO" mtd1: 00200000 00020000 "U-Boot" mtd2: 00580000 00020000 "Kernel" mtd3: 00800000 00020000 "File System" mtd4: 07000000 00020000 "app" df 可以查看已经挂载的分区和文件系统类型。 df -a Filesystem 1K-blocks Used Available Use% Mounted on ubi0:rootfs 4584 4576 8 100% / devtmpfs 127488 0 127488 0% /dev ramfs 0 0 0 0% /var ramfs 0 0 0 0% /tmp proc 0 0 0 0% /proc sysfs 0 0 0 0% /sys devpts 0 0 0 0% /dev/pts tmpfs 127592 0 127592 0% /dev/shm ubi1_0 89796 32 89764 0% /app fdisk 可以显示出所有挂载和未挂载的分区,但不显示文件系统类型。 fdisk -l Disk /dev/mtdblock0: 0 MB, 524288 bytes 255 heads, 63 sectors/track, 0 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/mtdblock0 doesn't contain a valid partition table Disk /dev/mtdblock1: 2 MB, 2097152 bytes 255 heads, 63 sectors/track, 0 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/mtdblock1 doesn't contain a valid partition table Disk /dev/mtdblock2: 5 MB, 5767168 bytes 255 heads, 63 sectors/track, 0 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/mtdblock2 doesn't contain a valid partition table Disk /dev/mtdblock3: 8 MB, 8388608 bytes 255 heads, 63 sectors/track, 1 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/mtdblock3 doesn't contain a valid partition table Disk /dev/mtdblock4: 117 MB, 117440512 bytes 255 heads, 63 sectors/track, 14 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/mtdblock4 doesn't contain a valid partition tabl...

Ubuntu 14.04 升级到 16.04

1、查看当前版本 lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.5 LTS Release: 14.04 Codename: trusty 2、执行更新命令 apt-get update && apt-get dist-upgrade 3、重启系统 reboot 4、升级系统 将源改为 16.04 的源 do-release-upgrade 5、验证升级完成 lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.5 LTS Release: 16.04 Codename: xenia...

mstsc 远程桌面连接 Windows Server 时报函数不受支持错误的解决方法

远程桌面连接时提示:“发生身份验证错误,要求的函数不受支持”(Win7) 或者“远程桌面发生身份验证错误,要求的函数不受支持”(Win10)。 这可能是由于 CredSSP 加密 Oracle 修正。 解决方法: Win + R 运行 gpedit.msc 本地计算机策略 > 计算机配置 > 管理模板 > 系统 > 凭据分配 > 加密 Oracle 修正,配置为已启用,保护级别选择易受攻击。 Win10 家庭版没有 gpedit,需要修改注册表。 路径:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters 在 System 下面手动建两级项:CredSSP、Parameters 在 Parameters 下建一个 DWORD 值,AllowEncryptionOracle 值为...

Debian Xfce4 VNC 服务

1、安装服务: apt-get install vnc4server 2、设置密码: vncpasswd 3、停止服务 vncserver -kill :1 Killing Xtigervnc process ID 12510... success! 4、编辑 xstartup vi ~/.vnc/xstartup #!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS vncconfig -iconic & xfce4-session & 5、启动服务 vncserver :1 -localhost n...