2010년 1월 9일 토요일
Atmel AVRStudio Download
2010년 1월 5일 화요일
VMWare의 Serial 포트 연결하기
- 물리적인 시리얼 포트에 직접 연결 - Host PC에 있는 물리적인 시리얼 포트를 Guest OS에 직접 연결해 준다.
- 파일 출력 - Guest OS의 시리얼 포트를 Host OS의 파일에 연결해 준다. 큰사이즈의 디버깅용 데이터 덤프나 긴 동작 시간동안의 로그 데이터 기록에 유용하다.
- 파이프 이용 - Unix계열 운영체제나 Windows 운영체제는 프로세서간 통신을 위한 IPC를 지원하며, 이때 PIPE를 이용한다. VMWare와 같은 가상화 프로그램에서 내부에 설치된 Guest OS와 Host OS에서 동작하는 응용프로그램간 통신 수행시 이 Pipe를 이용하는 방식이다. 정확하게는 VMWare와 Host OS상의 응용프로그램 사이에 Pipe통신을 수행하고, VMWare는 Guest OS에게 시리얼 포트로 보이도록 변환하는 기능을 수행해 준다.
이제 VMWare의 설정은 끝났으며, Host OS용 응용프로그램를 설정한다.
2010년 1월 3일 일요일
2010년 1월 1일 금요일
VMWARE Workstaion 7.0 한글 패치 유틸
Vmware Workstation 7.0 한글패치
2009년 12월 30일 수요일
AT91SAM9263에서 Linux부팅 시간 단축하기
Faster boot: starting Linux directly from AT91bootstrap
ATMEL의 ARM9프로세서인 AT91SAM9263을 이용하여 개발한 임베디드 보드에 OS로 리눅스를 적용하였다. 임베디드 시스템의 특성상 전원이 투입되면 바로 동작되어야 하나, 리눅스의 부팅과정은 요구조건보다 시간을 많이 소요하여 전원 투입 후 한동안 기다려야 응용프로그램이 동작하기 시작한다. 따라서 부팅시간을 단축하는 것에 관심을 가지고 있던 차에 이에 맞는 유용한 정보를 발견하였다.
Reducing start-up time looks like one of the most discussed topics nowadays, for both embedded and desktop systems. Typically, the boot process consists of three steps:
- First-stage bootloader
- Second-stage bootloader
- Linux kernel
The first-stage bootloader is often a tiny piece of code whose sole purpose is to bring the hardware in a state where it is able to execute more elaborate programs. On our testing board, a CALAO TNY-A9260, it’s a piece of code the CPU stores in internal SRAM and its size is limited to 4Kib, which is a very small amount of space indeed. The second-stage bootloader often provides more advanced features, like downloading the kernel from the network, looking at the contents of the memory, and so on. On our board, this second-stage bootloader is the famous U-Boot.
One way of achieving a faster boot is to simply bypass the second-stage bootloader, and directly boot Linux from the first-stage bootloader. This first-stage bootloader here is AT91bootstrap, which is an open-source bootloader developed by Atmel for their AT91 ARM-based SoCs. While this approach is somewhat static, it’s suitable for production use when the needs are simple (like simply loading a kernel from NAND flash and booting it), and allows to effectively reduce the boot time by not loading U-Boot at all. On our testing board, that saves about 2s.
As we have the source, it’s rather easy to modify AT91bootstrap to suit our needs. To make things easier, we’ll boot using an existing U-Boot uImage. The only requirement is that it should be an uncompressed uImage, like the one automatically generated by make uImage when building the kernel (there’s not much point using such compressed uImage files on ARM anyway, as it is possible to build self-extractible compressed kernels on this platform).
Looking at the (shortened) main.c, the code that actually boots the kernel looks like this:
int main(void)
{
/* ======== 1st step: Hardware Initialization ============ */
/* Performs the hardware initialization */
hw_init();
/* Load from Nandflash in RAM */
load_nandflash(IMG_ADDRESS, IMG_SIZE, JUMP_ADDR);
/* Jump to the Image Address */
return JUMP_ADDR;
}
In the original source code, load_nandflash actually loads the second-stage bootloader, and then jumps directly to JUMP_ADDR (this value can be found in U-Boot as TEXT_BASE, in the board-specific file config.mk. This is the base address from which the program will be executed). Now, if we want to load the kernel directly instead of a second-level bootloader, we need to know a handful of values:
- the kernel image address (we will reuse
IMG_ADDRESShere, but one could
imagine reading the actual image address from a fixed location in NAND) - the kernel size
- the kernel load address
- the kernel entry point
The last three values can be extracted from the uImage header. We will not hard-code the kernel size as it was previously the case (using IMG_SIZE), as this would lead to set a maximum size for the image and would force us to copy more data than necessary. All those values are stored as 32 bits bigendian in the header. Looking at the struct image_header declaration from image.h in the uboot-mkimage sources, we can see that the header structure is like this:
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
It’s quite easy to determine where the values we’re looking for actually are in the uImage header.
ih_sizeis the fourth member, hence we can find it at offset 12ih_loadandih_epare right afterih_size, and therefore can be found at offset 16 and 20.
A first call to load_nandflash is necessary to get those values. As the data we need are contained within the first 32 bytes, that’s all we need to load at first. However, some space is required in memory to actually store the data. The first-stage bootloader is running in internal SRAM, so we can pick any location we want in SDRAM. For the sake of simplicity, we’ll choose PHYS_SDRAM_BASE here, which we define to the base address of the on-board SDRAM in the CPU address space. Then, a second call will be necessary to load the entire kernel image at the right load address.
Then all we need to do is:
#define be32_to_cpu(a) ((a)[0] << 24 | (a)[1] << 16 | (a)[2] << 8 | (a)[3])
#define PHYS_SDRAM_BASE 0x20000000
int main(void)
{
unsigned char *tmp;
unsigned long jump_addr;
unsigned long load_addr;
unsigned long size;
hw_init();
load_nandflash(IMG_ADDRESS, 0x20, PHYS_SDRAM_BASE);
/* Setup tmp so that we can read the kernel size */
tmp = PHYS_SDRAM_BASE + 12;
size = be32_to_cpu(tmp);
/* Now, load address */
tmp += 4;
load_addr = be32_to_cpu(tmp);
/* And finally, entry point */
tmp += 4;
jump_addr = be32_to_cpu(tmp);
/* Load the actual kernel */
load_nandflash(IMG_ADDRESS, size, load_addr - 0x40);
return jump_addr;
}
Note that the second call to load_nandflash could in theory be replaced by:
load_nandflash(IMG_ADDRESS + 0x40, size + 0x40, load_addr);
However, this will not work. What happens is that load_nandflash starts reading at an address aligned on a page boundary, so even when passing IMG_ADDRESS+0x40 as a first argument, reading will start at IMG_ADDRESS, leading to a failure (writes have to aligned on a page boundary, so it is safe to assume that IMG_ADDRESS is actually correctly aligned).
The above piece of code will silently fail if anything goes wrong, and does no checking at all – indeed, the binary size is very limited and we can’t afford to put more code than what is strictly necessary to boot the kernel.
2009년 12월 29일 화요일
Free Embedded RTOS - ChibiOS/RT
- 개요
ChibiOS/RT is designed for deeply embedded real time applications where execution efficiency and tiny code size are desiderable features.
The system is implemented as a library to be linked with the application code, the OS and the application code together form the image to be loaded on the target device.
- 특징
The kernel provides a rich features set, it offers: preemptive multithreading, 128 priority levels, optional round-robin support, unified interrupts handling, support for preemptable interrupt handlers, virtual timers, semaphores, mutexes, condition variables,synchronous messages, mailboxes, event flags, Abstract Channels, I/O queues, heapand memory pools allocators.
Of course, the above mechanisms are not always required in most applications, it is possible to selectively exclude the unused subsystems reducing the total code size.
- 코드 사이즈
The kernel is very compact, on a reference Cortex-M3 (STM32) platform the kernel size ranges from 1.2KiB minimum up to 5.2KiB maximum size. Size metrics are available for all platforms, as test reports, into the source distribution.
- 성능
On a reference STM32 platform clocked at 72MHz the kernel is capable of context switching in1.41 microseconds, taking/releasing a semaphore takes 1.21 microseconds, spawning a thread (the whole create-execute-terminate cycle) takes 4.64 microseconds.
The timings are measured using the internal test suite, it is possible to inspect the benchmarking methodology and replicate the results by simply running the included demos. Performance metrics are available for all platforms, as test reports, into the source distribution.
- 링크