本文例子中涉及两个模块hello.ko和world.ko,其中hello导出符号供world使用;

insmod
该命令将模块的代码和数据装入内核,然后使用内核的符号表继续模块中任何未解析的符号。insmod不会修改模块的磁盘文件,而仅仅修改内存中的副本。insmod可以接受一些命令行选项,并且可以再模块链接到内核之前给模块中的整数和字符串变量赋值。

按照顺序加载,通过;

1 [root@localhost export]# insmod hello.ko
2 [root@localhost export]# insmod world.ko

先加载world.ko,不通过,因为world找不到从a中引用的符号;

1 [root@localhost export]# insmod world.ko 
2 insmod: ERROR: could not insert module world.ko: Unknown symbol in module

modprobe
与insmod类型,modprobe也用来将模块装入内核,区别在于,modprobe会考虑要加载的模块是否引用了一些当前内核中不存在的符号,如果有这类引用,modprobe会在当前模块搜索路径中查找定义了这些符号的其他模块,如果找到了这些依赖模块,它会同时将这些模块也装载到内核。这种情况下使用insmod会失败,并在系统日志文件中记录”unresolved symbols”消息;

在使用modprobe时,在配置文件中加入 modules_install行和clean行;

1 ifneq ($(KERNELRELEASE),)
 2         obj-m :=hello.o world.o
 3 #       module-objs := file1.o file2.o
 4 else
 5         KERNELDIR ?=/lib/modules/$(shell uname -r)/build
 6         PWD :=$(shell pwd)
 7 default:
 8         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
 9         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
10 clean:
11         rm -rf *.o *.mod.c *.ko *.symvers *.order *.makers
12         $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
13 endif

加载模块world,成功;

1 [root@localhost export]# modprobe world

lsmod查看,可见依赖的模块hello也被加载进内核;

1 [root@localhost export]# lsmod
2 Module                  Size  Used by
3 world                  16384  0 
4 hello                  16384  1 world

rmmod
rmmod用于从内核中移除模块;如果内核模块仍然在使用状态,或者内核被配置为禁止移除模块,则无法移除该模块;配置内核并支持在模块忙的时候仍能移除模块是可能的;但是,重新引导系统是更合适的办法;

先移除world.ko,再移除hello.ko,成功;

[root@localhost export]# rmmod world.ko 
[root@localhost export]# rmmod hello.ko

先移除模块hello.ko,产生错误,因为hello在被world使用;

1 [root@localhost export]# rmmod hello.ko
2 rmmod: ERROR: Module hello is in use by: world

lsmod
lsmod用于列出当前装载到内核中的所有模块,包括一些其他信息,其通过读取/proc/modules来获取这些信息;

1 [root@localhost export]# lsmod
2 Module                  Size  Used by
3 world                  16384  0 
4 hello                  16384  1 world

Referenced from:https://www.cnblogs.com/wanpengcoder/p/11755850.html

make[1]: 进入目录“/usr/src/linux-headers-5.4.0-89-generic”
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf --syncconfig Kconfig
make[2]: * 没有规则可制作目标“arch/x86/tools/relocs_32.c”,由“arch/x86/tools/relocs_32.o” 需求。 停止。
make[1]: * [arch/x86/Makefile:236:archscripts] 错误 2
make[1]: 离开目录“/usr/src/linux-headers-5.4.0-89-generic”
make: * [Makefile:5:all] 错误 2

解决办法:

In the make file, just change SUBDIRS=$(PWD) into M=$(shell pwd)

个人房贷单月数据增加是适度回调
郭子源

11月10日,中国人民银行发布的数据显示,2021年10月末,个人住房贷款余额37.7万亿元,当月增加3481亿元,较9月多增1013亿元。对此,市场上出现了“放松调控”甚至“宽信用”的猜测。

实际上,无需过度解读10月个人住房贷款增加。这是对此前部分地区、部分银行房贷从紧的适度调整,其目的是保障刚需、满足居民合理购房需求,进而稳定市场预期。房地产信贷平稳有序投放不会变,房地产市场平稳健康发展不会变。

