+886 Let's roll.

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

2014年6月26日星期四

如果今天要用C語言計算50!,int都是不夠用的。 要解這樣的問題,必需要用陣列。
 32位元系統unsigned int 最大 4,294,967,295 (10位數字)
64位元 uint64_t 18,446,744,073,709,551,615 (20 位數字)

/*從array的高位元開始存值*/
void Big_factorial_iteration(int n)
{
  int i=1;

  /*init array*/
  int a[SIZE_A]= {0};
  int tail=SIZE_A-1;

  a[tail]=1;

  for(i=1; i <= n  ; i++)
  {
    int j;
    /* multiply the value */
    for(j= tail ; j >= 0 ; j--)
    {
      a[j]=a[j]*i;
    }
    /*進位留下個位數,其餘的加點前一位 */
    for(j= tail ; j >= 0 ; j--)
    {
      if (a[j] >= 10)
          a[j-1]=a[j-1]+(a[j]/10);
          a[j]=a[j]%10;
    }
  }

  for(i=0; i< SIZE_A ; i++)
  {
     printf("%d",a[i]);
  }
  printf("\n");

}

int main()
{

  printf(" %d \n",factorial_recursion(10));
  printf(" %d \n",factorial_iteration(10));
  Big_factorial_iteration(20); 計算20階層
}

result: [carlos@localhost c_examples]$ ./factorial_2
 3628800
 3628800
 000000000002432902008176640000

 原始碼:
  https://github.com/tzuCarlos/linux_C/blob/master/c_examples/factorial_2.c

reference source:
http://www.cs.utexas.edu/users/djimenez/utsa/cs3343/lecture20.html http://en.wikipedia.org/wiki/Integer_(computer_science)
http://en.wikipedia.org/wiki/Factorial

2014年6月25日星期三


1.先安裝
sudo apt-get install fortune cowsay

2接著加入以下指令到 bash.bashrc中,這樣每次開啟terminal 或 ssh 就會有隻牛跟你說話囉
sudo vim  /etc/bash.bashrc
 

# Spicing up Terminal
fortune | cowsay -n
echo
source: http://xtremediary.blogspot.tw/2010/04/spice-up-ubuntulinux-terminal-with.html