2016-04-15 12 views
1

割り振る前にどのくらいの大きさの配列を作成できますか?または、メモリマップ内の何かと矛盾しないように配列を配置する方法は?linuxカーネルモジュールの最大ポインタ/配列サイズ

私はこの構成

VM running on Virtualbox with 
Operating system: Centos 7 
Memory: 2GB 
Processor: [email protected],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のままならば、どういうわけか、私はサイズをすれば= * 100000 10は、その後、パニックが発生し、カーネルと

コールトレースを再起動 ..モジュールがロードされるとrmmodはは完璧に動作することです:

[ 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 

それがアドレスに達したため、ほとんどの理由があります割り当てられない...

+5

ほとんどの場合、**カーネル**にはスタックに何も割り当てられません。 –

+1

カーネルでkmallocを実行します。それは何らかの理由で失敗した場合、パニックに陥ることはありません。 – stark

+0

ええ、kmallocはここに行く道です – Luanf

答えて

4

カーネル空間で実行されているプロセスのデフォルトのスタックサイズは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 */ 
+0

優秀、 私は大きな数字の前にkmallocを試しました。これはNULLをチェックするのに最適な解決策です:) –