C内核print函数传字符数组正常,直接传字符串常量失效问题
内核print函数无法打印字符串常量的原因及解决方法
问题核心在于字符串常量与字符数组的存储位置、内存权限存在差异:
在C语言中,char str[] = "foo"会把字符串内容复制到栈(或数据段)的可读写内存区域;而直接传入的"bar"属于字符串常量,编译器会将其放在只读数据段(.rodata)。在裸机/内核开发环境中,如果内核未正确配置内存映射或段权限,就会导致只读段的内存无法被正常访问。
你的print函数依赖strlen(str)获取字符串长度,而strlen需要从起始地址持续读取直到遇到终止符'\0'。如果只读数据段未被内核正确映射(比如未赋予读权限、地址空间未被内核可见),strlen会读取失败,返回0,循环体根本不会执行,自然没有输出。而字符数组所在的可读写段内存访问正常,strlen能正确计算长度,因此打印正常。
排查与解决步骤
- 检查链接脚本:确认
.rodata段被正确加入内核的内存映射,且权限设置为可读(x86架构下需确保段描述符包含读权限)。 - 验证内存访问:调试时可尝试直接读取字符串常量的地址,确认是否能获取到字符和终止符
'\0'。 - 修改print函数(辅助排查):将依赖
strlen的循环改为手动遍历,逻辑和strlen一致,但能更直观地观察读取情况:for (int i = 0; str[i] != '\0'; i++) { vidpointer = writebyte(vidpointer, str[i]); vidpointer = writebyte(vidpointer, printcolor); } - 检查编译选项:确认编译器未将只读段优化或放到错误位置,避免使用可能导致段分离的选项(如
-fdata-sections),除非你在链接脚本中已正确处理这些段。
内容的提问来源于stack exchange,提问作者Blue Herring
相关产品推荐
相关产品推荐

