Yiwei Lin
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
      • Create new note
      • Create a note from template
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Write
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Save as template
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: I/O, System Software --- # UFS(1): 基礎篇 ## Overview [UFS(Universal Flash Storage)](https://en.wikipedia.org/wiki/Universal_Flash_Storage) 是由 [JEDEC](https://zh.wikipedia.org/wiki/JEDEC) 制定,設計用於數位相機、智慧型手機等消費電子產品使用的快閃記憶體(flash)儲存規範。近期,在車用上 UFS 的使用也獲得關注。它的設計目標是發展一套統一的 flash 存取介面,在提供高數據傳輸速度和穩定性的同時,也可以減少消費者對於市面上各種記憶卡格式的混淆和不同記憶卡轉接器的使用。 ![image](https://hackmd.io/_uploads/S1OelPmubg.png =300x) UFS 被視為 [eMMC](https://zh.wikipedia.org/wiki/%E5%A4%9A%E5%AA%92%E9%AB%94%E8%A8%98%E6%86%B6%E5%8D%A1) 和 SD 卡的取代品。相較於 EMMC 採 parallel 傳輸技術,UFS 使用頻寬可更高的 serial 傳輸。架構上,host 與 device 間的交互會由 UFS host controller 來管理。對 host,JEDEC 定義了 UFS host controller interface 作為軟體的統一存取介面;對 device 的存取則透過 UIC,後者包含物理層介面上的 MIPI [MPHY](https://en.wikipedia.org/wiki/M-PHY),搭配 data link layer 上的 MIPI [UniPro](https://en.wikipedia.org/wiki/UniPro)。 下圖展示了在系統軟體架構中,UFS 設計的概觀。 ![image](https://hackmd.io/_uploads/rJTPvv7dZl.png) JEDEC 標準中的架構圖展示了設計的進階細節。 ![image](https://hackmd.io/_uploads/rk7oTg73a.png) > [JEDEC Publishes JESD220-2 Universal Flash Storage Card Extension Standard](https://www.storagenewsletter.com/2016/04/07/jedec-publishes-jesd220-2-universal-flash-storage-card-extension-standard/) ![image](https://hackmd.io/_uploads/SyL3w2NY0.png) > [White Paer: Introduction to the Universal Flash Storage Assocation](https://ufsa.org/wp-content/uploads/2011/06/1306_UFSA_White_Paper.pdf) 截至撰文的目前為止,UFS 開發至 4.0 版本,最高可提供 5800 MB/s 的頻寬。 ![image](https://hackmd.io/_uploads/rysObvmubl.png) ## UFS Application Layer 在 UFS 的應用層,host 的溝通是基於 [SCSI Architecture Model(SAM)](https://en.wikipedia.org/wiki/SCSI_architectural_model) 定義的 [SCSI](https://en.wikipedia.org/wiki/SCSI) 命令介面,命令透過 Command Descriptor Block(CBD) 結構形式組成。 每個 CDB 會是 6, 10 或 16 個 bytes 大小,並遵循 *I_T_L_Q nexus transaction*。這表示 CDB 需要識別與 **T**arget 中特定 **L**UN 通訊的 **I**nitiator,並執行特定的 **Q**uery。 ### Logical Unit(LUN) > [蛋蛋读UFS之五:逻辑单元(LU)](http://www.ssdfans.com/?p=92728) 在 SCSI 中導入了 Logical Unit(LUN) 的概念。一個儲存裝置(例如 UFS)可以被切分成數個 LUN,每個 LUN 有獨立的定址空間、大小、讀寫屬性、command queue、Memory Types 等等。 對於一個 UFS,最多可以有 32 個普通的 LUN,還可以有四個特別的 "Well known LUN": - Report LUNS: 針對 SCSI 的 Report LUNs 命令,紀錄整個 UFS 中的 LUN 數量與設定的資訊 - UFS Device LUNS: 針對 SCSI 的 INQUIRY 命令,與不針對特定的普通 LUN 功能相關,例如格式化(FORMAT UNIT)、電源管理相關(START STOP UNIT) - Boot LUNs: 與 UFS 的啟動相關,最多可以有兩個(LUN A and LUN B) - RPMB(Replay Protected Memory Block): 與安全存取相關 對於 UFS 的初始化,SCSI Driver 會先透過 Report LUNs (A0h) 命令獲得 LUN 的清單,然後就可以藉由確認每個 LUN 的容量,建立對應的 block device(`/dev/sdx`)。 ![image](https://hackmd.io/_uploads/SJbRg4PFWx.png) ## UFS Interconnect Layer(UIC) UFS 中以 [MIPI-MPHY](https://en.wikipedia.org/wiki/M-PHY)) 定義物理層(physical layer)的實作,以 [MIPI Unipro](https://en.wikipedia.org/wiki/UniPro) 定義資料連結層(data link layer) 的實作。 下圖則展示了 UFS 中的訊號定義,包含了硬體重製(RST_N)、reference clock(REF_CLK)、即數據接收與發送的 differential pair(DIN 和 DOUT)。 ![image](https://hackmd.io/_uploads/r1xgcr-k5-l.png) 而 UFS High-Speed (HS) Gear 則定義了在 MIPI M-PHY physical 層的最高 datarates,截至本文最高可達 [HS-Gear 6](https://www.mipi.org/knowledge-library/webinars/evolution-of-ufs-leveraging-m-phy-and-unipro-for-next-generation-performance-power-efficiency-and-reliability),支援每個 lane 最高 46.6 Gbps 的速度。此外,UFS 可支援最多 2 個 lanes。 | HS-Gear | Speed | |:--------- |:--------- | | HS-Gear 1 | 1.5 Gbps | | HS-Gear 2 | 2.9 Gbp | | HS-Gear 3 | 5.8 Gbps | | HS-Gear 4 | 11.6 Gbps | | HS-Gear 5 | 23.3 Gbps | | HS-Gear6 | 46.6 Gbps | ## UFS Transport Layer 在 UFS 的傳輸層(transport layer) 中傳遞的封包稱為 **UPIU(UFS Protocol Information Units)**。UFS 的傳輸是採用 client-server 的模型,由 UFS host 作為 Client/Initiator 發送命令給 UFS device 的 Server/Target。後者在完成請求後再返回 repsonse。 一個 UFS 請求的進行可以分成三個階段: * Command: Host 發起請求 * Data: 傳輸與 Command 相關的數據,不需要額外數據的命令可以略過此階段 * Response: Device 完成請求後,返回執行結果的資訊 * 與 PCIe 不同,UFS 的命令都必須返回結果 這三個階段分別可以對應到三種 UPIU: - Command UPIU - Data UPIU - Response UPIU 每種 UPIU 又可以依據應用區分成不同的類型,詳細可以對照 - [蛋蛋读UFS之三:UFS数据包UPIU](http://www.ssdfans.com/?p=92598) 的說明。 ## Power Management ### Device Power Modes UFS 裝置支援多種電源模式,這些模式由 START STOP UNIT(SSU) command 和一些 attribute 控制。Device power mode 獨立於 bus 上下游的 link 狀態。 在 UFS 標準中為裝置定義了數種電源模式。其中包含四種基本功耗模式。一種是裝置正在工作,一種是等待下一條指令,一種是已進入睡眠狀態並能在 host 需要時喚醒,還有一種是完全關閉電源的模式。此外,還需要三種過渡模式作為上述四種模式切換的中間狀態。 四種基本狀態分別是: * Active: 裝置正在回應命令或在背景運作,又可以分成 16 個等級(ActiveCCLevel) * Idle: 裝置未執行任何操作 * Sleep: 可顯著降低裝置的耗電量。在此狀態下,可以移除對 UFS 的供電(VCC)。此模式下任何 LUN 都不能被存取,也不能對 UFS 下 SSU 以外任何命令 * PowerDown: 此模式可以提供最大的省電量。在此狀態下可以移除所有供電。揮發性資料可能遺失 對應到 Linux 中的定義: ```cpp /* UFS device power modes */ enum ufs_dev_pwr_mode { UFS_ACTIVE_PWR_MODE = 1, UFS_SLEEP_PWR_MODE = 2, UFS_POWERDOWN_PWR_MODE = 3, UFS_DEEPSLEEP_PWR_MODE = 4, }; ``` :::warning 註: 留意到省電等級與數字順序上的差異 ::: 三種過度模式為: * Pre-Active * Pre-Sleep * Pre-PowerDown 狀態的轉換則如下圖所示: ![image](https://hackmd.io/_uploads/HywkemQ3T.png) > [Power Reduction and Low Risk Implementation of UFS v2.0 Design](https://www.jedec.org/sites/default/files/files/Hezi_Saar_MF_updated_9-22.pdf) 軟體要驅動電源模式的切換是透過 SSU(Start Stop Unit) command,在 Linux 中對應到 `ufshcd_set_dev_pwr_mode()`。command 格式如下: ![image](https://hackmd.io/_uploads/H1S9AXm2p.png) > [ufs2.2 协议扫盲(七)](https://blog.csdn.net/haoyun1990/article/details/121890051) 特別值得注意的欄位有: * OPCODE: 0x1B 為 SSU * IMMED: 設為 0 的話,response 會在切換完成後才回傳,設為 1 則進入過渡期就會回傳 * POWER CONDITION(PC): 與 mode 轉換相關,留意到數值內容關聯至當前的 device power mode Host 可以透過讀取 bCurrentPowerMode 屬性來檢索目前電源模式,以知道要切換到目標模式下 PC 的設定值。為此,bCurrentPowerMode 是裝置在任何電源模式下唯一都需要傳回的屬性。相對的,如果裝置未處於 active 或 idle 模式,則透過 QUERY REQUEST UPIU 存取 bCurrentPowerMode 以外的 descriptors、flags、attributes 的可能會失敗。 :::info 要取得 bCurrentPowerMode,在 Linux 下可以透過 sysfs 節點: ``` $ cat /sys/bus/platform/devices/<ufshci>/attributes/current_power_mode ``` 或者是使用 [ufs-utils](https://github.com/westerndigitalcorporation/ufs-utils),注意此種方式需要加上額外的 `CONFIG_SCSI_UFS_BSG` 進行編譯。 ``` $ ufs-utils attr -t 2 -p /dev/bsg/ufs-bsg0 ``` ::: ### UIC Link State UFS 中的 host 和裝置透過間以 M-PHY 連接,而 M-PHY 支援不同的模式和狀態,以達理想的傳輸速度或電源管理。如下圖,藍色方框中是低速模式(LS-MODE)的運作和省電狀態,紅色方框中則是高速模式(HS-MODE)的運作和省電狀態。 ![image](https://hackmd.io/_uploads/B1FpZ9K3T.png) ![image](https://hackmd.io/_uploads/ryQwf9Y2p.png) > [M-PHY Benefits and Challenges](https://mixel.com/m-phy-benefits-challenges/) 當沒有數據傳輸時,M-PHY 會自動切換到 STALL 或 SLEEP 狀態下。而 Host 可以通過 UFSHCI 的 UIC Command 暫存器(0x90) 透過 DME 來介入 UIC 層的行為,主動讓 M-PHY 狀態進入更為省電的 HIBERN8,即 `DME_HIBERNATE_ENTER`。 對應到 Linux 有以下幾種定義,其中 `UIC_LINK_ACTIVE_STATE` 包含了 LS/HS/Sleep,畢竟這些狀態之間的轉換是由硬體進行,從軟體的角度來看可視為一致。 ```cpp /* Host <-> Device UniPro Link state */ enum uic_link_state { UIC_LINK_OFF_STATE = 0, /* Link powered down or disabled */ UIC_LINK_ACTIVE_STATE = 1, /* Link is in Fast/Slow/Sleep state */ UIC_LINK_HIBERN8_STATE = 2, /* Link is in Hibernate state */ UIC_LINK_BROKEN_STATE = 3, /* Link is in broken state */ }; ``` :::warning 主要是設定為前三種其一 ::: ### UFS PM Level 在 Linux 中,裝置進入 suspend/runtime suspend 時的 Device Power Modes 和 UIC Link State 組合是直接綁定的。 ```cpp const struct ufs_pm_lvl_states ufs_pm_lvl_states[] = { [UFS_PM_LVL_0] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE}, [UFS_PM_LVL_1] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE}, [UFS_PM_LVL_2] = {UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE}, [UFS_PM_LVL_3] = {UFS_SLEEP_PWR_MODE, UIC_LINK_HIBERN8_STATE}, [UFS_PM_LVL_4] = {UFS_POWERDOWN_PWR_MODE, UIC_LINK_HIBERN8_STATE}, [UFS_PM_LVL_5] = {UFS_POWERDOWN_PWR_MODE, UIC_LINK_OFF_STATE}, [UFS_PM_LVL_6] = {UFS_DEEPSLEEP_PWR_MODE, UIC_LINK_OFF_STATE}, }; ``` 在 host controller driver 初始化階段設置好 `hba->spm_lvl` 和 `hba->rpm_lvl` 後,UFS core 將會在 suspend/runtime suspend 階段依此設定將裝置調整到對應的狀態。 ### Auto-Hibernation 查看 Capabilities registers 中的 Controller capabilities 可以知道 host controller 是否支援 auto hibernation。在支援該功能的 host controller 加上額外設定 Auto-Hibernate Idle Timer register(AHIT) 可允許 link 在設置的 idle 時間後,硬體自動發送 `DME_HIBERNATE_ENTER` 來進入 HIBERN8。 ## UFSHCI UFS Host controller interface (UFSHCI)是 Host 控制 UFS 裝置的介面,具體是透過使用相關暫存器和 request descriptors 來使 host contorller 對裝置完成請求。 UFSHCI 定義了兩種 interface space: * MMIO space: 在這個空間含有系統軟體可存取的一組硬體暫存器,映射到 host 的記憶體空間中 * Host memory space: 此空間包括提供執行命令的 descriptor 以及每個命令部分的資料的 buffer ## Reference - [What is Universal Flash Storage (UFS)](https://www.synopsys.com/glossary/what-is-universal-flash-storage.html) - [Overview of Universal Flash Storage Subsystem - Mohammad Faiz Abbas Rizvi, Texas Instruments India](https://www.youtube.com/watch?v=ZxWnRcyS2FU) - [Introduction to UFS Subsystem](https://elinux.org/images/6/64/Introduction_to_UFS.pdf) - [UFS 学习笔记(概念入门篇)](https://zhuanlan.zhihu.com/p/663057180) - [UFS Hibernate 介紹 - 協議](https://blog.csdn.net/guozhidixian/article/details/124361506) - [UFS Hibernate 介紹 - 代碼](https://blog.csdn.net/guozhidixian/article/details/124648915) - [蛋蛋读UFS之三:UFS数据包UPIU](http://www.ssdfans.com/?p=92598) - [蛋蛋读UFS之十:UFS电源管理](http://www.ssdfans.com/?p=92792)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully