第十二章B〈地板下面〉
台版 v1
地點:鏡界・翠鏡島 / 大陸代工廠區 / 書房 時間:1024年(交叉時間線) 視角:阿強 / 林昭明
阿強收到新 case 那天,沒覺得有什麼特別。
能芯的新模組。第三代。架構和上兩代不同——以前的模組,核心運算和周邊對接是分開的,你處理你的,我處理我的,中間靠標準協議溝通。第三代不是。它把運算和周邊整合在一起。一粒模組做完。效率高。但對接的方式,和以前完全不同。
這不是秘密。行業裡的人都知道。規格書是公開的。技術論壇討論了幾年。
阿強接到 case,第一件事是看靈韻合成的 firmware。
他做了十五年,這個動作是本能。你要知道自己站在哪裡,才知道問題在哪裡。
他看了兩天。
不是因為難。是因為他要確認自己沒有看錯。
整個 firmware 的核心邏輯——不是某一段,是整個——從 boot sequence 到 power management 到 peripheral handshake,每一層的 assumption 都是寫死了、傾向舊架構的。舊架構的意思是:以某間主流晶片商為中心。誰是 primary,誰是 secondary,整個 code 的邏輯是建立在這個不平等的前提上面的。
新模組不走這一套。而且新模組的架構其實更高效。
阿強站在廠房的走廊,看著窗外的天。他知道正常來說應該怎麼做——重構。至少 rewrite 和新架構對接那幾層。不是推倒重來。但核心那幾層,你要改。因為前提變了。你不改,上面疊多少東西——不斷出 update 去修補——都只是在一個傾斜的地基上蓋房子。
他等著靈韻合成那邊的方案。
等了兩個禮拜。
方案來了。
Workaround。
不是一個。是一串。在舊 architecture 上面,加一層 translation layer,把新模組的 protocol 轉成舊格式,再餵給 firmware。中間的 timing mismatch,用 delay buffer 頂住。Power state 的差異,用一個 lookup table 硬 map。
阿強坐在自己的 位子,看著那份方案。
他做了十五年。他見過 workaround。每間都有。有時候 deadline 趕,你沒有時間做 proper fix,workaround 是合理的。臨時的。過渡的。你寫的時候心裡面知道——這個之後要改回來。
但他看得出。
這個不是臨時的。
靈韻合成很認真地寫 workaround,但沒有任何計劃去改核心邏輯。沒有 roadmap。沒有 timeline。沒有人提過。這個複雜到極點的 workaround 就是「方案」。不是過渡。是終點。
他看著那份文件的最後一頁。「建議方案」四個字。沒有附錄。沒有「Phase 2:核心邏輯調整」。沒有「長期規劃」。
這就是全部。
Workaround 行不行?
行。大部分時候行。
但有邊角 case。有 timing issue。有些情況下 power state 會不同步。不是每次都發生。但會發生。
發生了怎麼辦?
靈韻合成的答案:叫供應商查。
阿強查。查完。不是供應商的問題。是 translation layer 的 timing mismatch。他寫在報告裡。用字很小心。沒有直接說「你們的 workaround 有問題」。他寫:「經分析,偏差來源與新舊協議轉換過程中的時序差異相關。建議評估 base code 層面的調整方案。」
回覆:「已收到。請繼續監測。」
他繼續監測。問題再出現。他再寫報告。
回覆:「請提供更多數據以供分析。」
他提供了。
然後靜了。
過幾天。Firmware 有一個 minor update。Changelog:「穩定性優化。」
問題暫時沒有再出現。
阿強知道他們做了什麼。他們做了非常複雜的補救——調了 delay buffer 的參數,加了幾條例外處理。很認真。但治標不治本。根本的核心邏輯偏向還在。下次換一個邊角 case,又會出來。然後又叫他查。然後又加補丁 code。然後又「穩定性優化」。循環。
他看回自己那句「建議評估 base code 層面的調整方案」。
在回覆裡,這句話沒有被提及。
好像他沒有寫過。
他之後再寫報告,沒有再寫這句。
阿強記得第一年問過一個問題。
不是很正式的。是一個會議尾聲,大家在收拾東西,他順口問了一句。
「為什麼 firmware 只圍繞舊架構設計?新模組那邊的 support⋯⋯」
他還沒說完。
不是有人打斷他。是氣氛變了。很微妙。好像有人在房間裡開了冷氣,但你找不到冷氣在哪裡。
靈韻合成那邊的人,有一個回答了。
「這個架構在市場上的份額很小。品質還有很多問題。我們的重點是服務主流用戶。這些東西交給 ODM 自己 handle 就好。」
阿強點頭。合理。
之後另一個人在 email 裡提過類似的事。用字不同,意思一樣:「這個架構的兼容性問題是已知的。品質和穩定性和主流方案有差距。ODM 那邊有經驗處理。」
再之後,一個私下的場合,還有人跟他說過。語氣不同。不是解釋。是一種⋯⋯他那時找不到詞。
後來他找到了。
那個語氣不是安撫。是警告。
「這個不是你要管的事。」
沒有人說這句話。但每一個人的語氣都是這句話。
阿強那時以為是公司政策。正常的。每間公司都有它的 focus。你不可能 support 所有東西。這個他理解。
他沒有再問。
但後來——很久之後——他偶爾會想起這件事。
不同的人。不同的場合。一樣的答案。一樣的措辭。一樣的語氣。
正常的公司,你問一個技術問題,不同的人會有不同角度的答案。有人從成本講。有人從技術講。有人從 schedule 講。因為每個人站的位置不同,看到的東西不同。
但他問的這個問題——所有人的答案一樣。
阿強不知道這代表什麼。可能只是公司的 official position 很清楚。可能只是大家都認同這個判斷。
可能。
阿強有一次和林昭明吃飯。出差。晚餐。一間普通的餐廳。
公事聊完。飯吃到一半。不知道怎麼聊到 firmware。可能是因為阿強那天做的 case——又是一個兼容性 issue,又是 workaround,又是「供應商查一查」。他有點累了。累的時候人會說多一些。
「林先生,你有沒有注意過⋯⋯靈韻合成的 firmware update,過去兩年,出了多少個?」
林昭明搖頭。
「我數過。六十幾個。」阿強喝了口東西。「六十幾個。很認真。每隔幾個禮拜就有。Feature 改了。Performance tuning 做了。Bug fix 做了。你看 changelog,很長。很詳細。好像很努力。」
他停了。
「但你知不知道——六十幾個 update,改了那麼多東西——核心那套邏輯有沒有變過?」
林昭明看著他。
「沒有。」
阿強放下杯子。
「你要在裡面做才知道。或者你要會看數據。公開的 changelog 不會告訴你。它寫著『穩定性優化』『兼容性改善』『效能提升』——你看完覺得很正常。但你拿著數據去對,你會發現:新架構的問題還在。每一次改完,那些邊角 case 還是會出現。改了六十幾次,核心的 timing mismatch 沒有變過。因為它改的東西全部是圍繞著舊那套邏輯轉。」
他看著桌面。
「它不是沒有做事。它做了很多事。但做的所有事都是在同一個框架裡面。框架本身——誰是 primary,誰是 secondary——沒有人碰過。」
林昭明問:「你覺得是做不到,還是不想改?」
阿強看著他。這個問題很直接。直接到他要想一下才能回答。
「⋯⋯做不到的東西我見過。做不到是有原因的。你看得出哪裡卡住,哪裡資源 不夠,哪裡技術還沒到。做不到的樣子是——有人在試,但還沒成功。」
他停了。
「這裡不是那個樣子。這裡是——很認真地在繞開那個核心。他們寧願每次出 update 都寫幾百行複雜的 workaround 去補救,也不肯改底層那幾行 code。好像有一種無形的力量,把那個框架鎖死了不准碰。」
林昭明聽完很久沒有說話。他喝了口水。然後問:
「你有沒有想過——為什麼不准碰?」
阿強很久沒有出聲。餐廳的聲音在他們之間流過。碗碟聲。其他桌的說話聲。冷氣的嗡嗡聲。
「我想過。」
「你的答案呢?」
「⋯⋯可能不是一個我應該知道的答案。」
林昭明很慢地點頭。
「我明白。」
沉默。
阿強忽然說了一件事。不是計劃好的。是那種累到一個程度、對著一個你覺得聽得懂的人,會不小心說出來的話。
「林先生。這些 workaround——我們寫了多少、怎麼寫的——你知道是不能寫在明面的。」
林昭明看著他。
「我知道。」
「不是因為 workaround 本身有問題。Workaround 每間廠都有。」
「我知道。」
阿強握著杯子。啤酒變熱了。
「是因為——如果有人問,『你們為什麼要寫那麼多 workaround』,答案會牽到一個地方。」
他停了。
「沒有人想去的地方。」
林昭明看著他。很久。
「你知道那個地方是哪裡。」
阿強沒有回答。他喝了最後一口。熱的。苦的。
「我不知道。我只知道——不要問。」
林昭明那天晚上回到家,沒有馬上開電腦。
他坐在書房,看著桌面。阿強的話在他腦子裡轉。
「改了那麼多東西——核心那套邏輯有沒有變過?沒有。」
「做的所有事都是在同一個框架裡面。」
「寧願寫幾百行 workaround 補救,也不肯改底層那幾行 code。」
他想起自己在靈韻合成裡面的經歷。有一次,他在一個內部會議裡問過類似的問題——不是問 firmware,是問一個流程的設計。他問:「為什麼這個流程不改?明明有更有效的方法。」
答案是什麼?他記得。不同的人。不同的場合。一樣的答案。
「這個是歷史上就這樣做的。」
「改的風險太大。」
「你沒有經驗才會覺得可以改。」
他那時以為是自己不夠了解。
現在他不這麼想了。
他開了電腦。
林昭明那天晚上搜尋的關鍵字和平時不同。
他打了「品牌廠」「晶片商」「回扣」。
頭幾頁沒什麼。行業新聞。產品發布。正常的東西。
然後他找到一件舊案。
幾年前。一間品牌廠。全球前幾大。被監管機構查出——長期收取某間晶片供應商的巨額款項。條件是:不用競爭對手的產品。
林昭明看到這裡,停了。
他繼續看。
款項的規模是天文數字。持續了幾年。品牌廠的高層知情。他們把這些款項混入正常收入,讓財報好看。當晶片商停止支付,品牌廠的利潤馬上萎縮——但他們向投資者隱瞞了真正的原因。
監管機構查了幾年。最後品牌廠賠了天文數字的和解金。高層罰款。件事上了新聞,又很快沉了下去。
林昭明記下了時間線。
開始收取:某年。被查:幾年後。和解:再幾年後。
和解之後呢?
他找。
品牌廠的公告寫著:「已全面配合監管要求,完善內部合規制度。」晶片商那邊也有類似的聲明。法律程序結束。罰款交了。件事過了。
但他想看的不是這些。
他找技術論壇。帖子不多。有些已經刪了,靠 cache 才看到殘留的片段。
有一個帖子,寫在和解之後兩年。標題很平淡:「XX 品牌對 YY 架構的支援現況。」
內容不平淡。
那個人用了很長的篇幅,逐層分析 firmware 的 boot sequence。結論是:表面上不斷更新,但核心邏輯沒有變。和解之前是這樣,和解之後還是這樣。整個 firmware 的 assumption——哪種晶片是 primary,哪種是 secondary——寫死在 code 裡面,之後所有的 update 都只是圍著這個 assumption 去修補。
有人在下面回覆:「你 expect 他們因為一件官司就 rewrite 整個 firmware?太天真。加 workaround 最省。」
又有人回:「我不 expect rewrite。我 expect 的是不要繼續當另一個架構不存在。但你看他們過去幾十個 update,寧願繞大圈加補丁,都不肯修正那個底層——到今天還是二等公民。」
帖子很舊。回覆不多。後來的討論被刪了幾條。
林昭明再找。找更近期的。
有。零星的。散落在不同的論壇。用字很小心。沒有人直接說那句話。但有人問過——
「和解之後十幾年,firmware 改了幾百次,但架構偏向還是一樣。如果真的沒有利益關係,純粹是 legacy code 的問題——十幾年出那麼多 update,每次都精準避開那個核心去修補?」
沒有人回答。
不是沒有人看到這個問題。是沒有人回答得了。或者沒有人敢回答。
林昭明看著螢幕。
他在筆記裡寫:
「開始收取——某年。」 「和解——幾年後。聲明停止。」 「和解之後至今——firmware 表面狂改,但核心前提不變。Workaround 不斷疊加。新架構仍然是二等公民。ODM 仍然在收尾。」
他停下來。
十幾年。
如果真的停了。十幾年你出幾百個 update,寧願把整個 firmware 寫到九彎十八拐,都不去改底層那一個不平等的前提?你是全球前幾大的品牌廠 。你有幾千個工程師。你每年的研發預算是天文數字。
十幾年。
如果真的停了。
林昭明看著自己寫的東西。他在最後那行底下,沒有寫問題。只寫了一個問號。
一個問號。
因為那個問題——如果寫出來——他自己也不知道意味著什麼。
他沒有關電腦。
他翻回自己之前做的那張表。第十二章那張。左邊「每間都有」,右邊「不同」。
右邊那欄。他一條一條看。
「明知沒問題還叫你再測。」 「零點三度叫你重做。」 「良率好了和你的測試沒有關係。」 「你提出疑問被當沒說過。」 「結論先定好,叫你測試只是填過程。」
他把這些和 firmware 的資料放在一起。
然後他做了一件事——他翻回過去兩年的測試紀錄。不是全部。是他記得的。阿強說過的。論壇上看到的。
他開始注意到一個 pattern。
被叫做無限測試的 case——「做完再做、結果一樣、但要你繼續做」——那些 case,涉及的產品,有一個共同點。
不是所有產品都被這樣對待。有些產品的測試流程正常得多——有問題就查,查到就修,修完繼續。和阿祥說的其他品牌廠的做法一樣。
但有一類產品——用新架構的產品——的測試流程不同。那種「做完再做」的 pattern,集中在這類產品上面。
林昭明看著這個 pattern。
他不確定。他手上的數據不夠。他沒有辦法 access 靈韻合成的內部紀錄。他只有阿強的碎片、論壇的碎片、自己的記憶碎片。
但碎片放在一起,有一個形狀。
如果 firmware 的 base code 從來不打算好好 support 新架構—— 如果這個 decision 背後有歷史原因—— 如果這個歷史原因不能被承認——
那麼無限測試的功能就不是「找問題」。
是製造紀錄。供應商那邊全部 pass。所以問題不在供應商那邊。所以問題在哪裡?沒有人知道。或者有人知道。但紀錄上面寫著:我們查過。我們做過。我們盡責了。
是消耗資源。供應商的人忙到沒命做測試、寫報告、開會、再測試。沒有時間退一步問:「等等,這個問題是不是其實在 firmware 那邊?」因為他們忙。因為下一份報告的 deadline 在等。
是建立 narrative。做得夠多次之後,連供應商自己都開始懷疑——是不是真的是我們的問題?阿強做了十五年都說不出哪裡不對。因為他做了那麼多測試,做到他自己都不確定了。
林昭明看著自己寫的東西。
他在最底加了一行:
「不是人有問題。是這個 system 從出生那天開始就是這樣設計的。人只是走著 system 叫他走的路。」
他停了。
然後加了兩個字:
「包括我。」
阿強握著那枝筆。
又一份報告。又一頁。結論欄。
「測試結果符合規格要求,未發現異常。建議維持現行方案並持續監測。」
他的筆停了一秒。
不是不簽。不是猶豫。是一種⋯⋯他以前沒有過的感覺。好像他的手記得一些他的腦還沒整理好的東西。
那封 email。「可以用來支持我們的結論。」
那六十幾個 firmware update。很認真,但核心邏輯從來沒有變。
那些不同的人用同一種語氣警告他「不要問」的時候。
他的名字在幾百份報告上面。每一份都是真實的。他做了測試。結果是這樣。他沒有造假。沒有一份是假的。
但這些報告在靈韻合成的系統裡扮演著什麼角色——這個他不知道。他只知道:他的簽名進了系統之後,去了哪裡、被怎麼用、出現在什麼文件裡、支撐著什麼結論——這些他碰不到。
他以前覺得這是正常的。品牌廠的 internal 東西,供應商本來就不需要知道。這是行規。
但如果——
如果他的簽名不只是「我做了測試」?如果他的簽名是「供應商確認沒有問題」?如果「供應商確認沒有問題」這句話在靈韻合成的系統裡,被用來支撐另一個結論——「所以問題不在 firmware」?
如果他的簽名是一份保險單的一部分?
阿強看著那枝筆。
他不知道。他真的不知道。可能只是他想太多了。可能他的報告就是他的報告,沒有人拿去做其他事。可能靈韻合成的 firmware 不改 base code,真的是因為 legacy 太深,改不了。可能一切都有合理的解釋。
可能。
但他做了十五年。六間品牌廠。他知道——當所有人用同一種語氣警告你「不要問」的時候,通常不是因為答案不重要。
是因為答案太重要了。
他簽名。日期。放去右手邊那疊。
但這次,他的手記住了那一秒的停頓。
林昭明合上電腦。
書房很安靜。窗外沒有風。
他現在知道的東西比一個月前多很多。但「知道」這件事本身,他不知道有沒有用。
他知道 firmware 表面狂改但核心不變。他知道有歷史。他知道有 pattern。他知道阿強感覺到的東西和他感覺到的東西是同一件事的兩面。
但他沒有 proof。
他沒有靈韻合成的 internal 文件。沒有 firmware 的 source code。沒有商業協議的紀錄。沒有任何人的書面確認。他有的只是:碎片。阿強的幾句話。論壇上的殘留帖子。一件十幾年前的和解案。和一份六十幾個 update、但核心邏輯從來沒有變過的 changelog。
碎片放在一起,有一個形狀。但形狀不是 proof。
而且——他想起阿強說的——這些 workaround 的數量和細節,是不能寫在明面的。品牌廠的黑盒裡面的東西,他碰不到。ODM 的 internal 紀錄,他更碰不到。
還有一層。
公司轉型了。系統換了。舊的 database 退役了。舊的紀錄 format 不 compatible 了。你想翻查?查不到。不是因為有人攔你。是因為「系統已經升級了」。
三層封鎖。
第一層:給你看的東西,已經過濾過了。你以為你碰到了核心,其實你碰到的是他們劃給你的邊界。
第二層:過濾背後還有東西。真正的 decision、真正的安排——從來沒有出過某幾個人的範圍。
第三層:轉型讓 raw data 斷裂了。就算你有一天有權限去查,你也查不到。因為那些 data 已經不存在於任何你可以 access 的地方。不是被刪。是被「淘汰」。
林昭明看著自己的筆記。
他寫的東西,在這個世界上,證明不了任何事。
他知道。
但他還是在寫。
因為阿強的手停了一秒。老周退休走了。那個匿名的人沒有再上線。阿祥還在做,覺得行業就是這樣。他的三個朋友裡面,前兩個覺得他的問題很奇怪,第三個知道但不想說。
這些人——每一個——都摸到了這頭大象的一部分。但沒有一個人看到整頭。因為這個 system 的設計就是讓每個人只看到自己那一塊,然後以為那一塊就是全部。
林昭明不確定自己有沒有看到整頭。可能他看到的只是比其他人多一塊。可能他的拼圖還有很多塊缺了。可能他拼錯了。
但他知道一件事。
那頭大象存在。
不是他想像出來的。
我坐在書房。桌面的東西攤開了很久。
阿強的話。老周的比喻。論壇的帖子。一件十幾年前的和解案。六十幾個 firmware update。一個問號。
我以為靈韻合成的問題是管理。是文化。是某幾個人的做事方式。我以為如果換一批人,事情會不一樣。
但如果不是人的問題 呢?
如果整個 firmware——整個系統——從第一天開始就是為了某一種特定的安排而設計的?如果那個設計的 DNA 裡面,已經寫死了規則?如果這個 DNA 在 code 裡面,在流程裡面,在每一個工程師的習慣裡面,深到你換多少人都換不走?
那麼阿強的測試就不只是「管理問題」。
他的名字在幾百份報告上面。他的簽名是真實的。每一次他簽名,他以為自己在確認「我做了測試,結果是這樣」。
但在那個 system 裡面,他的簽名的意思可能是另一件事。
可能。我不確定。我沒有 proof。
但那個 pattern——無限測試集中在某一類產品、firmware 表面狂改但核心不變、workaround 不斷疊加、所有人用同一種語氣警告你不要問——這個 pattern 不是隨機的。
隨機不會這麼整齊。
我不知道這幅圖有多大。我不知道地板下面還有多少層。每次我以為到了底,就發現下面還有。
但有一件事我現在知道了:
當所有人都說「這個不是你要管的事」——
那件事,通常就是最需要管的事。