본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

gdt_page

DEFINE_PER_CPU_PAGE_ALIGNED(structgdt_page, gdt_page) = { .gdt = {

  /*

   * Weneed valid kernel segments for data and code in long mode too

   * IRETwill check the segment types  kkeil2000/10/28

   * Alsosysret mandates a special GDT layout

   *

   * TLSdescriptors are currently at a different place compared to i386.

   *Hopefully nobody expects them at a fixed place (Wine?)

   */

  [GDT_ENTRY_KERNEL32_CS]  = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),

  [GDT_ENTRY_KERNEL_CS]  = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),

  [GDT_ENTRY_KERNEL_DS]  = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),

  [GDT_ENTRY_DEFAULT_USER32_CS]  = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),

  [GDT_ENTRY_DEFAULT_USER_DS]  = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),

  [GDT_ENTRY_DEFAULT_USER_CS]  = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),

} };

#defineGDT_ENTRY_INIT(flags, base, limit) { { { \

  .a = ((limit) & 0xffff) | (((base) &0xffff) << 16), \

  .b = (((base) & 0xff0000) >> 16) |(((flags) & 0xf0ff) << 8) | \

  ((limit) & 0xf0000) | ((base) &0xff000000), \

  } } }

structgdt_page {

  struct desc_struct gdt[GDT_ENTRIES];

}__attribute__((aligned(PAGE_SIZE)));

#defineGDT_ENTRIES 16

staticinline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)

{

  return per_cpu(gdt_page, cpu).gdt;

}

staticunsigned long get_segment_base(unsigned int segment)

{

  struct desc_struct *desc;

  int idx = segment >> 3;

  if ((segment & SEGMENT_TI_MASK) ==SEGMENT_LDT) {

  if (idx > LDT_ENTRIES)

  return 0;

  if (idx >current->active_mm->context.size)

  return 0;

  desc = current->active_mm->context.ldt;

  } else {

  if (idx > GDT_ENTRIES)

  return 0;

  desc = __this_cpu_ptr(&gdt_page.gdt[0]);

  }

  return get_desc_base(desc + idx);

}

'Core BSP 분석 > 리눅스 커널 핵심 분석' 카테고리의 다른 글

Debug config  (0) 2023.05.06
CONFIG_DETECT_HUNG_TASK  (0) 2023.05.06
process state  (0) 2023.05.06
cmm: thread dump  (0) 2023.05.05
x86 stack dump(1)  (0) 2023.05.05