لو جهاز S19 Pro عندك طاح أدائه وما عاد يعطيك الـ 110 TH/s المعتادة، وواجهة المستخدم تظهر لك 0 بدل 76 رقاقة أو السلسلة مقطوعة — خلاص، لازم تسحب لوحة الهاش للفاحص وتفكها على طاولة الصيانة. في 90% من الحالات، السبب يكون انفصال الكريستالة من الحرارة العالية، أو ضربة في منظم الجهد (LDO)، أو كسر دقيق (micro-crack) في شريحة التكستوليت.
معمارية لوحة الهاش في S19 Pro: تقسيم النطاقات والإشارات
تجي لوحة الهاش في Antminer S19 Pro محملة بـ 76 رقاقة من نوع BM1398، مقسمة على 19 نطاق طاقة متسلسل (كل نطاق فيه 4 رقاقات). الجهد الإجمالي للناقل (تقريباً 12.5–15 فولت حسب السوفتوير) يتوزع بينها بالتساوي. يعني كل نطاق يأخذ حوالي 0.7–0.8 فولت، والرقاقة نفسها تتغذى بجهد VCORE في حدود 0.32–0.42 فولت.
الإشارات تمشي بالترتيب في السلسلة من الرقاقة الأولى (جنب سوكت لوحة التحكم) لين الرقاقة رقم 76:
- CLK (25 MHz): إشارة التوقيت (الساعة). لو انقطعت عند الرقاقة رقم 30، كل الرقاقات اللي بعدها بتطفي فوراً.
- CO (Command Output): خط الأوامر الداخل من لوحة التحكم.
- RI (Return Input): خط الاستجابة الراجع للوحة التحكم. يمشي بالعكس — من الرقاقة 76 للرقاقة 1.
- RST (Reset): خط إعادة الضبط. لو نزل مستواه، يدخل الرقاقة في حالة ريست كاملة.
- BO (Busy Output): إشارة انشغال الخط.
خطوات التشخيص: من سجلات السجل (Kernel Log) لفحص الاتصالية
افتح الـ Kernel Log عن طريق واجهة الويب للجهاز أو السوفتوير المعدل مثل (VNish أو HiveOS). وشوف السلسلة وين فصلت بالضبط وتصفرت.
شنو تدور عليه في اللوج:
- Chain 1: found 0 asics — ما في أي رد على خط الـ RI. تشيك فوراً على الرقاقة الأولى، وتغذية الـ LDO الخاصة فيها، أو كابل الإشارة نفسه.
- Chain 2: only 42 asics found — الإشارة "علقت" عند الرقاقة 42 أو 43. افحص هذه المنطقة مباشرة.
- Read temp sensor failed — حساس الحرارة TMP75 ضرب. في S19 Pro، الحساسات موزعة على أكثر من نطاق. وإذا مات الحساس، اللوحة ما راح تشتغل كإجراء حماية.
قياس نقاط الاختبار (Test Points)
غذّي اللوحة من باور سبيشل للمختبر أو جهاز فحص (بدون ما تضخ أمبير عالي على الناقل)، واضبط الملتيميتر على وضع فحص الدايود (الطرف الأحمر على الأرضي GND).
[Chip 42] ---> (CO / CLK / RST) ---> [Chip 43]
[Chip 42] <--- (RI / BO) <--- [Chip 43]مقاومة خطوط الإشارة عند نقاط الاختبار بالنسبة للأرضي لازم تكون متقاربة ومتناسقة على طول اللوحة:
- CLK, CO, RI, RST: تقريباً في حدود 450–600 أوم.
لو لقيت نقطة CLK عند الرقاقة 43 تعطي صفر أوم (شورت كامل) أو تعطي ما لا نهاية (قطع) — خلاص، الرقاقة محتاجة تبديل.
تغذية الـ LDO
كل نطاق يحتاج جهود مساعدة لتشغيل الدوائر المنطقية الداخلية للرقاقة. واللي يزودها هي منظمات LDO صغيرة:
- VDD 1.8V: لتغذية دوائر الإشارة.
- VDD 0.8V: لتغذية النواة المنطقية الداخلية.
لو الرقاقة واصلها 1.8V وبنفس الوقت غائب عنها الـ 0.8V — ما راح تقدر تمرر إشارة الـ CLK للرقاقة اللي بعدها، واللوحة بتقص السلسلة عندها.
ليه تحتاج الأوسيلوسكوب وكيف تشتغل بيه؟
الملتيميتر يعطيك بس متوسط الجهد المستمر (DC). لكنه الملتيميتر ينعمي وما ينفع لو الجهد ممتاز بس الإشارة مشوهة بنويز أو سعتها طايحة. الملتيميتر ممكن يخدعك بامتياز، بينما الأوسيلوسكوب يوريك شكل الموجة الحقيقي فوراً.
تحتاج جهاز بنطاق ترددي لا يقل عن 100 MHz مع بروب (Probe) بمقسم 10X.
فحص إشارة الـ CLK (تردد الساعة 25 MHz):
حط رأس البروب على نقطة اختبار الـ CLK. المفروض تشوف موجة جيبية (Sinusoidal) متناسقة أو موجة مربعة بسعة تقارب 1.8V. لو شفت بدل الإشارة السليمة موجة مشوهة بسعة 0.4V — فهذا يعني أن البافر (Buffer) الداخلي للرقاقة انحرق وما يقدر يدفع الإشارة للي بعدها.
فحص حزم البيانات CO/RI:
أول ما تشتغل اللوحة ترسل نبضات سريعة. على الأوسيلوسكوب تظهر كأنها قفزات خاطفة (Burst). لو الحزمة وصلت لمدخل الرقاقة 43 وما طلع من مخرجها شيء — فالرقاقة ميتة، أو إشارة الـ RST عندها معلقة على الصفر.
التموجات على خط التغذية (Ripple):
حول مدخل الأوسيلوسكوب لـ AC (المدخل المغلق) وقس المكثفات مباشرة تحت بطن الرقاقة. لو التموجات أكثر من 30–40 millivolt، فهذا دليل أن مكثفات السيراميك حول الرقاقة تلفانة من الحرارة العالية المستمرة.
دليل نقاط الاختبار مرجعي (Antminer S19 Pro / BM1398)
| الخط | الجهد الطبيعي (DC) | الإشارة على الأوسيلوسكوب | المقاومة مع الأرضي (GND) | العرض عند الانقطاع |
|---|---|---|---|---|
| CLK | 0.8–0.9V | موجة جيبية 25 MHz، بسعة 1.8Vpp | 500–600 أوم | تتوقف السلسلة عند الرقاقة التالفة |
| CO | 0–0.2V | حزم نبضات 1.8V أثناء الاستعلام | 500–600 أوم | يتوقف الاستعلام عن باقي الرقاقات |
| RI | 1.7–1.8V | حزم نبضات أثناء الاستجابة | 500–600 أوم | يعطي 0 ASICs أو يقص الجزء الأخير من اللوحة |
| RST | 1.8V | مستوى منطقي مرتفع (High) | 500–650 أوم | الرقاقات تظل معلقة في وضع الريست |
| VDD 1.8V | 1.8V | خط صافي (تشويش AC أقل من 20mV) | 1–3 كيلو أوم | توقف بافرات الإدخال والإخراج (I/O) |
| VDD 0.8V | 0.8V | خط صافي (تشويش AC أقل من 15mV) | 100–300 أوم | توقف النواة الداخلية للرقاقة |
الجانب العملي لللحام: فك وتركيب الرقاقة BM1398
لوحات الألومنيوم في S19 Pro تشتغل كمشتت حراري ضخم. أنك تحاول تفك الرقاقة بالهوت اير من فوق بس — هذه أسرع طريقة عشان تحرق الطبقات وتطير المبادئ والمسارات (Pads).
شنو تحتاج للعملية:
- سخان سفلي (Preheater) ببروفايل حراري بين 160–180°C.
- كاوية هوت اير (مع نازل بمقاس الرقاقة).
- فلر BGA ناعم ما يحتاج غسيل (مثل NC-559 أو Martin أو RMA-223).
- كور قصدير بالرصاص مقاس 0.35 مم أو معجون قصدير رصاصي Sn63/Pb37 (الرصاص ينصهر عند 183°C، وهذا يسهل حياتك مقارنة بقصدير المصنع الخالي من الرصاص Lead-Free).
خطوات العمل:
- نحط اللوحة على السخان السفلي ونرفع الحرارة بالتدريج لين 150–160°C. لو استعجلت — التمدد الحراري المختلف بين التكستوليت والألومنيوم بيلوي اللوحة عليك مثل الموزة.
- نحط شوية فلكس تحت الرقاقة.
- نسخن بالهوت اير من فوق (حرارة الهواء الخارجي تقريباً 340–360°C مع تدفق هواء متوسط). التسخين يكون بحركات دائرية.
- نلمس الرقاقة بالملقط بخفة: أول ما تحس إنها "عامت" على الكرات، ارفعها بشويش ورأسياً للأعلى.
- ننظف المسارات على اللوحة باستخدام شيلد نحاسي (Copper Braid) مع كولوفونية، ونغسل المنطقة بإيزوبروبانول أو ثينر نظيف.
- نعيد صب الكرات (Reballing) للرقاقة الجديدة باستخدام الشابلون ومعجون القصدير الرصاصي أو الكور.
- نضبط اتجاه الرقاقة حسب الدليل (علامة النقطة على جسم الرقاقة ولازم تطابق الرسم المطبوع على اللوحة)، ونوزنها صح.
- نسخن بالسخان السفلي مع هواء خفيف من فوق لين تنزل الرقاقة. الرقاقة بتتمركز وتسحب نفسها مكانها تلقائياً بفضل الشد السطحي للقصدير المذاب.
سكربت Python للوجات للتسريع والتشخيص السريع
بدل ما تقعد تقرأ اللوجات وتضيع وقتك يدوياً، هذا سكربت جاهز. تعطيه ملف اللوج من الجهاز، وهو يحلل السلسلة الخربانة ويخبرك فوراً على أي رقاقة تحط الملتيميتر.
#!/usr/bin/env python3
import re
import sys
EXPECTED_ASICS = 76
def parse_asic_log(filepath):
chain_pattern = re.compile(
r"Chain\[(\d+)\]:\s*found\s*(\d+)\s*asics",
re.IGNORECASE
)
sensor_pattern = re.compile(
r"sensor[\[\s]*(\d+)[\]\s]*.*temp.*error",
re.IGNORECASE
)
issues_found = False
problem_chains = []
reported_sensors = set()
print(f"[*] Parsing log file: {filepath}\n")
try:
with open(filepath, "r", errors="ignore") as f:
for num, line in enumerate(f, 1):
# Check ASIC counts per chain
c_match = chain_pattern.search(line)
if c_match:
chain_id = int(c_match.group(1))
found = int(c_match.group(2))
if found < EXPECTED_ASICS:
issues_found = True
problem_chains.append(
(chain_id, found, EXPECTED_ASICS)
)
print(
f"[!] Chain {chain_id}: found "
f"{found}/{EXPECTED_ASICS} ASICs."
)
if found == 0:
print(
" -> First ASIC in chain not detected."
)
print(
" -> Inspect board power rail, RI, "
"RST, BOOT, and CLK signals."
)
else:
print(
f" -> Probe output signals (CLK/CO) "
f"on ASIC #{found}"
)
print(
f" -> Probe input signals (RI) and "
f"LDO rail on ASIC #{found + 1}"
)
print()
# Check temperature sensor faults
s_match = sensor_pattern.search(line)
if s_match:
sensor_id = int(s_match.group(1))
if sensor_id not in reported_sensors:
issues_found = True
reported_sensors.add(sensor_id)
print(
f"[!] Thermal sensor fault on "
f"sensor #{sensor_id} (Line {num})."
)
print(
" -> Check TMP75 IC, LDO power rail, "
"and I2C bus lines."
)
print()
# Final Diagnostic Summary
print("=" * 60)
print("DIAGNOSTIC SUMMARY")
print("=" * 60)
if not issues_found:
print("[+] No known error patterns detected in log.")
return False
if problem_chains:
print("\nFaulty Chains:")
for chain_id, found, expected in problem_chains:
print(
f" - Chain {chain_id}: "
f"{found}/{expected} ASICs detected"
)
if reported_sensors:
print("\nThermal Sensor Faults:")
for sensor_id in sorted(reported_sensors):
print(f" - Sensor #{sensor_id}")
print()
return True
except FileNotFoundError:
print(f"[-] File not found: {filepath}")
return True
except Exception as e:
print(f"[-] Error processing file: {e}")
return True
if __name__ == "__main__":
if len(sys.argv) < 2:
print(
f"Usage: {sys.argv[0]} <path_to_log.txt> "
f"[expected_asics]"
)
sys.exit(1)
if len(sys.argv) >= 3:
try:
EXPECTED_ASICS = int(sys.argv[2])
except ValueError:
print("[-] expected_asics must be an integer.")
sys.exit(1)
has_issues = parse_asic_log(sys.argv[1])
sys.exit(1 if has_issues else 0)أمثلة التشغيل:
python diag.py kernel.log
لو اللوحة فيها عدد مختلف من الرقاقات:
- python diag.py kernel.log 63
- python diag.py kernel.log 72
- python diag.py kernel.log 80
قائمة التجميع والاختبار النهائي قبل التقفيل في الشاسي
- مقاومة ناقل الـ VCORE: تأكد أن المقاومة مع الأرضي مو صفر (يعني ما في شورت).
- اختبار الـ LDO بدون حمل كامل: شغل اللوحة من باور المختبر، وتشيك وجود الـ 1.8V والـ 0.8V عند الرقاقة المبدلة.
- تتبع الإشارة: افحص بالأوسيلوسكوب تأكد أن تردد الـ 25 MHz يمر من الرقاقة الجديدة للي بعدها بسلاسة.
- اختبار الضغط والأداء العالي: ركب جهاز التعدين كامل مع مراوحه الأصلية، وشغل اللوحة على السوفتوير الأساسي لمدة 2–3 ساعات، وراقب أخطاء الـ HW على هذه السلسلة.