[HTML5&CSS] Display property: block과 inline

display property 중 block과 inline에 대해 알아보자.

기본적으로 elements들은 block 아니면 inline 으로 setting된다. block은 horizontally 모든 공간을 점유한다. 반면, inline은 그 content만큼의 공간만 차지한다.
block-level element의 예는 div가 있고, inline element의 예로 span이 있다.

다음과 같이 해서 이 값을 바꿀 수도 있다.

 

[ASM] IT Block

이게 ARM에만 관련된 것인지는 확실치 않다.

일단 ARM Compiler toolchain Assembler Reference에 IT instruction에 관한 설명(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Cjabicci.html)이 있다.

IT는 (If-Then) instuction을 말한다. 이름에서 알 수 있듯이, 분류는 Branch and control instruction 이다. IT instruction은 4개의 이어지는 instructions conditional로 구성되는데, 이를 IT block이라고 한다. 이들 condition은 모두 같을 수도, 일부는 다른 것들과 논리적으로 반대일 수도 있다. 이 instruction이 conditional flags를 바꾸지는 않는다.

IT{x{y{z}}} {cond} 로 쓰인다.

x는 그 IT block에서 두번째 instruction을 위한 condition switch, y는 세번째, z는 4번째, cond는 첫번째이다.

IT block의 2번째에서 4번째 instruction은 다음 중 하나일 수 있다:

T: Then. cond condition이 적용된다.

E: Else. cond의 반대 condition이 적용된다.

BKPT instruction을 제외한 IT block 안의 (branches를 포함하는) instrcution들은 {cond} 부분에 condition을 적어야 한다.

assembler가 뒤의 instruction에 적힌 condition에 따라 자동으로 생성해주므로, IT instrcution을 작성할 필요는 없다. IT instruction을 작성한다면, assembler가 그 validity를 체크한다.

ARM code를 assembling할 때 assembler가 같은 체크를 하지만, IT instrcution을 생성하지는 않는다.

CMP, CMN, TST를 제외한 condition code flags에 영향을 주지 않는 16-bit instrcution들은 IT blcok안에서 사용되어도 상관없다.

IT block 안의 BKPT instrcution은 언제나 실행되기 때문에 {cond} 부분 안에 condition은 필요없다. IT bock은 그 다음 instrcution부터 이어진다.

NOTE: AL condition을 사용함으로써 unconditional instruction을 위한 IT block을 사용할 수 있다.

IT block 안에서의 conditional branches는 IT block 밖에 있는 것보다 더 긴 branch range를 갖는다.

IT block 안에 다음 instruction들은 허용되지 않는다

  • IT
  • CBZ, CBNZ
  • TBB, TBH
  • CPS, CPSID, CPSIE
  • SETEND

IT block이 사용될 때 다른 제한은 다음과 같다.

  • PC를 바꾸는 branch나 다른 instrcution은 그 instruction이 그 block의 마지막 instruction일 때만 허용된다.
  • exception handler로부터 되돌아가기 전까지는 IT block 안의 어떤 instruction으로도 branch할 수 없다.
  • IT block 안에서 어떤 assembler directive도 사용할 수 없다.

NOTE: assembler는 IT block 안에서 이들 instruction들이 사용되면 disgnostic message를 출력한다.

[Linux kernel] GPIO 정리

lwn.net의 GPIO in the kernel: an introductionGPIO in the kernel: future directions 를 보고 나름의 정리를 해둔다.

1. 현재 GPIO의 Kernel Internal API

GPIO를 가지고 뭔가 하기 위해서 다음 헤더 파일을 include 한다.


#include <linux/gpio.h>

현재의 커널은 모든 GPIO를 unsigned integer로 나타낸다. 그래서 platform data나 device tree를 통해 GPIO 번호를 넘기는 것이 가능하다.

GPIO는 사용 전에 allocation 되어야 한다. 현재 구현은 이를 강제하고 있지는 않다. allocation 은 다음 함수를 이용한다.


int gpio_reqeust(unsigned int gpio, const char *label);

label은 나중에 sysfs 로 나타날 수 있다. 반환값 0은 성공, 다른 값은 음수로 에러 번호를 반환한다. 다음을 통해 GPIO를 다시 돌려줄 수 있다.


void gpio_free(unsigned int gpio);

