第十二章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 不是隨機的。
隨機不會這麼整齊。
我不知道這幅圖有多大。我不知道地板下面還有多少層。每次我以為到了底,就發現下面還有。
但有一件事我現在知道了:
當所有人都說「這個不是你要管的事」——
那件事,通常就是最需要管的事。