+886 Let's roll.

2015年1月29日 星期四


1. 下載 minicom 2.7
https://alioth.debian.org/projects/minicom/

2.解開後
./configure (我的安裝時說automake需要安裝Xcode,就安裝先囉)
make
sudo make install

3. 上usb-to-serial cable網站我的chip是PL2303 ->
系統偏好設定>安全性與隱私>允許安裝

查詢我的設備是tty.usbserial

ls -1 /dev/tty.*
/dev/tty.usbserial 


4.執行minicom -s 設定>
Serial port setup -> A - Serial Device:/dev/tty.usbserial
-> F - Hardware Flow Control:NO
選: save setup as dfl  -> 發現錯誤 sudo mkdir /usr/local/etc -> sudo chmod 777 /usr/local/etc

nailed it!!!

2015年1月26日 星期一

Linux VLAN 筆記 

kernel 開啟802.1q功能後,便可以透過簡單指令,設定VLAN. 
brctl delif br0 ath0
brctl delif br0 eth0

vconfig add ath0 555
vconfig add eth0 555
ifconfig ath0.555 up
brctl addbr br555
brctl addif br555 ath0.555
brctl addif br555 eth0.555
ifconfig ath0.555 up
ifconfig eth0.555 up

ifconfig br555 10.0.0.11 up

Wireless AP mode運作正常,抓無線封包有看到帶了VLAN ID 555.
不幸的是,我的Wireless STA,不能成功ping到我的AP,只好下去看程式,這邊有幾個部份要看. 
1. Linux kernel 802.1q 
2.Wireless driver.(我手邊的是Atheros proprietary LSDK driver,所以這部份內容都不會放上來)
 3.hostapd跟wpa_supplicant.  
 
 Linux的net_dev是用一個list串起來,每個net_dev都有會呼叫ev_queue_xmit ->dev_hard_start_xmit ,去傳送封包至下一步。
 
 vlan.c::vlan_proto_init()時會invoke,dev_add_pack(&vlan_packet_type);
 
  •  static struct packet_type vlan_packet_type __read_mostly = {
  •         .type = cpu_to_be16(ETH_P_8021Q),
  •         .func = vlan_skb_recv, /* VLAN receive method */
  • };
vlan_packet_type()宣告了, type是8021q(0x8100)封包接收時是由它來使用vlan_skb_recv()處理。

 所有帶VLAN tag header的封包會經過vlan_dev.c::vlan_skb_recv()處理,去掉VLAN header,再處理接下來的header ex: ARP or IP。
 
 傳送時vlan_dev_hard_start_xmit()會invoke __vlan_put_tag()去加入VLAN header。
 
 整個流程是wifi_Dev_RX->vlan_skb_recv()->bridge->中間處理比方說ARP->送出ARP reply->dev_hard_start_xmit()->加入VLAN header後由實體網卡送出。
 
 
 參考資料:
 
 
 vconfig add ath0 555  will invoke ospriv_vlan_add_vid( ). 
 參考資料: 

2014年11月19日 星期三


寫了一個簡單的bare metal啟動MMU的程式,
把實際位址0x20000000~0x210000000 對應到虛擬位址0xa0000000~0xa1000000

ARM MMU的部份在ARMv6之前跟之後的版本不同,
請看Technical Reference Manual。

Raspberry Pi MMU initialization example.

hackpad note:https://lbd.hackpad.com/MMU-initialization-Jl8YoJ3iUdf
source code:https://github.com/tzuCarlos/RaspberryPi/tree/master/labMMU

2014年11月4日 星期二

     最近因為轉職的關係,時間很零碎,年過30體力ok,不過熬夜的能力大減! 入手了一個Raspberry Pi,原因是社群比較多,在台灣也比較好買到,Beagleboard-XM我在官方論壇上問問題,幾乎沒人回應了,大家都玩BeagleBone Black。

      持續的學習! 分享學習的筆記,我跟我同年紀的人,程度差太多了,努力跟上領先集團,
 因為我是阿宅,沒人要跟我一起開讀書會,人家用黃色小鴨Debug,我就用自由女神學習吧,概念就是,跟著自由女神解釋,自己寫了什麼,藉以review筆記。
     
