以下是發送一個NVMe admin/Io command 的流程。相關driver source code 可參考NVMe official website
1. Host Adds a command in the submission queue's tail entry
2. Host rings the submission queue's Tail Doorbell
3. Device fetch the command
4. Device process the command (done)
5. Device adds the completion result in the completion queue's tail entry (Completion result has its relevant command id)
6. Device send a Interrupt(Probably MSI-X)
7. Host reads the completion queue
7.1 Host has received the completion command
8. Host rings the completion queue's Head Doorbell
bloggerads
2017年4月16日 星期日
NVMe : Queue Size / Queue entry Size
Queue 相關 size 的 configuration
- Admin Queue
- Completion Queue 和 Submission Queue 各只有一組
- Initial 時需設定Queue Size, 即AQA.ACQS, AQA.ASQS, controller 應support 2~4096個entry
- I/O Queue
- Initial 時需設定每個entry的Size, 即 CC.IOSQES = 6 (64 Byte), CC.IOCQES = 4 (16 Byte), 這是NVM command的size。
- 透過 CAP.MQES (Maximum Queue Entries Supported)得到 I/O Submission/Completion Queue support 的最大entry數量(最少兩個entry)。 在使用Admin Command Create I/O Queue時不要超過他
- 透過 Set Feature (Feature Id 07h) 設定host driver所需的Submission/Completion Queues數量 (最大64K個), 從completion queue 回來的資料可以得到Controller 所能allocate 的Submission/Completion Queue數量
2017年4月8日 星期六
利用C語言的正規表達功能來Parsing 傳入程式中的引數
這篇介紹 C 的 sscanf 函數來做到類似 C++11 正規表達的效果,並以 Parsing 傳入程式中的引數做範例
----------------------Output---------------------------
> g++ -o c c.cpp
> c -name:John -age:20
age : 20
name : John
// c.cpp int main(int argc, char* argv[]) { char s0[30], s1[30]; int ret; for (int i=argc-1; i>0; i--) { s0[0] = s1[0] = 0; //sscanf(argv[i], "%*[^:]:%s", s0); //[^:]代表在':'處設斷點但不包含':', '*'代表忽略'%'起始的字串 sscanf(argv[i], "-%29[^:]:%29s", s0, s1); if (s0[0] == 0 || s1[0] == 0) puts("Wrong type!"); else printf("%s : %s\n", s0, s1); } return 0; }
----------------------Output---------------------------
> g++ -o c c.cpp
> c -name:John -age:20
age : 20
name : John
2017年2月5日 星期日
DOS : Legacy Graphic Output Control
在Dos下想輸出文字到螢幕上,除了呼叫C/C++提供的函數 printf, cout 或 Bios提供的軟體中斷 int 10, 是否有直接控制硬體的方法呢? 答案是有的,可以直接把要顯示的資料搬到A/B Segment。用以下的code來做範例 (Compile using Watcom)
在螢幕座標(y,x) = (1, 0) 秀出 Hi Martin.
ps. 如果想畫一個點陣圖請參考 mode 13h, 解析度為320*200, 256色, 透過寫入A000:0來完成
題外話, 我用了以上的技巧寫了一個Dos版的source code Editor, 名稱叫E editor (下圖)。 平常工作時都會開個Dos模擬器跑Dos tool,享受Dos單純的美。
Key:
F1: Copy Line
F2: Paste Line
F3: Delete Line
F10: Save File
下載: (password: martinlee)
E Editor
typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; enum Colour{ BLACK=0, BLUE, GREEN, CYAN, RED, MAGNETA, BROWN, LGRAY, \ DGRAY=8, LBLUE, LGREEN, LCYAN, LRED, LMAGNETA, YELLOW, WHITE}; #define COLOUR(forecolour, backcolour) ((backcolour) << 4 | (forecolour) & 0x0F) void WriteString(int y, int x, BYTE colour, char *string) { volatile WORD *pvram; for (DWORD i=0;string[i]!=0; x++, i++) { pvram = (volatile WORD *)0xB8000 + y * 80 + x; *pvram = (BYTE)string[i] | colour << 8; } } void WriteCharacter(int y, int x, BYTE colour, BYTE ch) { volatile WORD * pvram; pvram = (volatile WORD *)0xB8000 + (y * 80 + x) ; *pvram = ch | (colour << 8); } int main() { WriteCharacter(1,0, COLOUR(RED, BLACK), 'H'); WriteCharacter(1,1, COLOUR(RED, BLACK), 'i'); WriteString(1, 3, COLOUR(GREEN, BLACK), "Martin."); }
在螢幕座標(y,x) = (1, 0) 秀出 Hi Martin.
ps. 如果想畫一個點陣圖請參考 mode 13h, 解析度為320*200, 256色, 透過寫入A000:0來完成
題外話, 我用了以上的技巧寫了一個Dos版的source code Editor, 名稱叫E editor (下圖)。 平常工作時都會開個Dos模擬器跑Dos tool,享受Dos單純的美。
F1: Copy Line
F2: Paste Line
F3: Delete Line
F10: Save File
下載: (password: martinlee)
E Editor
2017年1月13日 星期五
DOS : Increase Dosbox screen size in Windows
Step 1. Find dosbox-0.74.conf
Step 2. Modify the SDL part in the dosbox-0.74.conf
[SDL]
fullscreen=false
fulldouble=false
fullresolution=original
windowresolution=1024x768
output=ddraw
autolock=true
sensitivity=100
waitonerror=true
priority=higher,normal
mapperfile=mapper.txt
usescancodes=true
ps. Some Dos application may consume lot of CPU usage. Fix it by Setting a fixed CPU cycles, for example, 16000.
[CPU]
cycles=auto
cycles=16000
Step 2. Modify the SDL part in the dosbox-0.74.conf
[SDL]
fullscreen=false
fulldouble=false
fullresolution=original
windowresolution=1024x768
output=ddraw
autolock=true
sensitivity=100
waitonerror=true
priority=higher,normal
mapperfile=mapper.txt
usescancodes=true
ps. Some Dos application may consume lot of CPU usage. Fix it by Setting a fixed CPU cycles, for example, 16000.
[CPU]
cycles=16000
2016年12月2日 星期五
gcc : Built-in functions for atomic memory access
這一篇是研究Memory barrier的心得。研究的原因是因為在UEFI環境下使用multi-processor protocol 來驗證CPU design,過程用到了相關的gcc Atomic函式。Atomic 提供同步機制,使得在Multi-Processor/Multi-Thread的系統下操作同一塊memory, 各個Core的Cache都能確保和Memory同步。
這邊只是以軟體thread寫個應用程式作範例來解釋Memory barrier, 如果不使用Built-in functions for atomic memory access而將__sync_fetch_and_add(&count,1);改成count++, 則count結果會不正確。
#include <stdio.h> #include <pthread.h> #include <stdlib.h> static int count = 0; void *MyTest(void *arg) { for (int i=0; i<20000; ++i) __sync_fetch_and_add(&count, 1); return NULL; } int main(int argc, const char *argv[]) { pthread_t Thread_Id[10]; int i; for (i=0;i<10;++i) pthread_create(&Thread_Id[i], NULL, MyTest, NULL); // Wait until all threads have finished. for (i=0;i<10;++i) pthread_join(Thread_Id[i], NULL); printf("%d\n",count); return 0; }
另外,__sync_synchronize (): This built-in function issues a full memory barrier.呼叫這個函式讓每個Core上的cache和memory同步。
<note> UEFI kernel提供EFI_MP_SERVICES_PROTOCOL,透過這個protocol,可以指定呼叫某個/或多個CORE (AP)分別執行特定的function,達到Multi-processing的效果。
-------------------------------------------------------------------------------------------------------------------------
<note> UEFI kernel提供EFI_MP_SERVICES_PROTOCOL,透過這個protocol,可以指定呼叫某個/或多個CORE (AP)分別執行特定的function,達到Multi-processing的效果。
-------------------------------------------------------------------------------------------------------------------------
Ps. 在windows下測試,需要自行加入pthread這個library。
如果你用Dev-C++ 5.11, 在Project->Parameters->Add library or object 加入
如果你用Dev-C++ 5.11, 在Project->Parameters->Add library or object 加入
"../../Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib/libpthread.a"
順便解釋一下我認知的procces/thread:
process: 在系統中被註冊要執行的程式,其擁有CPU的使用權和獨立的位址空間。
thread: 系統處理工作的基本單位,一個CPU核心在同一時間只能提供一個thread來執行process
Multi-Thread: 將多個thread同時assign給一個process
Multi-Process: 每個process都分到thread來處理
thread: 系統處理工作的基本單位,一個CPU核心在同一時間只能提供一個thread來執行process
Multi-Thread: 將多個thread同時assign給一個process
Multi-Process: 每個process都分到thread來處理
2016年12月1日 星期四
UEFI : 在Linux(Ubuntu)下build UEFI Bios module
為什麼要在Linux(Ubuntu)底下build Bios module呢?
因為接手了大陸同事的UEFI Shell code,而他使用了 gcc 的library "Atomic Memory Access",這個library在平常我們慣用的Visual Studio compiler下無法直接使用。
所以這兩天,花了點時間研究一下如何在Ubuntu下建構可以編譯的環境。
由於網路上比較少有這樣的文章分享, 因此特地新增一篇網誌做說明以及紀錄
基本上我是參考以下這兩篇Using EDK II with Native GCC、UDK2014 How to Build
,這邊解釋一下必要的流程
#取得EDK2 code base 請參考 https://github.com/tianocore/edk2
#安裝所需要的編譯工具
bash$: sudo apt-get install build-essential subversion uuid-dev iasl
#取得nasm組譯器
bash$: sudo apt-get install nasm
因為接手了大陸同事的UEFI Shell code,而他使用了 gcc 的library "Atomic Memory Access",這個library在平常我們慣用的Visual Studio compiler下無法直接使用。
所以這兩天,花了點時間研究一下如何在Ubuntu下建構可以編譯的環境。
由於網路上比較少有這樣的文章分享, 因此特地新增一篇網誌做說明以及紀錄
基本上我是參考以下這兩篇Using EDK II with Native GCC、UDK2014 How to Build
,這邊解釋一下必要的流程
#取得EDK2 code base 請參考 https://github.com/tianocore/edk2
#安裝所需要的編譯工具
bash$: sudo apt-get install build-essential subversion uuid-dev iasl
#取得nasm組譯器
bash$: sudo apt-get install nasm
訂閱:
文章 (Atom)
