Skip to content

Commit 1257a00

Browse files
committed
improve kklibc stdlib and stdio, add kernel panic red screen
1 parent f1d82ba commit 1257a00

File tree

13 files changed

+224
-207
lines changed

13 files changed

+224
-207
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
commit f1d82ba66c77d46c2b727a6af6c8ce7e559b3c07
2+
Author: Alexeev Bronislav <[email protected]>
3+
Date: Mon Aug 25 02:42:53 2025 +0700
4+
5+
refactor/docs: fix shell, update readme
6+
17
commit 915ca27874432db51cd6d1370d4accd7b53d5d12
28
Author: Alexeev Bronislav <[email protected]>
39
Date: Mon Aug 25 02:32:46 2025 +0700

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
- **Загрузчик** с переходом из реального режима в защищённый
1919
- **GDT** (Глобальная таблица дескрипторов)
2020
- **Управление памятью** с аллокаторами:
21-
- Аллокатор на основе связанных блоков памяти
21+
- Аллокатор на основе связанных блоков памяти (TODO: Подключить стандартные методы `kmalloc`, `kfree`, `krealloc` к пейджингу)
2222
- Paging
2323
- **Драйверы**:
2424
- VGA-экран с поддержкой цветного текста

src/kernel/drivers/screen.c

Lines changed: 30 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,36 @@ void kprint_backspace() {
114114
set_cursor_offset(offset);
115115
}
116116

117+
void halted_cpu_screen_clear() {
118+
int screen_size = MAX_COLS * MAX_ROWS;
119+
int i;
120+
u8 *screen = (u8*) VIDEO_ADDRESS;
121+
122+
for (i = 0; i < screen_size; i++) {
123+
screen[i*2] = ' ';
124+
screen[i*2+1] = WHITE_ON_BLUE;
125+
}
126+
set_cursor_offset(get_offset(0, 0));
127+
}
128+
129+
void panic_red_screen(char* title, char* description) {
130+
int screen_size = MAX_COLS * MAX_ROWS;
131+
u8 *screen = (u8*)VIDEO_ADDRESS;
132+
133+
for (int i = 0; i < screen_size; ++i) {
134+
screen[i * 2] = ' ';
135+
screen[i * 2 + 1] = WHITE_ON_RED;
136+
}
137+
138+
set_cursor_offset(get_offset(0, 0));
139+
140+
kprint_colored("KINTSUGIOS KERNEL PANIC RED SCREEN\n\n", WHITE_ON_RED_CLR_CODE);
141+
kprint_colored(title, WHITE_ON_RED_CLR_CODE);
142+
kprint_colored("\n\n", WHITE_ON_RED_CLR_CODE);
143+
kprint_colored(description, WHITE_ON_RED_CLR_CODE);
144+
145+
asm volatile("hlt");
146+
}
117147