試著使用hackpad,比較方便編輯跟備份。

 
    Raspberry Pi bare metal Hello World
    中文:https://lbd.hackpad.com/Raspberry-PiHello-world-qivrzCRU6mW
 English:https://lbd.hackpad.com/Hello-world-on-qemu-Raspberry-Pi-dUGFyJw9Hva
   

2014年9月6日 星期六


lab3,Happy Moon Festival!!!  We'll study how to initial stack
 and add a printk function for debug in lab3.

終於有點空閒時間了,大家中秋節快樂,
這個例子練習了ARM在開機時initial stack的部份,
並加入了一個printk的功能,以便日後debug.

 I just give some notes for now.

start.S -
__vector_reset will invoke when boot, 
it will initialize stack pointer then clear bss section 
and then invoke plat_boot function to print helloworld.

開始後會跳到__vector_reset去進行stack initial的動作
,然後初始化bss段,跳到plat_boot去動作。

boots.c
It will print helloworld and invoke test_printk function.
會印出helloworld並呼叫 test_printk。


source code download (原始碼下載):
https://github.com/tzuCarlos/v1OS.git



further study:
Jserv's CuRTOS give us a nice ARM boot asm example, we'll need to disable MMU, setup stack, timer, interrupt and some hardwares. though bootloader already did some during boot, but for portal reason, a nice OS still need to initial by itself.
請先看Jserv大,寫的CuRTOS的啟動程式部份,裡面有很詳細的註解,不過今天我們只有做stack的配置。
https://github.com/jserv/CuRT/blob/master/arch/arm/mach-pxa/start.S




參考資料:
Jesrv, CuRTOS, https://github.com/jserv/CuRT
王佑中博士,CuRTOS解析, https://sites.google.com/site/embedded2009/introduction-to-curt-v1
http://www.bravegnu.org/gnu-eprog/c-startup.html#_stack

2014年8月28日 星期四


This is a tutorial on bare-metal [OS] development on the Beagleboard-XM.
I will show you how to implement a Helloworld image in this article.
在這篇文章中,我會介紹如何寫一個Helloworld的image. 

1. From BeagleBoard-xM System Reference Manual, we can get, "A single RS232 port is provided on the BeagleBoard and provides access to the TX and
RX lines of UART3 on the processor."
2. From DM3730 Technical Reference Manual- we can get "THR_REG W UART3 base address is 0x49020000"  -

首先我們可以從BeagleBoard-xM System Reference Manual,查到板上子上的RS-232是接在UART3上,再從DM3730 Technical Reference Manual,得知,UART3的THR_REG的位址是0x49020000.

I've already added  comments in source file, please refer to source code(github) for details.
我把註解加入到檔案中了,請到github下載source。

1.boot.asm
#UART3 THR_REG register address
.equ UART3_THR_REG, 0x49020000
.arm
_start:
ldr r0,=UART3_THR_REG
adr r1,.L0
bl helloworld
.L1:
b .L1
.align 2
.L0: 
.ascii "helloworld\n\0"
2.Helloworld.c
int helloworld(unsigned int *addr,const char *p){
while(*p){
*addr=*p++;
};
return 0;
}
3.linker script
MEMORY
{
ram : ORIGIN = 0x80300000, LENGTH = 0x10000
}
SECTIONS
{
.text : { *(.text*) } > ram
}
4.Makefile
ARMGNU = arm-elf
AOPS = --warn --fatal-warnings
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding
boot.bin: boot.asm
$(ARMGNU)-gcc -O2 -c helloworld.c
$(ARMGNU)-as boot.asm -o boot.o
$(ARMGNU)-ld -T linker.ld boot.o helloworld.o -o boot.elf
$(ARMGNU)-objcopy boot.elf -O binary boot.bin
clean:
rm *.elf *.o *.bin -f


U-Boot 2014.01-00014-gcc58fc1 (Feb 10 2014 - 16:24:52)

OMAP3630/3730-GP ES1.1, CPU-OPP2, L3-200MHz, Max CPU Clock 1 Ghz
OMAP3 Beagle board + LPDDR/NAND
I2C:   ready
DRAM:  512 MiB
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0
*** Warning - readenv() failed, using default environment