党中央、国务院关于房地产调控的战略和方针,是当前及今后做好房地产金融工作的长期遵循。我们坚持房子是用来住的、不是用来炒的定位,坚持不将房地产作为短期刺激经济的手段,坚持“稳地价、稳房价、稳预期”目标,加快建立房地产长效机制。截至2021年9月末,房地产贷款增速已降至8.6%,比全部贷款增速低近3个百分点,其中,房地产开发贷款增速大幅下滑。

但要注意,在防范化解房地产“灰犀牛”风险的同时,也会伴随着市场“阵痛”,以及由此引发的短期、过激市场反应,近期个别大型房企的风险暴露便是典型。
个人房贷单月数据增加是适度回调
对于处置风险过程中可能引发的风险,必须高度重视。部分大型房企工地停工、已预售房产无法按时交付,不仅会损害购房者合法权益,还会导致部分购房者产生不稳定预期,长此以往,也不利于房地产市场平稳健康发展。

购房者的不稳定预期,一定程度也来自此前普遍收紧的个人住房贷款。出于“稳地价、稳房价、稳预期”目标,金融监管部门于2020年12月正式建立“房地产贷款集中度管理制度”,要求银行的房地产贷款余额占比、个人住房贷款余额占比不得高于相应上限。

为防止市场出现短期、过激行为,监管部门对以上整改设置了2年、4年不等的过渡期。但在具体执行过程中,过度收缩行为依然存在,从各家银行今年的执行情况看,个人住房贷款发放逐月减少并非个例。

矫枉不能过正。具有稳定性、连续性的政策,适时、适度根据市场变化做出微调,这也是对市场的有效反馈。因此,10月个人住房贷款增加,是对此前信贷过度收紧的回调,能够进一步稳定市场预期。

房地产政策的定力不会放松。而从具体落地层面看,金融系统要准确把握、稳妥实施房地产金融审慎管理制度,执行各项政策要兼顾好“防止过快上涨”和“防止过快下跌”之间的关系,切实推动房地产市场平稳健康发展。
Referenced from:http://paper.ce.cn/jjrb/html/2021-11/12/content_453383.htm

穆迪:中国地方政府的土地出让收入明年可能萎缩 | 联合早报网
 update:2021-11-12
据彭博社报道,穆迪分析师Jack Yuan等人周四在一份报告中说:土地出让收入约占地方政府收入的三分之一,这项收入的下降可能会限制基础设施项目的财政资金。报告称,这会遏制经济增长,加剧支持增长与去杠杆之间的政策两难困境。

“在房地产市场放缓的情况下,贵州这类对土地出让依赖程度较高的高负债省份将面临财政压力。”

报告认为,鉴于地方政府可能会走上靠举债支持基建投资以促进增长的老路,今年前10个月进展缓慢的地方政府债券发行明年可能会回升,特别是专项债发行。分析师们表示,地方政府的展望为“负面”。

Referenced from:https://www.zaobao.com/realtime/china/story20211111-1212535

美媒:中国考虑放宽房地产政策限制 以帮助开发商脱手资产 | 联合早报网
 update:2021-11-12
中国监管机构担心其对房地产业借贷的限制会令金融风险蔓延,正在考虑放宽规定,让陷入困境的开发商可以通过出售资产,来避免出现违约和对更广泛的经济构成打击。

目前,去年底出台的限制房地产公司借款额度的规定(即所谓的杠杆率“三条红线”)非常严格,损害了中国恒大等开发商出售资产以偿还债务的能力。

《华尔街日报》引述消息人士透露,中国央行正在考虑为资金紧张的房地产公司开辟一条脱手项目的途径,允许买家(可能是国有企业)在不让项目相关债务影响自身负债率的情况下接管资产。

房地产业借贷规定可能放松凸显出,中国政府在应对规模过于庞大的房地产行业的问题之际,日益面临两难困境。房地产行业以及建筑等相关行业合计占中国经济总产出的近三分之一。近来中国房地产行业违约风险不断上升,已经搅动了全球市场,中国经济也因此面临急剧放缓风险。

