在分配之前我怎么知道,我可以创建多大的数组?或者如何定位我的数组以使其不与内存映射中的某些内容冲突?
我有这个配置
VM running on Virtualbox with
Operating system: Centos 7
Memory: 2GB
Processor: E7500@2,9Ghz
Host OS: Suse Leap 41
我有这段代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_DESCRIPTION("linux module");
MODULE_AUTHOR ("doald duck");
static int __init KM () {
size = 100000;
size = 10*100000;
printk( "creating an int aray of %d 1st ....\n",size);
int ia [size];
int ia_ = -1;
while (++ia_ < size ){
ia [ia_] = ia_ +2000;
}
return 0;
}
static void __exit _KM () {
printk ("unloading 'za module ");
}
module_init (KM);
module_exit (_KM);
如果尺寸保持在100000;模块正在加载,rmmod完美运行.. 如果以某种方式我做size = 10 * 100000然后发生内核恐慌并重新启动
呼叫追踪是:
[ 155.751747] creating an aray of 1000000 1st ....
[ 155.753448] BUG: unable to handle kernel paging request at ffff88007c408000
[ 155.753629] IP: [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1]
[ 155.753962] PGD 3f32067 PUD 3f35067 PMD 3ed00063 PTE 800000007c408161
[ 155.754065] Oops: 0003 [#1] SMP
[ 155.754170] Modules linked in: kernel_module1(POE+) ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter vfat fat snd_intel8x0 snd_ac97_codec ac97_bus snd_seq iTCO_wdt iTCO_vendor_support ppdev snd_seq_device snd_pcm snd_timer snd soundcore parport_pc pcspkr parport lpc_ich mfd_core sg i2c_piix4 video i2c_core ip_tables xfs libcrc32c sr_mod cdrom sd_mod ata_generic crct10dif_generic crc_t10dif crct10dif_common pata_acpi ahci libahci ata_piix serio_raw libata e1000 dm_mirror
[ 155.754955] dm_region_hash dm_log dm_mod
[ 155.754979] CPU: 0 PID: 2562 Comm: insmod Tainted: P OE ------------ 3.10.0-327.13.1.el7.x86_64 #1
[ 155.755086] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 155.755190] task: ffff88007c72f300 ti: ffff88007c668000 task.ti: ffff88007c668000
[ 155.755286] RIP: 0010:[<ffffffffa0037037>] [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1]
[ 155.755391] RSP: 0018:ffff88007c29b450 EFLAGS: 00010287
[ 155.755487] RAX: 000000000005b2ec RBX: ffffffff81951020 RCX: ffff88007c29b450
[ 155.755594] RDX: 000000000005babc RSI: 0000000078e678e4 RDI: 0000000000000246
[ 155.755687] RBP: ffff88007c66bd58 R08: 0000000000000086 R09: 0000000000000269
[ 155.755782] R10: 0000000000000000 R11: ffff88007c66ba6e R12: ffff8800026609c0
[ 155.755877] R13: ffffffffa0037000 R14: 0000000000000000 R15: ffffffffa03e4000
[ 155.755974] FS: 00007f6dfdbc4740(0000) GS:ffff88007da00000(0000) knlGS:0000000000000000
[ 155.756074] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 155.756164] CR2: ffff88007c408000 CR3: 000000007c606000 CR4: 00000000000006f0
[ 155.756262] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 155.756356] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 155.756451] Stack:
[ 155.756527] 000007d1000007d0 000007d3000007d2 000007d5000007d4 000007d7000007d6
[ 155.756635] 000007d9000007d8 000007db000007da 000007dd000007dc 000007df000007de
[ 155.756745] 000007e1000007e0 000007e3000007e2 000007e5000007e4 000007e7000007e6
[ 155.756842] Call Trace:
[ 155.756923] Code: e5 e8 23 81 5f e1 be 40 42 0f 00 48 c7 c7 48 30 3e a0 31 c0 e8 10 81 5f e1 48 81 ec 08 09 3d 00 31 c0 48 89 e1 8d 90 d0 07 00 00 <89> 14 81 48 ff c0 48 3d 40 42 0f 00 75 ec 48 c7 c7 3b 30 3e a0
[ 155.757153] RIP [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1]
[ 155.757246] RSP <ffff88007c29b450>
[ 155.757329] CR2: ffff88007c408000
主要是因为它到达了一个无法分配的地址......
答案 0 :(得分:5)
在内核空间中运行的进程的默认堆栈大小为8192字节,但根据体系结构可能会更少。
要求大小的记忆,请使用kmalloc
,这是朋友。
size_t sz = 10000;
int *ia = kmalloc(sz, GFP_KERNEL);
if (ia == NULL)
{
/* allocation failed, handle error */
return -1;
}
/* OK, though it may have allocated more than you asked for */