openeuler 使用指令查找U盘:输入fdisk -l,内核崩溃 ,系统重启,使用lsblk显示正常,数据传输正常

报错日志:

[root@edgenode1 ~]# fdisk -l

Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors

Units: sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 4096 bytes

I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk /dev/mmcblk0: 116.48 GiB, 125074145280 bytes, 244285440 sectors

Units: sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disklabel type: gpt

Disk identifier: 878D3D1E-1622-41C8-C177-AD673846C697

Device Start End Sectors Size Type

/dev/mmcblk0p1 16384 32767 16384 8M unknown

/dev/mmcblk0p2 32768 40959 8192 4M unknown

/dev/mmcblk0p3 40960 565247 524288 256M unknown

/dev/mmcblk0p4 565248 827391 262144 128M unknown

/dev/mmcblk0p5 827392 892927 65536 32M unknown

/dev/mmcblk0p6 892928 244285406 243392479 116.1G unknown

[ 77.879852] Unable to handle kernel paging request at virtual address ffff7fc10593f1be

[ 77.887786] Mem abort info:

[ 77.890602] ESR = 0x96000004

[ 77.893674] EC = 0x25: DABT (current EL), IL = 32 bits

[ 77.898994] SET = 0, FnV = 0

[ 77.902065] EA = 0, S1PTW = 0

[ 77.905215] Data abort info:

[ 77.908089] ISV = 0, ISS = 0x00000004

[ 77.911935] CM = 0, WnR = 0

[ 77.914904] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000001c01000

[ 77.921608] [ffff7fc10593f1be] pgd=0000000000000000, p4d=0000000000000000