这些消息人士说,这一潜在举措是对旨在控制房地产投机并减少经济对该行业依赖的更广泛政策的调整,而不是改变这一政策。他们说,房地产借贷限制可能会实施长达四年。

Referenced from:https://www.zaobao.com/realtime/china/story20211111-1212536

综述:恒大再次在最后一刻躲过违约 房地产业债务危机隐患犹存 | 路透
 update:2021-11-12
国际清算公司Clearstream的发言人周四表示,该公司客户收到了逾期的恒大三笔债券的利息付款。

恒大是全球债务负担最重的地产开发商,最近几周接连面对一个又一个的付款最后期限。该公司负债规模超过3,000亿美元,其中190亿美元是美元债券。

最新所付款项是在截至周三的30天宽限期结束时支付的,这是恒大过去一个月中第三次避过违约。这三笔债券的利息总额超过1.48亿美元。

恒大如果没有在宽限期届满前支付款项,则将正式违约,并触发该公司其他美元债券的交叉违约条款,加剧笼罩中国经济的债务危机隐患。

尽管恒大再次设法避开了违约,但房地产业困境没有减轻迹象,还有大量债务即将到期。

“近期似乎正在出台解决方案,但要解决这个问题,还有很长的路要求。现在还是早期阶段,”这位消息人士称,他指的是恒大。由于未获授权对媒体表态,该消息人士拒绝署名。

恒大没有回应路透关于最新票息支付情况的评论请求。

恒大在12月28日有总额超过2.55亿美元的票息付款到期。恒大还面临来自国内其他债权人的压力,令人窒息的资金短缺给其数百个住宅项目蒙上了阴影。

Referenced from:https://cn.reuters.com/article/evergrande-bond-default-rea-crisis-1112-idCNKBS2HX014?il=0

在用户空间访问 I/O 端口
以上函数主要提供给设备驱动使用,但它们也可在用户空间使用,至少在 PC上可以。 GNU C 库在 中定义了它们。如果在用户空间代码中使用必须满足以下条件:

(1)程序必须使用 -O 选项编译来强制扩展内联函数。

(2)必须用ioperm 和 iopl 系统调用(#include ) 来获得对端口 I/O 操作的权限。ioperm 为获取单独端口操作权限,而 iopl 为整个 I/O 空间的操作权限。 (x86 特有的)

(3)程序以 root 来调用 ioperm 和 iopl,或是其父进程必须以 root 获得端口操作权限。(x86 特有的)

若平台没有 ioperm 和 iopl 系统调用,用户空间可以仍然通过使用 /dev/prot 设备文件访问 I/O 端口。注意:这个文件的定义是体系相关的,并且I/O 端口必须先被注册。

ioperm和iopl介绍。

1.ioperm
 
功能描述:

为调用进程设置I/O端口访问权能。ioperm的使用需要具有超级用户的权限,只有低端的[0-0x3ff] I/O端口可被设置,要想指定更多端口的权能,可使用iopl函数。这一调用只可用于i386平台。 

用法:

int ioperm(unsigned long from, unsigned long num, int turn_on);      

参数:

from:起始端口地址。

num:需要修改权能的端口数。

turn_on:端口的新权能位。1为开启,0为关闭。

返回说明:

成功执行时,返回0。失败返回-1,errno被设为以下的某个值

EINVAL:参数无效
EIO:这一调用不被支持
EPERM:调用进程权能不足。 

  1. iopl

功能描述:该调用用于修改当前进程的操作端口的权限。可以用于所有65536个端口的权限。因此,ioperm相当于该调用的子集。和ioperm一样,这一调用仅适用于i386平台。 

用法:
   int iopl(int level);

参数:

level: 端口的权限级别。为3时可以读写端口。默认权能级别为0,用户空间不可读写。

返回说明:成功执行时,返回0。失败返回-1,errno被设为以下的某个值

EINVAL:level值大于3
ENOSYS:未实现该调用
EPERM:调用进程权能不足。 

二、程序示例

  1. ioperm.c

操作低于0x3FF的端口

该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。

/*Description:This function is used to test ioperm()*/

#define PORT_ADDR 0x3FF 

int main(void)
{
      int ret;
      char port_val;

      /*set r/w permission of port_addr on, only one port*/
      ret = ioperm(PORT_ADDR, 1, 1);
      if(ret < 0){
           perror("ioperm set error");
           return 0;
      }
      port_val = inb(PORT_ADDR);
      printf("Original value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);    
      /*reverse the least significant bit */
      outb(port_val^0x01, PORT_ADDR);
      port_val = inb(PORT_ADDR);
      printf("Current value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);    
      /*set r/w permission of PORT_ADDR off, only one port*/
      ret = ioperm(PORT_ADDR, 1, 0);
      if(ret < 0){
           perror("ioperm set error");
           return 0;
      }
      return 0;
} 

程序执行的结果是:

[root@localhost misc-progs]# ./a.out
Original value of port 0x3ff is : 00
Current value of port 0x3ff is : 01
[root@localhost misc-progs]# ./a.out
Original value of port 0x3ff is : 01
Current value of port 0x3ff is : 00

该程序执行几次,将进行几次的LSB翻转。

这里有一个问题值得注意:在2.4(RH9)的内核上,当端口值大于0x3FF时,执行该程序则会报错:ioperm set error: Invalid argument。即IO端口的值设置有问题,超出了限制。但是在2.6内核下并没有报错,而且执行结果也符合程序既定的结果。但是man ioperm中仍然说明了0x3FF的限制。暂且存疑。

  1. iopl.c

该程序可以操作所有65536个端口。

该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。

代码如下:

/*Description:This function is used to test iopl()*/

#define PORT_ADDR 0x3FF 

int main(void)
{
      int ret;
      char port_val; 

      /*set r/w permission of all 65536 ports*/
      ret = iopl(3);
      if(ret < 0){
           perror("iopl set error");
           return 0;
      }

      port_val = inb(PORT_ADDR);
      printf("Original value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);    

      /*reverse the least significant bit */
      outb(port_val^0x01, PORT_ADDR);
      port_val = inb(PORT_ADDR);
      printf("Current value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);  
      /*set r/w permission of  all 65536 ports*/
      ret = iopl(0);

      if(ret < 0){
           perror("iopl set error");
           return 0;
      }
      return 0;
}

程序执行结果:

[root@linux misc-progs]# ./a.out
Original value of port 0x3ff is : 01
Current value of port 0x3ff is : 00
[root@linux misc-progs]# ./a.out
Original value of port 0x3ff is : 00
Current value of port 0x3ff is : 01

该程序执行几次,将进行几次的LSB翻转。
Referenced from:http://blog.chinaunix.net/uid-10167808-id-25953.html

linux O_WRONLY 头文件 #include "fcntl.h"

#include <bits/stdc++.h>
#include "unistd.h"
#include "fcntl.h"

using namespace std;
#define MAX_BUF 256

int main(int argc, char* argv[])
{
    int fd;
    char buf[MAX_BUF]; 
    int gpio = 1;

    fd = open("/sys/class/gpio/export", O_WRONLY);
    sprintf(buf, "%d", gpio); 
    write(fd, buf, strlen(buf));
    close(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    fd = open(buf, O_WRONLY);
    // Set out direction
    write(fd, "out", 3); 
    // Set in direction
    write(fd, "in", 2); 
    close(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    fd = open(buf, O_WRONLY);
    // Set GPIO high status
    write(fd, "1", 1); 
    // Set GPIO low status 
    write(fd, "0", 1);
    close(fd);

    char value;
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    fd = open(buf, O_RDONLY);
    read(fd, &value, 1);
    if(value == '0')
    { 
        // Current GPIO status low
    }
    else
    {
        // Current GPIO status high
    }
    close(fd);

    fd = open("/sys/class/gpio/unexport", O_WRONLY);
    sprintf(buf, "%d", gpio);
    write(fd, buf, strlen(buf));
    close(fd);

    return 0;
}