gcc - 如何使用内联汇编在控制寄存器 (cr0) 中设置一个位?
问题描述
我正在尝试使用内联汇编设置 cr0 寄存器的第 30 位。我在我的内核模块中使用以下程序集,
__asm__ (
"mov %%cr0, %%rax\n\t"
"or 0x40000000, %%eax\n\t"
"mov %%rax, %%cr0\n\t"
::
:"%rax"
);
我的模块编译但在插入模块后我的终端冻结。当我尝试删除模块时,从新终端显示以下内容,
rmmod: ERROR: Module xxx is in use
并dmesg
在 中显示以下内容red color
,
RIP [<ffffffffc09c604c>] hello_start+0x4c/0x1000 [ModuleName]
如何在 linux 上使用 gcc 程序集在 x86-64 中设置控制寄存器 0 (cr0) 位和尝试通过 cr0 寄存器禁用分页也谈到了同样的问题。我尝试遵循他们的解决方案,但我无法让它发挥作用。任何帮助,我在内联汇编中哪里出错了?
更新帖子:
我已经根据@prl 的建议修复了代码,以下是我的完整源代码,
u64 get_cr0(void){
u64 cr0;
__asm__ (
"mov %%cr0, %%rax\n\t"
"mov %%eax, %0\n\t"
: "=m" (cr0)
: /* no input */
: "%rax"
);
return cr0;
}
static int __init hello_start(void){
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
printk(KERN_INFO "cr0 = 0x%8.8X\n", get_cr0());
__asm__ (
"mov %%cr0, %%rax\n\t"
"or $0x40000000, %%eax\n\t"
"mov %%rax, %%cr0\n\t"
::
:"%rax"
);
printk(KERN_INFO "cr0 after change = 0x%8.8X\n", get_cr0());
return 0;
}
static void __exit hello_end(void){
printk(KERN_INFO "Goodbye Mr.\n");
__asm__ (
"mov %%cr0, %%rax\n\t"
"and $~(0x40000000), %%eax\n\t"
"mov %%rax, %%cr0\n\t"
::
:"%rax"
);
}
事实上,我的系统在加载模块后运行速度非常慢。但是在更改位之后,我仍然没有看到cr0
寄存器值有任何差异。以下是中的输出dmesg
[ +0.000400] Loading hello module...
[ +0.000001] Hello world
[ +0.000002] cr0 = 0x80050033
[ +0.000312] cr0 after change = 0x80050033
[ +6.085675] perf interrupt took too long (2522 > 2500), lowering kernel.perf_event_max_sample_rate to 50000
为什么我看不到 cr0 寄存器第 30 位的变化?
因此,在移除模块后,我尝试清除第 30 位,希望我的系统能够开始正常响应。但似乎没有奏效。我的系统仍然运行缓慢。任何想法,如何在修改后将系统恢复到正常功能状态cr0
?
解决方案
推荐阅读
- java - 无法建立与数据库的连接
- python - 如何在 Django 表单中设置单选按钮的样式
- bash - 嵌套函数中的 BATS assert_failure
- logstash - 从 Kibana 仪表板中的 LogStash 消息字段中提取
- highcharts - 如何为 Highstock 图表中的条形图着色
- java - java 命令的-agentlib 选项有什么作用。在其中使用 TakipiAgent 时出错
- spring-boot - 无法在 Kubernetes 上部署的 Spring Boot 应用程序中生成的 /tmp/ 目录中找到文件
- postgresql - 用于构建应用程序的 postgresql 限制
- node.js - 为什么我在 AWS EC2 上的 Nginx 设置不起作用?
- sql - 系列中的重复事件