我的舊台機最近跑emerge的時候只要遇到compile很久的包(e.g. www-client/chromium)就會出現随機的segmentation fault或internal compiler error。因為每次出錯地方都不同,很明顯是舊電腦的硬體問題。检查硬碟後發現正常。跑memtest發現有一根RAM壞了。内存地址0x1AE501B8到0x1AFD3FE3出現錯誤。嗯,Gentoo真的可能比較傷硬體。
發現了問題就好解决。把壞掉的RAM拔掉(四根RAM唯一一根generic brand的。這教訓我硬體還是買名牌的好)。但這樣我就少了1GB了。買新的?這電腦舊到不想再化錢了。(我很吝啬)。Google一下發現GRUB2原來有很強的功能:
badram addr,mask[,addr,mask...]只要那OS的kernel由GRUB2手上拿取memory map,GRUB可以告訴启動的OS不要用某段内存。(像Windows這用chainload的OS應該不行吧?)badram接受和memtest的address/mask一樣的參數對。address是第一個内存地址。mask的定義是1指固定數位、0指可改變數位。
但是壞掉RAM的間隔很复雜,不是一組參數就可以specify的。所以必須分段解决。第一段比較容易:0x1AE501B8-0x1AEFFFFF。保持前3位不變的mask是0xFFF00000。從0x1AF00000開始就比較麻煩了。因為從0x0-0xD每個數位都變化。用簡單的mask那將會把一些正常的内存地址也包含在badram裡。所以要把這段間隔分成更小的間隔。例如用0x1AF00000,0xFFF80000可以加入0x1AF00000-0x1AF7FFFF。如此類推……
這麼麻煩的計算當然要交給電腦:
#!/usr/bin/evn python addr1 = 0x1AE501B8 addr2 = 0x1AFD3FE3 BASE = 0x100000000 def findmask(a0, a1, pcount = 1): if a0 > a1: raise ValueError ("Second argument must be greater than or equal to the first argument") msk = 0xFFFFFFFF oldmsk, oldsum = msk, a0 while True: D = (( a0 | ~msk ) % BASE) if D <= a1: oldsum = D oldmsk = msk if D >= a1: break msk = ( msk << 1 ) % BASE print "%2d: 0x%X, 0x%X, 0x%X" % (pcount, a0, oldmsk, oldsum) if oldsum == a1: return oldmsk, oldsum else: return findmask(oldsum+1, a1, pcount + 1) findmask(addr1, addr2)出來的結果:
address | mask | RANGE |
---|---|---|
0x1AE501B8 | 0xFFF00000 | 0x1AEFFFFF |
0x1AF00000 | 0xFFF80000 | 0x1AF7FFFF |
0x1AF80000 | 0xFFFC0000 | 0x1AFBFFFF |
0x1AFC0000 | 0xFFFF0000 | 0x1AFCFFFF |
0x1AFD0000 | 0xFFFFE000 | 0x1AFD1FFF |
0x1AFD2000 | 0xFFFFF000 | 0x1AFD2FFF |
0x1AFD3000 | 0xFFFFF800 | 0x1AFD37FF |
0x1AFD3800 | 0xFFFFFC00 | 0x1AFD3BFF |
0x1AFD3C00 | 0xFFFFFE00 | 0x1AFD3DFF |
0x1AFD3E00 | 0xFFFFFF00 | 0x1AFD3EFF |
0x1AFD3F00 | 0xFFFFFF80 | 0x1AFD3F7F |
0x1AFD3F80 | 0xFFFFFFC0 | 0x1AFD3FBF |
0x1AFD3FC0 | 0xFFFFFFE0 | 0x1AFD3FDF |
0x1AFD3FE0 | 0xFFFFFFFC | 0x1AFD3FE3 |
$ echo 'GRUB_BADRAM = "0x1AE501B8,0xFFF00000,0x1AF00000,0xFFF80000,..."' >> /etc/default/grub $ grub2-mkconfig -o /boot/grub2/grub.cfg就可以了。把壞掉的内存地址排除掉後memtest没有找到新的錯誤。www-client/chromium正在快樂compile中……
No comments:
Post a Comment