In:    serial
Out:   serial
Err:   serial
Beagle xM Rev A/B
No EEPROM on expansion board
No EEPROM on expansion board
Die ID #692000019ff80000015eeaa10201402e
Net:   usb_ether
Hit any key to stop autoboot:  0
OMAP3 beagleboard.org # fatload mmc 0:1 0x80300000 boot.bin
reading boot.bin
68 bytes read in 4 ms (16.6 KiB/s)
OMAP3 beagleboard.org # go 0x80300000
## Starting application at 0x80300000 ...
helloworld



原始碼下載:
https://github.com/tzuCarlos/v1OS.git



Reference:
李無言, 一步步寫嵌入式操作系統︰ARM編程的方法與實踐,.
http://www.books.com.tw/products/CN10720115
http://stackoverflow.com/questions/6870712/beagleboard-bare-metal-programming
http://wiki.osdev.org/ARM_Beagleboard

2014年8月8日 星期五

從記憶體中讀資料
load date from memory into register
把暫存器中存資料存進記憶體
store register data into memory

               Figure 1. integer registes, 
               source:https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf

mov operand combinations(mov的運算整理)
mov imm to register, mov $0x11,%eax -> var_a=0x11;
mov imm to mem, mov $0x39,(%eax) -> *p=0x39;
mov reg to reg, mov %edx,%eax -> var_a=var_b;
mov reg to mem, mov %eax,(%edx) -> *p=var_a;
mov mem to reg, mov (%eax),%eax -> var_a=*p;

*can not do memory to memory transfer in single instruction.

Here is an simple swap code:

void swap(int *xp, int *yp)
{
   int a=*xp;
   int b=*yp;

   *xp=b;
   *yp=a;
}

Let's see how above code done by assembly.
Variables store in which memory place and registers is assigned by complier.
讓我們來看上面的程式碼,如何使用組合語言完成,
變數會放在哪個register對應到哪個memory位址,是由complier決定的。


gcc -g -c mov.c -m32 -o mov32

00000000 :
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 10                sub    $0x10,%esp
//start-- int a=*xp; 
//move Memory[ebp+0x8](xp) to register exa.

//move memory content(*xp) to register eax
//move value(*xp) in eax to Memory[ebp-0x4](variable a).
   6:   8b 45 08                mov    0x8(%ebp),%eax
   9:   8b 00                   mov    (%eax),%eax
   b:   89 45 fc                mov    %eax,-0x4(%ebp)

//end int a=*xp;


//  int b=*yp;
// *yp會存在記憶體中ebp+0xC的位址,先把這位址存到eax中

// 再把exa記憶體中對應的值取出來存到,eax
//接著把exa的值,存到b變數所在的記憶體ebp-0x8中
   e:   8b 45 0c                mov    0xc(%ebp),%eax
  11:   8b 00                   mov    (%eax),%eax
  13:   89 45 f8                mov    %eax,-0x8(%ebp)

//end   int b=*yp;
  16:   8b 45 08                mov    0x8(%ebp),%eax
  19:   8b 55 f8                mov    -0x8(%ebp),%edx
  1c:   89 10                   mov    %edx,(%eax)
  1e:   8b 45 0c                mov    0xc(%ebp),%eax
  21:   8b 55 fc                mov    -0x4(%ebp),%edx
  24:   89 10                   mov    %edx,(%eax)
  26:   c9                      leave
  27:   c3                      ret

X86-64
 gcc -g -c mov.c -o mov64

0000000000000000 :
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 89 7d e8             mov    %rdi,-0x18(%rbp)
   8:   48 89 75 e0             mov    %rsi,-0x20(%rbp)
   c:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  10:   8b 00                   mov    (%rax),%eax
  12:   89 45 fc                mov    %eax,-0x4(%rbp)
  15:   48 8b 45 e0             mov    -0x20(%rbp),%rax
  19:   8b 00                   mov    (%rax),%eax
  1b:   89 45 f8                mov    %eax,-0x8(%rbp)
  1e:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  22:   8b 55 f8                mov    -0x8(%rbp),%edx
  25:   89 10                   mov    %edx,(%rax)
  27:   48 8b 45 e0             mov    -0x20(%rbp),%rax
  2b:   8b 55 fc                mov    -0x4(%rbp),%edx
  2e:   89 10                   mov    %edx,(%rax)
  30:   5d                      pop    %rbp
  31:   c3                      retq


reference:
https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf