Initialize the Buffer Management Structure

Một phần của tài liệu The art of linux kernel design (Trang 90 - 93)

2. Device Initialization and Process 0 Activation 45

2.10 Initialize the Buffer Management Structure

The buffer area is the medium through which the memory exchanges data with peripher- als. The biggest difference between the memory and the hard drive lies in the fact that the disk saves large amounts of data at a low cost. The disk is not involved in operations (because the CPU cannot address the disk). In addition, the memory not only needs to store data, but the more important thing here is to perform data operation with the CPU and bus. The buffer is in between, and it not only saves the data but also participates in some searching, organization, and indirect, auxiliary operation. After having the buffer medium to the peripherals, it only needs to consider exchanging data with the buffer in accordance with the requirements and does not need to consider how the memory will use these interaction data. As for memory, it also only needs to consider whether the condition

0x9FFFF

ROM BIOS and VGA

Kernel

Disable interrupt

0x00000 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

Kernel code area Kernel data area

Kernel code area Kernel data area (IDT)

system_call

Hook the system call service program system_call to the 0x80 item of IDT

0 47 255

0 47 255

system_call (IDT)

Before loading system call service program After loading system call service program

Figure 2.22 Call service program of the system.

of the interaction with the buffer is ready and does not need to care about the interaction between buffer and peripherals. Organization, management, and coordination are oper- ated by the OS.

The OS manages the buffer through the hash_table[NR_HASH] and the buffer_head two-way chain complex hash table.

The OS sets the buffer by calling the buffer_init function; the execute code is as follows:

In the buffer_init function, from the kernel end and the terminal of the buffer area beginning at the same time grow in relative direction, pair to make buffer_head, buffer block, until less than a pair of buffer_head, a buffer block, in the second chapter, at the beginning of the memory set pattern, with about 3000 pairs of buffer_head, buffer block, buffer_head in low address, buffer block in the high address (Figure 2.23).

Set the member of device head: device id b_dev, b_count, “update” sign b_uptodate,

“dirty” logo sign b_dirt, and “locking” flag b_lock to 0. As shown in the figure, the b_data pointer points to the corresponding buffer block. Using the b_prev_free and b_next_free of the buffer_head, set all the buffer_head into a two-way linked list. The free_list refers to the first buffer_head, and use free_list to set the two-way linked list formed by the buffer_

head link into a bidirectional ring chain, as shown in the following illustration (Figure 2.24).

Notice the memory change shown at the top of Figure 2.25. There is a black area of the memory near the system core part that stored the buffer management structure. Because it manages more than 3000 buffer blocks, it takes up the same memory space as the kernel.

The figure describes the two-way linked list structure.

Finally, set the hash_table[307] and all the contents of hash_table[307] to NULL. As shown in Figure 2.25, the code is as follows:

free_list

Note: both sides are arranged tightly buffer_head

h->b_data = (char *) b

Figure 2.23 An overview of initialization a.

//code path:init/main.c:

void main(void) {

……

buffer_init(buffer_memory_end);

……

}

N indicates NULL It is free when starting

hash_table free_list

N indicates that count is 0

N N N N N N

N N N N N N

N N N N N ...

Figure 2.24 An overview of initialization b.

ROM BIOS and VGA

Hash table Kernel

Disable interrupt

0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

Kernel code area Kernel data area

0 307

Step 1: sets free list

Step 2: set the hash table

Hash table NULL

After initializing buffer Before initializing buffer List head

0 307

Kernel code area Kernel data area

Figure 2.25 Initialize the buffer management structure.

//code path:fs/buffer.c:

……

struct buffer_head * start_buffer = (struct buffer_head *) &end;

struct buffer_head * hash_table[NR_HASH];

static struct buffer_head * free_list;

……

Look at the code struct buffer_head *h = start_buffer; in this line, start_buffer iden- tifies the starting position of the buffer. This also solves the problem about the starting position of the buffer. It is defined in buffer.c:

struct buffer_head * start_buffer = (struct buffer_head *) &end;

The end is the end address of the kernel code. In the designing stage, it is difficult to accurately estimate this address. Set the end value during kernel module linking and use it here.

Một phần của tài liệu The art of linux kernel design (Trang 90 - 93)

Tải bản đầy đủ (PDF)

(524 trang)