---
# System prepended metadata

title: EDID 入門篇

---

# EDID 介紹 

EDID全名為Extended Display Identification Data，是由VESA協會制定的顯示器標準資訊格式。具體來說，可以把 EDID 當成一個顯示器的 metadata / 身分證，其內容會包含顯示器的相關資訊，如顯示器名稱、產品序號、支援解析度、聲音格式等等。目的為告訴輸出端顯示器支援的能力，確保電腦或是機上盒等影音輸出裝置，在連接上顯示器後，能根據資訊輸出正確的影音格式，因此可以避免無法顯示或顯示比例不正常等狀況發生。

目前此項技術已廣泛應用於影音顯示介面如 DisplayPort、HDMI。在實作上，為了要容納先前提到的EDID資訊於顯示器中，儲存在 EEPROM 中，並且在HDMI介面會利用I2C的介面來進行雙向的資料傳輸。

EDID 透過 I2C 與 source 進行傳輸
![image](https://hackmd.io/_uploads/Bk9xGxZ0kx.png)


![image](https://hackmd.io/_uploads/SkxVEx-AJl.png)

目前 HDMI 介面使用 EDID v1.3，DP 介面則使用 EDID v1.4


## EDID 資料結構(v1.3)
EDID 由 1 ~ 4 個 block 組成，每個 block 大小為 128 Byte。第一個 block 又稱為 EDID Base Block，由 VESA EDID 標準制定。隨著越來越多的顯示/聲音格式，需要更多的容量存放訊息，所以也發展成利用 Extension Block 格式在 EDID 內放置多個 Block，最多可放置 255個 Block。

EDID Base Block 又稱為 Block，每個 Byte 採用 16 進位資料格式。

TODO:
write the detail of the first block


## UEFI EDID related protocol

在 UEFI 環境下，常會需要透過 GOP 與其相關的 Protocol 進行顯示相關功能開發，而 UEFI 定義了相關的 protocol 來取得 EDID 資訊


### EdidDiscovered
```c!
typedef struct {
 UINT32                              SizeOfEdid;
 UINT8                               *Edid;
} EFI_EDID_DISCOVERED_PROTOCOL;
```

#### SizeofEdid:
Edid buffer 大小，最小值 128 byte。
若沒有 EDID 資訊，則設為 0。

#### Edid
指向唯讀位元陣列的指標，該位元陣列為顯示器(video output device) EDID 資訊。

#### 說明

該 Protocol 包含從顯示器回傳的 EDID 資訊，若該顯示器沒有任何 EDID 資訊，則 SizeofEdid = 0 且 \*Edid = NULL;

當 GOPDriverBinding -> Start() 被呼叫時，該 Protocol 會被 installed 在每個實體連接的 display device 的 child handle 上

Ex: 當一個 HDMI display device 連接到 video controller 時，HDMI ddevice 會被 installed 成一個 child handle，並同時 install EdidDiscovered.

若連接著 video output device 並非 EDID capable(非常老的類比 CRT 螢幕)，或是 EDID 資訊無法取得，則該 protocol 會以 SizeofEdid = 0 且 \*Edid = NULL 的方式被安裝。

### EdidOverride
```c!
typedef struct _EFI_EDID_OVERRIDE_PROTOCOL {
 EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID      GetEdid;
  } EFI_EDID_OVERRIDE_PROTOCOL;

```
#### GetEdid
回傳 EDID value & attribute


#### 說明
由 platform firmware 產生，該 protocol 允許系統提供另一個 EDID 資訊給 GOP。

#### EFI_EDID_OVERRIDE_PROTOCOL.GetEdid()
```c
typedef
EFI_STATUS
(EFIAPI \*EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) (
 IN   EFI_EDID_OVERRIDE_PROTOCOL                   *This,
 IN   EFI_HANDLE                                   *ChildHandle,
 OUT  UINT32                                       *Attributes,
 OUT UINTN                                         *EdidSize,
 OUT UINT8                                         **Edid
 );
```
#### 說明
Returns policy information and potentially a replacement EDID for the specified video output device.


This protocol is optionally provided by the platform to override or provide EDID information and/or output device display properties to the producer of the Graphics Output protocol. If ChildHandle does not represent a video output device, or there are no override for the video output device specified by ChildHandle, then EFI_UNSUPPORTED is returned. Otherwise, the Attributes, EdidSize, and Edid parameters are returned along with a status of EFI_SUCCESS.


### EdidActive
```c!
typedef struct {
 UINT32                             SizeOfEdid;
 UINT8                              *Edid;
} EFI_EDID_ACTIVE_PROTOCOL; 
```

#### 說明:

包含 **正在使用**的(Active)顯示器的 EDID 資訊，
該資訊由 EFI_EDID_OVERRIDE_PROTOCOL 或 EFI_EDID_DISCOVERED_PROTOCOL 提供。

若沒有 override，則 EDID 資訊和 EFI_EDID_DISCOVERED_PROTOCOL 相同

When the set of active video output devices attached to a frame buffer are selected, the EFI_EDID_ACTIVE_PROTOCOL must be installed onto the handles that represent the each of those active video output devices. If the EFI_EDID_OVERRIDE_PROTOCOL has override EDID information for an active video output device, then the EDID information specified by GetEdid() is used for the EFI_EDID_ACTIVE_PROTOCOL. Otherwise, the EDID information from the EFI_EDID_DISCOVERED_PROTOCOL is used for the EFI_EDID_ACTIVE_PROTOCOL. Since all EDID information is read-only, it is legal for the pointer associated with the EFI_EDID_ACTIVE_PROTOCOL to be the same as the pointer associated with the EFI_EDID_DISCOVERED_PROTOCOL when no overrides are present.


## UEFI Application 取得 EDID 資訊
下列程式為一個 UEFI application，透過 EdidDiscoveredProtocol 取得 EDID 資訊。

```c
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/EdidDiscovered.h>

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS Status;
  EFI_EDID_DISCOVERED_PROTOCOL *EdidDiscovered;

  // Locate the EDID Discovered Protocol.
  Status = gBS->LocateProtocol(&gEfiEdidDiscoveredProtocolGuid, NULL, (VOID **)&EdidDiscovered);
  if (EFI_ERROR(Status)) {
    Print(L"Failed to locate EDID Discovered Protocol: %r\n", Status);
    return Status;
  }

  // Check if EDID data is available.
  if (EdidDiscovered->Edid == NULL || EdidDiscovered->SizeOfEdid == 0) {
    Print(L"No EDID data available.\n");
    return EFI_NOT_FOUND;
  }

  // Print the EDID data in hexadecimal format.
  Print(L"EDID Data (%d bytes):\n", EdidDiscovered->SizeOfEdid);
  for (UINTN i = 0; i < EdidDiscovered->SizeOfEdid; i++) {
    Print(L"%02x ", EdidDiscovered->Edid[i]);
    if ((i + 1) % 16 == 0) {
      Print(L"\n");
    }
  }
  Print(L"\n");

  return EFI_SUCCESS;
}

```

## Reference
https://www.graniteriverlabs.com/zh-tw/technical-blog/edid-overview

https://silverwind1982.pixnet.net/blog/post/365351044

https://uefi.org/sites/default/files/resources/2_-_AMD_UEFI_Plugfest_EDID_Spring2012.pdf

https://glenwing.github.io/docs/VESA-EEDID-A1.pdf