Monday, January 9, 2012

I think port to ARM.

I'm thinking my own OS to port x86 to ARM.
I have to control ARM chip.
I will try to design and make program on ARM.
Install gcc for ARM.
$ sudo apt-get install gcc-arm-linux-gnueabi
Install ARM qemu.
$ sudo apt-get install qemu qemu-kvm qemu-kvm-extras
Write program by ARM assemble(hello world) and check ARM registers.
.text
    .align 2
    .global _start

# write system call
sys_write = 0x900004
# exit system call
sys_exit = 0x900001

# Program entry
_start:
    ldr r1, msg
    mov r0, #1
    ldr r2, msg_sz
    swi #sys_write

    mov r0, #0
    swi #sys_exit

msg:    .long msg_str
msg_sz: .long msg_sz0

    .data
    .align 2

msg_str: .asciz "Hello, world\n"

    .align 2
    msg_sz0 = . - msg_str

    .bss
    .align 2
data: .long 0
Compile and link program.
$ arm-linux-gnueabi-as -o hello.o hello.s                 
$ arm-linux-gnueabi-ld hello hello.o
Run software on ARM qemu.
$ qemu-arm ./hello

Hello, world
$
Thanks.

Reading ATA device sector


I should write to read ATA device sector.
  1. First, We will wait until the port 0x03f6 is zero using device selection protocol.
  2. Second, Next, We will set device number to port 0x01f6(device/head register).
  3. Next, We will set 0x02 to port 0x03f6(device control register) and set 0x00 to port 0x01f1(features register).
  4. Then, We will prepare for reading sector.Details below.
  5. out8(0x01f2, 1); // Set read count.
    out8(0x01f3, sector & 0xff); // Set sector number to register.
    out8(0x01f4, (sector >> 8) & 0xff); // Set cylinder low to register.
    out8(0x01f5, (sector >> 16) & 0xff); // Set cylinder High to register.
    out8(0x01f6, ((sector >> 24) & 0x0f) | 0x40); // Set Head number to register.
    
  6. Finally, We will read sector data by setting 0x20 to port 0x01f7.
    1. out8(0x01f7, 0x20); // read data.
for(i = 0; i < SECTOR_SIZE; i++) {
  buf[i] = inw(0x01f0);
}

in8(0x03f6);
in8(0x01f7);
Thank you.