몇 가지 변형이 있는데 gpio_request_one() 은 초기 설정을 같이 할 수 있고, gpio_request_array() 는 몇 개의 GPIO를 한번에 설정하면서 request 할 수 있다. “managed” 버전(예를 들면, devm_gpio_request())은 개발자가 잊어버렸을 때 cleanup을 자동적으로 처리한단다(managed 버전이 있는 건 몰랐네…).

GPIO가 입력으로 사용되면,


int gpio_direction_input(unsigned int gpio);


출력으로 사용되면,


int gpio_direction_output(unsigned int gpio, int value);

output 일 때 value는 꼭 0 이나 1로 지정되어야 한다. 둘 다 성공 시에는 0을, 아니면 음수로 에러 번호를 반환한다.

GPIO 입력값을 읽을 때는,


int gpio_get_value(unsigned int gpio);

에러가 발생하려면 gpio_direction_input()을 호출했을 때 에러가 발생한다고 생각하기 때문에 별도 에러 체크는 하지 않는다. 그러므로 gpio_direction_input()의 반환값을 꼭 체크해야 한다.

GPIO 출력값을 설정할 때는 gpio_direction_output()을 사용할 수도 있지만, 이미 출력모드로 되어 있으면, 다음을 사용하는게 더 낫다.


void gpio_set_value(unsigned int gpio, int value);


몇몇 GPIO 컨트롤러는 GPIO 입력 값이 바뀌면 인터럽트를 걸어주는데, 이 IRQ 번호를 얻고 싶으면,


int gpio_to_irq(unsigned int gpio);

여기서의 gpio는 gpio_request() 로 꼭 얻어야 하고, gpio는 일단 입력 모드로 된다. irq 번호 대신 음수로 된 에러 번호가 반환될 수 있다. 반환된 irq는 request_irq()로 인터럽트 핸들러를 셋팅할 수 있다.

GPIO를 sysfs로 export 해서 user space에서 제어할 수 있도록 하려면,


int gpio_export(unsigned int gpio, bool direction_may_change);

direction_may_change는 보이는 것처럼, user space에서 direction을 바꿀 수 있는지 셋팅해주기 위한 것이다. 안하는 게 낫다. gpio_unexport() 로 sysfs를 없앨  수 있고, gpio_export_link() 를 사용하면 다른 이름으로 export 할 수도 있다.

더 많은 사항은 Documentation/gpio.txt 를 참고.

2. Descriptor-based API (gpiod_*)

현재의 GPIO API 가 integer를 사용하는데, 이 대신에 descriptor-based GPIO 인터페이스를 제공하는 방법이다. 이를 위해 struct gpio_desc * 포인터 타입을 사용한다. 이 인터페이스에 대한 반응은 꽤 좋다고 한다. 거의 곧 머지될 거 같다나..
현재 GPIO API와 매우 비슷하다.


#include <linux/gpio/consumer.h>

int gpiod_direction_input(struct gpio_desc *desc);
int gpiod_direction_direction_output(struct gpio_desc *desc, int value);
int gpiod_get_value(struct gpio_desc *desc);
void gpiod_set_value(struct gpio_desc *desc, int value);
int gpiod_to_irq(struct gpio_desc *desc);
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc);
void gpiod_unexport(struct gpio_desc *desc);


gpio_ prefix 대신 gpiod_ prefix를 사용하고 GPIO 번호 integer대신 struct gpio_desc * 를 사용한다.

GPIO 번호로 descriptor를 얻을 수도 있다.


struct gpio_desc *gpio_to_desc(unsigned gpio);

반대인 desc_to_gpio() 도 있다. desc로 gpio 번호를 얻으면 포인터에서 얻어진 것이므로 현재의 기존 GPIO API에 안심하고 쓸 수 있다. 그러나 GPIO 번호로 descriptor를 얻는 건 별로 좋지 않다. 그래서 다음을 제공한다.


struct gpio_desc *gpiod_get(struct device *dev, const char *name);

dev는 GPIO 라인을 제공하는 device여야 하고, “name”은 라인을 말한다.
GPIO 라인 접근을 제거하기 위해서 gpiod_put() 도 제공한다.

3. Block GPIO

위에 설명한 것들은 개별 GPIO 라인을 관리하는데 초점을 둔다. 근데 GPIO들은 그룹으로 함께 쓰일 때가 많다.
어떤 하드웨어들은 또 한번의 I/O 메모리 write 연산으로 여러 라인을 동시에 바꿀 수 있다. 그래서 여러 GPIO를 하나의 그룹처럼 조작할 때, 하나의 블록으로 엮어서 사용하기 위해 Block GPIO 패치가 시도되었다. Descriptor-based GPIO API 에 비하면 별로 크게 다루어지지는 않았다.


struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size, const char *name);

gpios는 하나의 블록으로 그룹지어지는, GPIO 번호들의 size 크기의 Array 이다. name은 user spcae에서 그 블록으로 동작하는데 사용될 수 있다. gpios 안의 GPIO 들은 gpio_request()로 이전에 이미 요청되어져 있어야 하고, 그 direction 도 각각 셋팅되어져 있어야 한다. GPIO 들이 흩어져 있거나, 드라이버가 Internal Block APIO를 구현하지 않으면, 그냥 지금처럼 개별 라인으로 접근한다.

GPIO 블록의 조작은,


unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
void gpio_block_set(struct gpio_block *block, unsigned long mask, unsigned long values);

mask 로 블록 안의 GPIO를 고를 수 있는데, mask는 위의 gpio_block_create() 로 전달되는 array에 해당하는 비트가 쓰인다. 여기서 알 수 있는 점은 한 개 블록의 GPIO 의 갯수는 long의 비트 수까지만 될 수 있다는 점이다.
gpio_block_get() 은 가능하면 한꺼번에 지정된 라인들을 읽고, 비트 마스크로 결과를 반환한다. gpio_block_set()은 한꺼번에 셋팅할 수 있다.

GPIO 볼록은 다음으로 제거 가능하다.


void gpio_block_free(struct gpio_block *block);


User space에서 sysfs 로 GPIO 블록을 셋팅하거나 읽을 수 있도록하는, 등록 함수도 있다.


int gpio_block_register(struct gpio_block *block);
void gpio_block_unregister(struct gpio_block *block);

등록하면 gpio_block_create()에서 사용한 이름으로 device_node도 생성된다. 그 디바이스를 읽으면, 블록 안의 GPIO의 상태를 반환하고, 쓰면, 그에 따른 GPIO를 셋팅할 수도 있다. read, write 동작에 사용하는 mask를 셋팅하는데-커맨드 번호로 0을 사용- ioctl() 도 제공한다.

[Android] ext4 file system을 위한 빌드 설정 파일

오픈 소스의 Android Build 시스템을 확인해보면 Makefile 에 다음과 같이 system.img 나 userdata.img 등을 만들기 위한 옵션에 따른 처리가 있다.

build/core/Makefile

# #################################################################
# Targets for user images
# #################################################################
INTERNAL_USERIMAGES_EXT_VARIANT :=
ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
INTERNAL_USERIMAGES_USE_EXT := true
INTERNAL_USERIMAGES_EXT_VARIANT := ext2
else
ifeq ($(TARGET_USERIMAGES_USE_EXT3),true)
INTERNAL_USERIMAGES_USE_EXT := true
INTERNAL_USERIMAGES_EXT_VARIANT := ext3
else
ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)
INTERNAL_USERIMAGES_USE_EXT := true
INTERNAL_USERIMAGES_EXT_VARIANT := ext4
endif
endif
endif

ifneq (true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED))

  INTERNAL_USERIMAGES_SPARSE_EXT_FLAG := -s
endif

# $(1): src directory
# $(2): output file
# $(3): mount point
# $(4): ext variant (ext2, ext3, ext4)
# $(5): size of the partition
define build-userimage-ext-target
  @mkdir -p $(dir $(2))
  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
          $(MKEXTUSERIMG) $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG) $(1) $(2) $(4) $(3) $(5)
endef
 
ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
## generate an ext image
# $(1): output file
define build-systemimage-target
    @echo “Target system fs image: $(1)”
    $(call build-userimage-ext-target,$(TARGET_OUT),$(1),system,$(INTERNAL_USERIMAGES_EXT_VARIANT),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))

endef

$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)

        $(call build-systemimage-target,$@)
 

그래서 다음과 같이 ext4 사용, 파티션 사이즈, 그리고 sparse 이미지 여부를 설정해주면 그에 맞는 sytstem.img, userdata.img를 얻을 수 있다.
 

BoardConfig.mk

TARGET_USERIMAGES_USE_EXT4 := true
TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true

BOARD_SYSTEMIMAGE_PARTITION_SIZE := 290979840
BOARD_USERDATAIMAGE_PARTITION_SIZE := 134217728
BOARD_FLASH_BLOCK_SIZE := 4096


ext4 sparse 이미지에 대해서는 system/extras/ext4_utils 의 make_ext4fs 툴의 소스 및 헤더파일을 살펴보면 알 수 있다.