[ 77.928398] Internal error: Oops: 96000004 [#1] SMP

[ 77.933267] Modules linked in: sd_mod uas usb_storage scsi_mod xt_comment rtc_aip8563(O)

[ 77.941361] CPU: 6 PID: 1243 Comm: fdisk Tainted: G O 5.10.0 #63

[ 77.948653] Hardware name: Rockchip RK3588 EVB4 LP4 V10 Board (DT)

[ 77.954829] pstate: 00400009 (nzcv daif +PAN -UAO -TCO BTYPE=--)

[ 77.960830] pc : __memcpy+0x2c/0x180

[ 77.964404] lr : kmemdup+0x60/0x90

[ 77.967802] sp : ffff80001362bc80

[ 77.971108] x29: ffff80001362bc80 x28: ffff00011376ac40

[ 77.976411] x27: 0000000000000000 x26: 0000000000000000

[ 77.981714] x25: 0000000000000000 x24: 0000000000000000

[ 77.987016] x23: 00000000480a101d x22: ffff000108d35000

[ 77.992319] x21: ffff7fc10593f1be x20: 0000000000000042

[ 77.997621] x19: ffff00010ab49280 x18: 0000000000000000

[ 78.002924] x17: 0000000000000000 x16: 0000000000000000

[ 78.008225] x15: 0000000000000000 x14: 0000000000000000

[ 78.013526] x13: 0000000000000000 x12: 0000000000000056

[ 78.018828] x11: 0000000000000024 x10: 0000000000000a60

[ 78.024140] x9 : ffff80001022531c x8 : ffff00011376b700

[ 78.029442] x7 : 0000000000000004 x6 : ffff00010ab49280

[ 78.034743] x5 : 0000000000000000 x4 : 0000000000000002

[ 78.040054] x3 : 0000000000000080 x2 : 0000000000000040

[ 78.045356] x1 : ffff7fc10593f1be x0 : ffff00010ab49280

[ 78.050659] Call trace:

[ 78.053102] __memcpy+0x2c/0x180

[ 78.056336] scsi_bios_ptable+0x84/0xe4 [scsi_mod]

[ 78.061128] scsi_partsize+0x24/0x120 [scsi_mod]

[ 78.065748] scsicam_bios_param+0x24/0x114 [scsi_mod]

[ 78.070800] sd_getgeo+0xc8/0xe4 [sd_mod]

[ 78.074805] blkdev_ioctl+0x160/0x2c0

[ 78.078459] block_ioctl+0x44/0x54

[ 78.081860] vfs_ioctl+0x30/0x50

[ 78.085082] __arm64_sys_ioctl+0x68/0x9c

[ 78.089003] el0_svc_common.constprop.0+0x13c/0x1f0

[ 78.093870] do_el0_svc+0x84/0xa4

[ 78.097187] el0_svc+0x20/0x30

[ 78.100241] el0_sync_handler+0xcc/0x154

[ 78.104160] el0_sync+0x1a0/0x1c0

[ 78.107466]

[ 78.107466] PC: 0xffff8000106f266c:

[ 78.112418] 266c cb040060 d65f03c0 d343fc4c b400048c f240081f 540001a0 8b0a0000 8b0a0021

[ 78.120595] 268c cb0a0042 d343fc4c b40003ac f8408403 f8408424 f100058c ca040066 da9f10c7

 

linux内核、用户空间的内存划分:

如下图:32位系统内核空间划分0~3G为用户空间,3~4G为内核空间。详细请参考《Linux用户空间与内核空间

注意:内核地址空间的范围是 0xC0000000 ~ 0xFFFFFFFF 

而对于64位系统,内核空间划分如下:

ARM64架构处理器采用48位物理寻址机制,最大可以寻找到256TB的物理地址空间。对于目前的应用来说已经足够了,不需要扩展到64位的物理地址寻址。虚拟地址也同样最大支持48位支持,所以在处理器的架构设计上,把虚拟地址空间划分为两个空间,每个空间最大支持256TB。Linux内核在大多数体系结构中都把两个地址空间划分为用户空间和内核空间。

  • 用户空间:0x0000_0000_0000_0000到0x0000_ffff_ffff_ffff

  • 内核空间:0xffff_0000_0000_0000到0xffff_ffff_ffff_ffff

64位的Linux内核已经没有高端内存的概念了,因为48位的寻址空间已经足够大了

在QEMU实验平台上,ARM64架构的LInux内核的内存分布图如下:

如图所示,ARM64架构处理器的Linux内核内存布局图。ARM64架构处理器的Linux内核内存布局如下:

(1)用户空间:0x0000_0000_0000_0000到0x0000_ffff_ffff_ffff,一共有256TB。

(2)非规范区域

(3)内核空间:0xffff_0000_0000_0000到0xffff_ffff_ffff_ffff。一共有256TB。

内核空间又做了如下细分:

  • vmalloc区域:0xffff_0000_0000_0000到0xffff_7bff_bfff_0000,大小为126974GB。
  • vmemmap区域:0xffff_7bff_c000_0000到0xffff_7fff_c000_0000,大小为4096GB。
  • PCI I/O区域:0xffff_7fff_ae00_0000到0xffff_7fff_be00_0000,大小为16MB。
  • Modules区域:0xffff_7fff_c000_0000到0xffff_8000_0000_0000,大小为64MB。
  • normal memory线性映射区:0xffff_8000_0000_0000到0xffff_ffff_ffff_ffff,大小为128TB。

根据地址划分可以看出出问题的内核地址空间在vmemmap区域

vmemmap区域

 vmemmap是内核中page 数据的虚拟地址。针对sparse内存模型。内核申请page获取的page地址从此开始

异常内存访问导致的oops:


1、Unable to handle kernel paging request at virtual address 00000000

         =====》越出内核地址空间范围,原因是由于使用空NULL指针

2、Unable to handle kernel paging request at virtual address 20100110

    =====》越出内核地址空间范围,原因是的内存越界导致该指针

     所在内存被破坏了。 接下来的困难是在什么地方这个内存被修改?为什么被修改?

3、Unable to handle kernel paging request at virtual address c074838c

      =====》没有越出内核地址空间范围,为什么也oops?

     这种情况我称之为:试图篡改受限制内存。比如:声明为const的变量!

     还有其它形式的受限制内存吗?

三、访问受限制内存导致oops:
const在C语言当中声明一个变量为只读,
如果试图直接修改const变量,build阶段编译器,就检查出来,并报read only错误,
如下:
const int i = 1;
i = 10;
build error: assignment of read-only variable 'i'  //只读变量赋值错误

但是如果通过指针间接修改const变量,编译器是检查不出来的。
如下:
const int i = 1;
int *p = &i;    
*p = 10;
不出所料地编译成功了! 但不要高兴,这样的代码是有隐患的!
因为,很显然,我们将变量声明为const,是希望它能受到保护的!
既然编译器检查不出这种隐患,由谁负责保护它呢?
我想,linux只有运行时,由mm模块来保护声明为const的变量了!!!???
但遗憾的是,linux 3.4.5以前的版本一直没有这个保护功能,应该老版本linux自身的漏洞吧!
直到约linux 3.4.67 (android 4.4)才有运行时保护受限制内存的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值