8. Параметры ядра

Предыдущая  Содержание  Следующая V*D*V

Загрузчик должен передать параметры ядру для описания выполненных установок, размера и формы памяти в системе и, опционально, многие другие величины.

 

Список тэгов должен отвечать следующим ограничениям:

 

Список должен быть сохранён в оперативную память и размещён в области памяти, где ни декомпрессор ядра, ни манипуляции initrd не перезапишут его. Рекомендуется размещение в первых 16 Кб оперативной памяти, обычно, в начале физической памяти плюс 0x100 (который оставляет место нулевой странице векторов исключений). Физический адрес списка тэгов должен быть помещен в R2 при входе в ядро, но исторически это не было обязательным и ядро будет использовать фиксированные значения в начале физической памяти плюс 0x100. На это не следует полагаться в будущем.

Список не должен выходить за границы области 0x4000, где создаётся начальная таблица трансляции страниц. Ядро не выполняет никаких проверок границ и перезапишет список параметров, если он сделает это.

Список должен быть выровнен к границам слова (32 бита, 4 байта) (если не используете рекомендованные размещения).

Список должен начинаться с ATAG_CORE и заканчиваться ATAG_NONE.

Список должен содержать по крайней мере один ATAG_MEM

 

Каждый тэг в списке состоит из заголовка, содержащего две беззнаковых 32-битных величины: размера тэга (32 бита, 4 байтное слово) и значение тэга.

 

struct atag_header {

    u32 size; /* размер тэга в словах, включая этот заголовок */

    u32 tag;  /* значение тэга */

};

 

За каждым заголовочным тэгом следуют данные, связанные с этим тэгом, за исключением ATAG_NONE, который не имеет данных и ATAG_CORE, где данные не является обязательными. Размер данных определяется размером поля в заголовке, минимальный размер равен 2, так как размер заголовка включён в эту величину. ATAG_NONE уникален тем, что его поле размера (size) устанавливается в ноль.

 

Тэг может содержать дополнительные данные после обязательных структур при условии, что размер (size) скорректирован для покрытия дополнительной информации, это даёт возможность дальнейшего расширения и загрузчик сможет продлить данные, предоставляемые ядру. Например, загрузчик может предоставить дополнительную информацию о серийных номерах в ATAG_SERIAL, которые могут затем быть интерпретированы модифицированным ядром.

 

Порядок тэгов в списке параметров не имеет значения, они могут появиться столько раз, сколько требуется, хотя толкование дублирующихся тэгов зависит от обстоятельств.

 

Данные для каждого отдельного тэга описаны в Приложении A, справочный разделе "Значения Тэгов".

 

Таблица 3. Список используемых тэгов.

 

Имя тэга

Значение

Размер

Описание

ATAG_NONE

0x00000000

2

Пустой тэг, используемый в конце списка

ATAG_CORE

0x54410001

5 (2 if empty)

Первый тэг, используемый в начале списка

ATAG_MEM

0x54410002

4

Описывает физическую область памяти

ATAG_VIDEOTEXT

0x54410003

5

Описывает текстовый VGA дисплей

ATAG_RAMDISK

0x54410004

5

Описывает как в ядре будет использоваться ramdisk

ATAG_INITRD2

0x54420005

4

Описывает где размещается в памяти скомпрессированный образ ramdisk

ATAG_SERIAL

0x54410006

4

64 битный серийный номер

ATAG_REVISION

0x54410007

3

32 битный номер ревизии платы

ATAG_VIDEOLFB

0x54410008

8

Начальные значения кадровых буферов типа vesafb-type

ATAG_CMDLINE

0x54410009

2 + ((length_of_cmdline + 3) / 4)

Командная строка для передачи ядру

 

Структура может быть определена следующим образом:

 

struct atag {

    struct atag_header hdr;

    union {

        struct atag_core core;

        struct atag_mem mem;

        struct atag_videotext videotext;

        struct atag_ramdisk ramdisk;

        struct atag_initrd2 initrd2;

        struct atag_serialnr serialnr;

        struct atag_revision revision;

        struct atag_videolfb videolfb;

        struct atag_cmdline cmdline;

    } u;

};

 

После того, как эти структуры были определены, необходимо их определить примерно так, как показано:

 

#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))

#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)

static struct atag *params; /* используется как указатель на текущий тэг */

 

static void

setup_core_tag(void * address,long pagesize)

{

    params = (struct tag *)address;         /* Начальные параметры для старта */

    params->hdr.tag = ATAG_CORE;            /* начинаем с основного тэга */

    params->hdr.size = tag_size(atag_core); /* размер тэга */

    params->u.core.flags = 1;               /* обеспечить только чтение */

    params->u.core.pagesize = pagesize;     /* размер системной страницы (4k) */

    params->u.core.rootdev = 0;             /* нулевое корневое устройство (обычно перезаписывается)

    params = tag_next(params);              /* передвинуть указатель на следующий тэг */

}

 

static void

setup_mem_tag(u32_t start, u32_t len)

{

    params->hdr.tag = ATAG_MEM;            /* Тэг памяти */

    params->hdr.size = tag_size(atag_mem); /* размер тэга */

    params->u.mem.start = start;           /* Начало области памяти (физический адрес)

    params->u.mem.size = len;              /* Размер области */

    params = tag_next(params);             /* передвинуть указатель на следующий тэг */

}

 

static void

setup_end_tag(void)

{

    params->hdr.tag = ATAG_NONE; /* Пустой тэг заканчивает список */

    params->hdr.size = 0;        /* нулевая длина */

}

 

static void

setup_tags(parameters)

{

    setup_core_tag(0x100, 4096);         /* стандартный основной тэг, размер страницы 4k */

    setup_mem_tag(0x10000000, 0x400000); /* 64Mb с адреса 0x10000000 */

    setup_mem_tag(0x18000000, 0x400000); /* 64Mb с адреса 0x18000000 */

    setup_end_tag(void);                 /* завершающий тэг */

}

 

Этот завершённый  фрагмент кода иллюстрирует абсолютные минимальные требования для набора параметров и предназначен для демонстрации концепций, высказанных ранее в этом разделе. Реальный загрузчик, вероятно, установит дополнительное значения и, вероятно, протестирует память в реальной системе, вместо использования фиксированных значений. Более полный пример можно найти в Приложении B, "Полный пример".

 

Предыдущая  Содержание  Следующая