118148
/**********************************************************
119149
* Приватные функции ядра *
@@ -174,18 +204,6 @@ int print_char(char c, int col, int row, char attr) {
174204
return offset;
175205
}
176206

177-
void halted_cpu_screen_clear() {
178-
int screen_size = MAX_COLS * MAX_ROWS;
179-
int i;
180-
u8 *screen = (u8*) VIDEO_ADDRESS;
181-
182-
for (i = 0; i < screen_size; i++) {
183-
screen[i*2] = ' ';
184-
screen[i*2+1] = WHITE_ON_BLUE;
185-
}
186-
set_cursor_offset(get_offset(0, 0));
187-
}
188-
189207
int get_cursor_offset() {
190208
/* Используем VGA порты для получения текущей позиции курсора
191209
* 1. (data 14) Получаем высший байт оффсета курсора
@@ -222,131 +240,3 @@ void clear_screen() {
222240
int get_offset(int col, int row) { return 2 * (row * MAX_COLS + col); }
223241
int get_offset_row(int offset) { return offset / (2 * MAX_COLS); }
224242
int get_offset_col(int offset) { return (offset - (get_offset_row(offset)*2*MAX_COLS))/2; }
225-
226-
227-
// Старый код
228-
// #include "screen.h"
229-
// #include "lowlevel_io.h"
230-
// #include "../common.h"
231-
//
232-
// void kprint(u8 *str)
233-
// {
234-
// /* Функция печати строки */
235-
//
236-
// // u8 *str: указатель на строку (на первый символ строки). Строка должна
237-
// // быть null-terminated.
238-
//
239-
// while (*str)
240-
// {
241-
// putchar(*str, WHITE_ON_BLACK);
242-
// str++;
243-
// }
244-
// }
245-
//
246-
// void putchar(u8 character, u8 attribute_byte)
247-
// {
248-
// /* Более высокоуровневая функция печати символа */
249-
//
250-
// // u8 character: байт, соответствующий символу
251-
// // u8 attribute_byte: байт, соответствующий цвету текста/фона символа
252-
//
253-
// u16 offset;
254-
//
255-
// offset = get_cursor();
256-
// if (character == '\n')
257-
// {
258-
// // Переводим строку.
259-
// if ((offset / 2 / MAX_COLS) == (MAX_ROWS - 1))
260-
// scroll_line();
261-
// else
262-
// set_cursor((offset - offset % MAX_COLS) + MAX_COLS*2);
263-
// }
264-
// else
265-
// {
266-
// if (offset == (MAX_COLS * MAX_ROWS * 2)) scroll_line();
267-
// write(character, attribute_byte, offset);
268-
// set_cursor(offset+2);
269-
// }
270-
// }
271-
//
272-
// void scroll_line()
273-
// {
274-
// /* Функция скроллинга */
275-
//
276-
// u8 i = 1; // Начинаем со второй строки.
277-
// u16 last_line; // Начало последней строки.
278-
//
279-
// while (i < MAX_ROWS)
280-
// {
281-
// memcpy(
282-
// (u8 *)(VIDEO_ADDRESS + (MAX_COLS * i * 2)),
283-
// (u8 *)(VIDEO_ADDRESS + (MAX_COLS * (i-1) * 2)),
284-
// (MAX_COLS*2)
285-
// );
286-
// i++;
287-
// }
288-
//
289-
// last_line = (MAX_COLS*MAX_ROWS*2) - MAX_COLS*2;
290-
// i = 0;
291-
// while (i < MAX_COLS)
292-
// {
293-
// write('\0', WHITE_ON_BLACK, (last_line + i * 2));
294-
// i++;
295-
// }
296-
// set_cursor(last_line);
297-
// }
298-
//
299-
// void clear_screen()
300-
// {
301-
// /* Функция очистки экрана */
302-
//
303-
// u16 offset = 0;
304-
// while (offset < (MAX_ROWS * MAX_COLS * 2))
305-
// {
306-
// write('\0', WHITE_ON_BLACK, offset);
307-
// offset += 2;
308-
// }
309-
// set_cursor(0);
310-
// }
311-
//
312-
// void write(u8 character, u8 attribute_byte, u16 offset)
313-
// {
314-
// /* Функция печати символа на экран с помощью VGA по адресу 0xb8000 */
315-
//
316-
// // u8 character: байт, соответствующий символу
317-
// // u8 attribute_byte: байт, соответствующий цвету текста/фона символа
318-
// // u16 offset: смещение (позиция), по которому нужно распечатать символ
319-
//
320-
// u8 *vga = (u8 *) VIDEO_ADDRESS;
321-
// vga[offset] = character;
322-
// vga[offset + 1] = attribute_byte;
323-
// }
324-
//
325-
// u16 get_cursor()
326-
// {
327-
// /* Функция, возвращающая позицию курсора (char offset). */
328-
//
329-
// port_byte_out(REG_SCREEN_CTRL, 14); // Запрашиваем верхний байт
330-
// u8 high_byte = port_byte_in(REG_SCREEN_DATA); // Принимаем его
331-
// port_byte_out(REG_SCREEN_CTRL, 15); // Запрашиваем нижний байт
332-
// u8 low_byte = port_byte_in(REG_SCREEN_DATA); // Принимаем и его
333-
// // Возвращаем смещение умножая его на 2, т.к. порты возвращают смещение в
334-
// // клетках экрана (cell offset), а нам нужно в символах (char offset), т.к.
335-
// // на каждый символ у нас 2 байта
336-
// return (((high_byte << 8) + low_byte) * 2);
337-
// }
338-
//
339-
// void set_cursor(u16 pos)
340-
// {
341-
// /* Функция, устаналивающая курсор по смещнию (позиции) pos */
342-
//
343-
// pos /= 2; // конвертируем в cell offset (в позицию по клеткам, а не
344-
// // символам)
345-
// // Устанавливаем позицию курсора
346-
// port_byte_out(REG_SCREEN_CTRL, 14); // Указываем, что будем
347-
// // передавать верхний байт
348-
// port_byte_out(REG_SCREEN_DATA, (pos >> 8)); // Передаем верхний байт
349-
// port_byte_out(REG_SCREEN_CTRL, 15); // Указываем, что будем
350-
// // передавать нижний байт
351-
// port_byte_out(REG_SCREEN_DATA, (pos & 0xff)); // передаем нижний байт
352-
// }

