לקראת פרויקט חדש, התחלתי ללמוד נושא שדי התחמקתי ממנו עד כה: כיצד כותבים Bootloader. בפוסט זה אדבר על הצרכים והשיקולים בכתיבה של Bootloader למיקרו-בקרים באופן כללי.
מה זה Bootloader
ה-Bootloader הינו תוכנה שיושבת לצד הקוד הראשי וה"רגיל", במיקום נפרד בזיכרון המיקרו-בקר, ורצה לפני הקוד הראשי בעת אתחול. ל-Bootloader (מעתה והלאה נקרא לו BL לשם קיצור) יכולים להיות מספר שימושים, והנפוץ ביותר מביניהם הוא כאמצעי לצריבה של קוד ראשי חדש – בלי צורך בצורב יקר, ואפילו בלי גישה פיזית ישירה למיקרו-בקר אלא רק דרך קווי תקשורת (קווית או אלחוטית) רגילים.
ככל שהתפקיד של המיקרו-בקר חשוב ומסובך יותר, כך עולה גם החשיבות של ה-BL ככלי לביצוע עדכונים ותיקוני באגים. שלט רחוק של טלוויזיה הוא פשוט יחסית ויכול לפעול עשרות שנים בלי שינוי, ולכן אין טעם לכתוב לו BL – אבל מערכת שמצפינה מידע, למשל, חייבת אפשרות להתעדכן (ומהר) אם מישהו יפרוץ את הסיסמה או את אלגוריתם ההצפנה הקיים.
הצד הטכני
אחת הבעיות הטכניות הגדולות ביותר בכתיבת BL היא המגבלות שארכיטקטורת המיקרו-בקר מציבה. דגמים שונים עשויים להקצות מקומות "שמורים" בזיכרון, בעלי גודל או מיקום מוגדרים מראש, שרק בהם מותר ל-BL להיות. יש מגבלות גם על האופנים בהם ה-BL יכול לצרוב את הקוד החדש ב-Flash. ומה קורה אם גם ה-BL וגם הקוד הראשי משתמשים בפסיקות? איך מגדירים טבלת ווקטורים (=פונקציות פסיקה) לכל אחד בנפרד ומחליפים ביניהן בעת הצורך? ואיך בכלל מודיעים לסביבת הפיתוח שהקוד שאנחנו כותבים עכשיו מיועד להיות BL ולא קוד רגיל?
כדי לכתוב BL חייבים למצוא את התשובות לשאלות האלה, אך כאמור הן תלויות לגמרי בכלים הספציפיים שאיתם אנחנו עובדים, ואין עיקרון-על שנכון לכל המקרים.
הקוד לצריבה
מה בעצם נשלח ל-BL ונצרב על ידו? בעיקרון אפשר לשלוח כל דבר, למשל תוכן חדש עבור כתובות מסוימות בזיכרון ה-EEPROM, אך מקובל לשלוח את קובץ ה-HEX שמופק על ידי הקומפיילר. מבחינת סביבת הפיתוח אנחנו כותבים קוד רגיל (פחות או יותר) למיקרו-בקר, אך במקום להעביר את הקוד המקומפל ישירות דרך צורב, אנחנו שומרים אותו בצד ומעבירים לתוכנה הייעודית שמדברת עם ה-BL.
פורמט HEX הוא פורמט מקובל בתעשייה לקוד מקומפל של מיקרו-בקרים, ובשונה מקובצי EXE של Windows, למשל, הוא לא כולל רק את הפקודות בקוד מכונה גולמי, אלא גם את הכתובות שבהן הפקודות אמורות להיכתב ועוד כמה פרמטרים, והכל כתוב כספרות בבסיס הקסדצימלי (1-16). כדי שהתוכנה וה-BL יידעו איך "לאכול" את קובץ ה-HEX, צריך לדעת לנתח אותו ולהוציא את המידע הרלוונטי.
וידוא כתיבה
הקוד הראשי החדש שמועבר ל-BL ונצרב על ידו חייב, כמובן, לעבור באופן מושלם. קוד שנצרב באופן חלקי או שגוי עלול לא לעבוד בכלל, או לעבוד עם באגים נסתרים, שיהיו הרבה יותר גרועים מאשר מערכת מושבתת. לכן, מעבר לפעולה הבסיסית של קליטת המידע וצריבתו, ה-BL מוכרח גם להבטיח שאין שום פגם בתהליך – ושאם בכל זאת קורה משהו, אז שלפחות הקוד הבעייתי לא יופעל.
שיטה מקובלת (שמוצעת, למשל, במסמך AN1310A של Microchip) היא ליצור מעין דיאלוג של מידע ושל אימותים בין ה-BL לבין התוכנה ששולחת לו את הקוד החדש. התוכנה הזו יכולה לרוץ על מחשב או על מיקרו-בקר אחר, כמובן. כל פיסת קוד שנשלחת ל-BL מלווה בקוד CRC (או אחר) לאיתור שגיאות. ה-BL מחשב עצמאית CRC עבור המידע, ומשווה בין מה שחישב למה שקיבל. במקרה של אי-התאמה, הוא יכול להכשיל את התהליך או לבקש שליחה חוזרת, בהתאם לתחכום של המערכת ולפרוטוקול שאנו מגדירים בינו לבין התוכנה.
בנוסף, אחרי שהקוד נצרב, על ה-BL לקרוא בחזרה את מה שצרב מזיכרון ה-Flash ולחשב על זה שוב את ה-CRC. כך הוא יכול לוודא שלא קרתה תקלת חומרה (למשל נפילת מתח קצרה) שפגמה בקוד, ושמה שנכתב ונשמר בזיכרון הוא אכן הקוד הנכון עד לרמת הביט הבודד.
התמונה הרחבה
אילוץ משמעותי נוסף בכתיבת BL הוא שכמעט בכל המקרים, לא יהיה למיקרו-בקר מספיק מקום בזיכרון כדי לאחסן ולבדוק את הקוד החדש במלואו לפני הצריבה. זה אומר שתהליך הצריבה דרך ה-BL חייב להתבצע בהמשכים, בחבילות מידע קטנות שנשלחות בזו אחר זו. לכן, מעבר להתמודדות עם קטעי הקוד הנפרדים, צריך משהו שיוודא שהתוכנית כולה הגיעה בשלמותה ונצרבה נכון, וגם זה צריך להיות חלק מהפרוטוקול.
לסיכום, כתיבה של BL ושל תוכנה מנהלת מחייבת היכרות עם הפרטים הטכניים של המיקרו-בקר ושל קובץ ה-HEX, והרבה בקרות ואימותים על המידע שעובר מצד לצד. במערכות רגישות מבחינת אבטחה, ה-BL יזדקק לשכבה נוספת של הצפנות ואימותים, כדי לוודא שאף צד שלישי לא יוכל לגנוב את המידע או לעשות בו מניפולציות בדרך.
כל זה נשמע אולי מרתיע, אך למעשה התכנות לא כזה מסובך – מה שחשוב זה לאתר את כל הפרטים הטכניים הרלוונטיים, להגדיר לעצמנו מראש את הפרוטוקול מתחילתו ועד סופו כדי לא ללכת לאיבוד, וכרגיל, לבדוק את המערכת ולדבג אותה בקפדנות, כי BL לא תקין שיוצא לשטח זה ממש לא נעים…