分享到plurk 分享到twitter 分享到facebook

版本 fe037fdcc97810eae020d9a5aacb207132a72b00

embedded/Lab42

Changes from fe037fdcc97810eae020d9a5aacb207132a72b00 to c214ce789bd6424153ff24316f26b36b99c35382

---
title: Lab42: Mini ARM OS
toc: no
...

預期目標
------------
- 研究一個具體而微的作業系統
- 專案整合與程式碼移植
- 學習 GNU Toolchain,驗證 [Week #6](/embedded/2015q1w6), [Week #7](/embedded/2015q1w7), [Week #8](/embedded/2015q1w8) 所學
- 實做 OS scheduler

Mini ARM OS
------------------
* 設定 qemu 的路徑,假設 ``qemu_stm32`` 目錄位於 ``$HOME/workspace`` 裡面

.. code-block:: prettyprint

```
    export PATH=~/workspace/qemu_stm32/arm-softmmu:$PATH

```
* 取得 [mini-arm-os](https://github.com/embedded2015/mini-arm-os) 程式碼

.. code-block:: prettyprint

```
    git clone https://github.com/embedded2015/mini-arm-os.git || git clone git@github.com:embedded2015/mini-arm-os.git

```
* 依據 [mini-arm-os](https://github.com/embedded2015/mini-arm-os) 指示

實驗和觀察
----------------
* 00-HelloWorld

![](/embedded/Lab42/00.png)

  - 輸入``arm-none-eabi-objdump -D hello.elf``後,會看到以下:

.. code-block:: prettyprint

```
    00000000 <isr_vectors>:
       0:        00000000         andeq        r0, r0, r0
       4:        000000ad         andeq        r0, r0, sp, lsr #1

```
  以及

.. code-block:: prettyprint

```
    000000ad <reset_handler>:
    ac:    b580          push    {r7, lr}
    ae:    af00          add    r7, sp, #0
    b0:    f7ff ffcc     bl    4c <main>

```
  - 發現 PC 會去抓 0x4 值 ``0x000000ad`` (LSB一定要1),所以會去執行 ``000000ad`` 也就是 reset_handler,之後才會去執行 ``main()``
  - ``reset_handler`` 定義在 startup.c 中:

.. code-block:: prettyprint

```c
    __attribute((section(".isr_vector")))

```
  會把以下部份

.. code-block:: prettyprint

```c
    uint32_t *isr_vectors[] = {
        0,
        (uint32_t *) reset_handler,    /* code entry point */
    };

```
  放入 ``.isr_vector`` 中,linker 會把 ``0`` 重新定位於 ``0x0``,``reset_handler`` 重新定位在 ``0x4``,如此一來,PC 一開始就會去執行 ``reset_handler()``

參考作業要求
-------------------
* 將 [Lab-39](/embedded/Lab39) 的 ARM semihosting 機制移植到 [mini-arm-os](https://github.com/embedded2015/mini-arm-os),這樣就能存取 host 端的資源,如檔案操作
  - 將排程的行為紀錄 (task switching: in/out, timestamp) 於 ``log`` 檔案中

* 原本 mini-arm-os 使用 round robin 輪流執行每個 task,改為支援以下:
  - priority-based scheduling
  - message queue

* 可參考 [rtenv+](/embedded/rtenv) 的程式碼,以便理解前述所需要的實做

挑戰題
----------
* 將 [Lab-40](/embedded/Lab40) 的視覺化工具移植到 [mini-arm-os](https://github.com/embedded2015/mini-arm-os)
* 將 [Lab-39](/embedded/Lab39) 的 romfs 移植到 mini-arm-os
  -  linker script 和工具程式需要作一定程度的修改

繳交作業
------------
- 截止日期:
   * Apr 25, 2015 (含) 之前

- 更新開發過程到共筆網站: [Lab 42 / 作業共筆](https://embedded2015.hackpad.com/2015q3-Week-7-Lab42#2015q3-Week-7-Lab42),需要標注自己的 ID
    * 將符合作業提案的程式碼,提交到自行 fork 的 repository: https://github.com/embedded2015/mini-arm-os
    * 注意: 要記得 fork [mini-arm-os](https://github.com/embedded2015/mini-arm-os)
    * 注意: 請直接修改 ``06-Preemptive`` 目錄裡面的檔案,不要建立重複內容的新目錄

參考資料
-------------
* [Lab11: Build RTOS for ARM](/embedded/Lab11)
  - Lucas Wei 的[程式碼實做](/embedded/Sol11)

* [rtenv+](/embedded/rtenv)
  - 在 rtenv+ 中提供四種檔案類型,分別為 fifo pipe (``S_IFIFO``), message queue (``S_IMSGQ``), register file (``S_IFREG``), block file (``S_IFBLK``)
  - 每一種檔案類型都擁有自己的資料結構以及處理函式,其中處理函式針對 ``read``, ``write``, ``lseek`` 這三個 system call,都有提供一個檢查函式 (e.g. ``fifo_writable``) 以及一個或多個運作函式 (e.g. ``fifo_write``)