src/kernel/drivers/screen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ void kprintln(char *message);
9999
void kprintln_colored(char *message, int color);
100100
void kprint_colored(char *message, int color);
101101
void kprint_backspace();
102+
void panic_red_screen(char* title, char* description);
102103

103104
#endif

src/kernel/kernel/kernel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ void user_input(char *input) {
9090
if (strcmp(input, "HELP") == 0) {
9191
kprintln("Keramika Shell Help");
9292
for (int i = 0; i < commands_length; ++i) {
93-
kprintf("%s - %s\n", commands[i].text, commands[i].hint);
93+
printf("%s - %s\n", commands[i].text, commands[i].hint);
9494
}
9595
executed = 1;
9696
}
9797

9898
if (executed == 0 && strcmp(input, "") != 0) {
99-
kprintf_colored("Invalid command: %s", RED_ON_BLACK_CLR_CODE, input);
99+
printf_colored("Invalid command: %s", RED_ON_BLACK_CLR_CODE, input);
100100
}
101101

102102
// Вывод строки шелла

src/kernel/kernel/utils.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void fibonacci_command(char **args) {
2020

2121
u32 fib = fibonacci(num);
2222

23-
kprintf("fib(%d) = %d", num, fib);
23+
printf("fib(%d) = %d", num, fib);
2424
}
2525

2626
void binary_pow_command(char **args) {
@@ -34,7 +34,7 @@ void binary_pow_command(char **args) {
3434

3535
int powered = binary_pow(b, e);
3636

37-
kprintf("%d ** %d = %d", b, e, powered);
37+
printf("%d ** %d = %d", b, e, powered);
3838
}
3939

4040
void rand_comamnd(char **args) {
@@ -45,7 +45,7 @@ void rand_comamnd(char **args) {
4545

4646
u32 seed = strtoint(args[0]);
4747

48-
kprintf("%d", rand(&seed));
48+
printf("%d", rand(&seed));
4949
}
5050

5151
void rand_range_command(char **args) {
@@ -58,7 +58,7 @@ void rand_range_command(char **args) {
5858
u32 min = strtoint(args[1]);
5959
u32 max = strtoint(args[2]);
6060

61-
kprintf("%d", rand_range(&seed, min, max));
61+
printf("%d", rand_range(&seed, min, max));
6262
}
6363

6464
void reboot_command(char** args) {
@@ -105,10 +105,10 @@ void info_command_shell(char** args) {
105105
meminfo_t meminfo = get_meminfo();
106106

107107
kprint("MEMORY\n");
108-
kprintf("HEAP (%d): start at %d, minimal block size %d\n", meminfo.heap_size, meminfo.heap_start, meminfo.block_size);
109-
kprintf("Total used: %d\n", meminfo.total_used);
110-
kprintf("Total free: %d\n", meminfo.total_free);
111-
kprintf("Block count: %d", meminfo.block_count);
108+
printf("HEAP (%d): start at %d, minimal block size %d\n", meminfo.heap_size, meminfo.heap_start, meminfo.block_size);
109+
printf("Total used: %d\n", meminfo.total_used);
110+
printf("Total free: %d\n", meminfo.total_free);
111+
printf("Block count: %d", meminfo.block_count);
112112
}
113113

114114
void mem_dump(char** args) {
@@ -117,7 +117,7 @@ void mem_dump(char** args) {
117117

118118
void echo_command(char **args) {
119119
for (int i = 0; args[i] != NULL; i++) {
120-
kprintf("%s ", args[i]);
120+
printf("%s ", args[i]);
121121
}
122122
}
123123

@@ -134,7 +134,7 @@ void free_command(char **args) {
134134

135135
u32 addr = hex_strtoint(addr_str);
136136
kfree((void*)addr);
137-
kprintf("Freed memory at %x", addr);
137+
printf("Freed memory at %x", addr);
138138
}
139139

140140
void kmalloc_command(char** args) {
@@ -149,5 +149,5 @@ void kmalloc_command(char** args) {
149149
char buf1[32] = "";
150150
hex_to_ascii((int)ptr, buf1);
151151

152-
kprintf("Allocate %d bytes.\nPointer: %s", size, buf1);
152+
printf("Allocate %d bytes.\nPointer: %s", size, buf1);
153153
}

src/kernel/kklibc/mem.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,6 @@ void heap_init() {
3131
kprint("\n");
3232
}
3333

34-
// TODO: Paging is not implemented
35-
void *get_physaddr(void *virtualaddr) {
36-
unsigned long pdindex = (unsigned long)virtualaddr >> 22;
37-
unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
38-
39-
unsigned long *pd = (unsigned long *)0xFFFFF000;
40-
// Here you need to check whether the PD entry is present.
41-
42-
unsigned long *pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
43-
// Here you need to check whether the PT entry is present.
44-
45-
return (void *)((pt[ptindex] & ~0xFFF) +
46-
((unsigned long)virtualaddr & 0xFFF));
47-
}
48-
4934
void *kmalloc(u32 size) {
5035
// Выравниваем размер до границы BLOCK_SIZE
5136
if (size % BLOCK_SIZE != 0) {
@@ -167,14 +152,14 @@ void kmemdump() {
167152
mem_block_t *current = info.free_blocks;
168153
u32 counter = 0;
169154

170-
kprintf("Heap: %x - %x (%d bytes)\n", info.heap_start,
155+
printf("Heap: %x - %x (%d bytes)\n", info.heap_start,
171156
info.heap_start + info.heap_size, info.heap_size);
172-
kprintf("Block size: %d bytes\n", info.block_size);
173-
kprintf("Total: USED=%d bytes, FREE=%d bytes, in %d blocks\n\n",
157+
printf("Block size: %d bytes\n", info.block_size);
158+
printf("Total: USED=%d bytes, FREE=%d bytes, in %d blocks\n\n",
174159
info.total_used, info.total_free, info.block_count);
175160

176161
while (current) {
177-
kprintf("Block %d: %x, Size=%d, %s\n", counter++, (u32)current,
162+
printf("Block %d: %x, Size=%d, %s\n", counter++, (u32)current,
178163
current->size, current->is_free ? "FREE" : "USED");
179164
current = current->next;
180165
}
@@ -184,5 +169,5 @@ void get_freememaddr() {
184169
char free_mem_addr_str[32] = "";
185170
hex_to_ascii(free_mem_addr, free_mem_addr_str);
186171

187-
kprintf("%s\n", free_mem_addr_str);
172+
printf("%s\n", free_mem_addr_str);
188173
}

src/kernel/kklibc/mem.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ typedef struct meminfo {
3030
u32 block_count;
3131
} meminfo_t;
3232

33-
void *get_physaddr(void *virtualaddr);
3433
meminfo_t get_meminfo();
3534
void get_freememaddr();
3635

0 commit comments

Comments
 (0)