Форум программистов, компьютерный форум, киберфорум
Разработка и тестирование
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/42: Рейтинг темы: голосов - 42, средняя оценка - 4.83
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106

Хочу создать загрузчик для своей ОС

12.01.2010, 21:28. Показов 8705. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Я очень хочу создать ОС. Большую часть работы я уже сделал, но мне надо сделать загрузчик.
Помогите мне его сделать. Я был бы очень благодарен!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.01.2010, 21:28
Ответы с готовыми решениями:

Хочу обновить видеокарту для своей системы
Здравствуйте подскажите пожалуйста у меня сборка такая : Intel Core i7 3770 @ 3.40GHz Технология Ivy Bridge 22nm бп-600W 16,0ГБ...

Хочу сделать красивый дизайн для своей программы в делфи.
Доброго времени суток уважаемые форумчане! Хочу сделать красивый дизайн для своей программы в делфи. и столкнулся с такой фишкой как...

Хочу загрузчик на С++
Ничего не делающий загрузчик на FASM: use16 org 07c00h start: jmp $ endst: rb 510-(endst-start) db 055h, 0aah Как...

4
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
18.01.2010, 16:55
Лучший ответ Сообщение было отмечено как решение

Решение

Ради интереса:
Расскажи о функционале твоей ОС:
А если по делу, а не ассемблерных дел мастер:

Завалялась у меня одна статья из нета достал когда-то:
Ради экономии места: использовал теги кода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
Статья real HELLO world:
Изучение нового языка программирования начинается, как правило, с написания простенькой программы, выводящей на экран краткое приветствие типа "Hello World!". Например, для C это будет выглядить приблизительно так. 
 
main()
{
printf("Hello World!\n");
}
Показательно, но совершенно не интересно. Программа, конечно работает, режим защищенный, но ведь для ее функционирования требуется ЦЕЛАЯ операционная система. А что если написать такой "Hello World", для которого ничего не надо. Вставляем дискетку в компьютер, загружаемся с нее и ..."Hello World". Можно даже прокричать это приветствие из защищенного режима. 
 
Сказано - сделано. С чего бы начать?.. Набраться знаний, конечно. Для этого очень хорошо полазить в исходниках Linux и Thix. Первая система всем хорошо знакома, вторая менее известна, но не менее полезна. 
 
Подучились? ... Понятно, что сперва надо написать загрузочный сектор для нашей мини-опрерационки (а ведь это именно мини-операционка). Поскольку процессор грузится в 16-разрядном режиме, то для созджания загрузочного сектора используется ассемблер и линковщик из пакета bin86. Можно, конечно, поискать еще что-нибудь, но оба наших примера используют именно его и мы тоже пойдет по стопам учителей. Синтаксис этого ассемблера немколько странноватый, совмещающий черты, характерные и для Intel и для AT&T (за подробностями направляйтесь в Linux-Assembly-HOWTO), но после пары недель мучений можно привыкнуть. 
 
2. Загрузочный сектор (boot.S)
 
 
 
Сознательно не буду приводить листингов программ. Так станут понятней основные идеи, да и вам будет намного приятней, если все напишите своими руками. 
 
Для начала определимся с основными константами. 
 
START_HEAD = 0 - Головка привода, которою будем использовать. 
 
START_TRACK = 0 - Дорожка, откуда начнем чтение. 
 
START_SECTOR = 2 - Сектор, начиная с которого будем считывать наше ядрышко. 
 
SYSSIZE = 10 - Размер ядра в секторах (каждый сектор содержит 512 байт) 
 
FLOPPY_ID = 0 - Идентификатор привода. 0 - для первого, 1 - для второго 
 
HEADS = 2 - Количество головок привода. 
 
SECTORS = 18 - Количество дорожек на дискете. Для формата 1.44 Mb это количество равно 18. 
 
В процессе загрузки будет происходить следующее. Загрузчик BIOS считает первый сектор дискеты, положит его по адресу 0000:0x7c00 и передаст туда управление. Мы его получим и для начала переместим себя пониже по адресу 0000:0x600, перейдем туда и спокойно продолжим работу. Собственно вся наша работа будет состоять из загрузки ядра (сектора 2 - 12 первой дорожки дискеты) по адресу 0x100:0000, переходу в защищенный режим и скачку на первые строки ядра. В связи с этим еще несколько констант: 
 
BOOTSEG = 0x7c00 - Сюда поместит загрузочный сектор BIOS. 
 
INITSEG = 0x600 - Сюда его переместим мы. 
 
SYSSEG = 0x100 - А здесь приятно расположится наше ядро. 
 
DATA_ARB = 0x92 - Определитель сегмента данных для дескриптора 
 
CODE_ARB = 0x9A - Определитель сегмента кода для дескриптора. 
 
Первым делом произведем перемещение самих себя в более приемлемое место. 
 
   cli
   xor     ax, ax
   mov     ss, ax
   mov     sp, #BOOTSEG
   mov     si, sp
   mov     ds, ax
   mov     es, ax
   sti
   cld
   mov     di, #INITSEG
   mov     cx, #0x100
   repnz
   movsw
   jmpi    go, #0      ;  прыжок в новое местоположение 
                          загрузочного сектора  на метку go
Теперь необходимо настроить как следует сегменты для данных (es, ds) и для стека. Это конечно неприятно, что все приходится делать вручную, но что делать. Ведь нет никого в памяти компьютера, кроме нас и BIOS. 
 
go:
  mov     ax, #0xF0
  mov     ss, ax
  mov     sp, ax          ; Стек разместим как 0xF0:0xF0 = 0xFF0
  mov     ax, #0x60       ; Сегменты для данных ES и DS зададим в 0x60
  mov     ds, ax
  mov     es, ax
Наконец можно вывести победное приветствие. Пусть мир узнает, что мы смогли загрузиться. Поскольку у нас есть все-таки еще BIOS, воспользуемся готовой функцией 0x13 прерывания 0x10. Можно конечно презреть его и написать напрямую в видеопамять, но у нас каждый байт команды на счету, а байт таких всего 512. Потратим их лучше на что-нибудь более полезное. 
 
  mov     cx,#18
  mov     bp,#boot_msg
  call    write_message
Функция write_message выгдядит следующим образом 
 
write_message:
   push    bx
   push    ax
   push    cx
   push    dx
   push    cx
   mov     ah,#0x03      ; прочитаем текущее положение курсора,
                           дабы не выводить сообщения где попало.
   xor     bh,bh
   int     0x10
   pop     cx
   mov     bx,#0x0007    ; Параметры выводимых символов :
                           видеостраница 0, аттрибут 7 (серый на черном)
   mov     ax,#0x1301    ; Выводим строку и сдвигаем курсор.
   int     0x10
   pop     dx
   pop     cx
   pop     ax
   pop     bx
   ret
А сообщение так 
 
boot_msg:
                .byte 13,10
                .ascii "Booting data ..."
                .byte 0
К этому времени на дисплее компьютера появится скромное "Booting data ..." . Это в принципе уже "Hello World", но давайте добьемся чуточку большего. Перейдем в защищенный режим и выведем этот "Hello" уже из программы написаной на C. 
 
Ядро 32-разрядное. Оно будет у нас размещаться отдельно от загрузочного сектора и собираться уже gcc и gas. Синтаксис ассемблера gas соответсвует требованиям AT&T, так что тут уже все проще. Но для начала нам нужно прочитать ядро. Опять воспользуемся готовой функцией 0x2 прерывания 0x13. 
 
recalibrate:
  mov     ah, #0
  mov     dl, #FLOPPY_ID
  int     0x13            ; производим переинициализацию дисковода.
  jc      recalibrate
  call    read_track      ; вызов функции чтения ядра
  jnc     next_work       ; если во время чтения не произошло ничего
                            плохого то работаем дальше
bad_read:
                          ; если чтение произошло неудачно то
                            выводим сообщение об ошибке
  mov     bp,#error_read_msg
  mov     cx,7
  call    write_message
inf1:     jmp     inf1    ; и уходим в бесконечный цикл.
                            Теперь нас спасет только ручная перезагрузка
Сама функция чтения предельно простая: долго и нудно заполняем параметры, а затем одним махом считываем ядро. Усложнения начнуться, когда ядро перестанет помещаться в 17 секторах ( то есть 8.5 kb), но это пока только в будущем, а пока вполне достаточно такого молниеносного чтения. 
 
read_track:
   pusha
   push  es
   push  ds
   mov   di, #SYSSEG         ; Определяем
   mov   es, di              ; адрес буфера для данных
   xor   bx, bx
   mov   ch, #START_TRACK    ;дорожка 0
   mov   cl, #START_SECTOR   ;начиная с сектора 2
   mov   dl, #FLOPPY_ID
   mov   dh, #START_HEAD
   mov   ah, #2
   mov   al, #SYSSIZE        ;считать 10 секторов
   int   0x13
   pop   ds
   pop   es
   popa
   ret
Вот и все. Ядро успешно прочитано и можно вывести еще одно радостное сообщение на экран. 
 
next_work:
  call    kill_motor       ; останавливаем привод дисковода
  mov     bp,#load_msg     ; выводим сообщение
  mov     cx,#4
  call    write_message
Вот содержимое сообщения 
 
load_msg:
   .ascii "done"
   .byte 0
А вот функция остановки двигателя привода. 
 
kill_motor:
  push    dx
  push    ax
  mov     dx,#0x3f2
  xor     al,al
  out     dx,al
  pop     ax
  pop     dx
  ret
На данный момент на экране выведено "Booting data ...done" и лампочка привода флоппи-дисков погашена. Все затихли и готовы к смертельному номеру - прыжку в защищенный режим. 
 
Для начала надо включить адресную линию A20. Это в точности означает, что мы будем использовать 32-разрядную адресацию к данным. 
 
  mov     al, #0xD1      ; команда записи для 8042
  out     #0x64, al
  mov     al, #0xDF      ; включить A20
  out     #0x60, al
Выведем предупреждающее сообщение, о том, что переходим в защищенный режим. Пусть все знают, какие мы важные. 
 
protected_mode:
   mov     bp,#loadp_msg
   mov     cx,#25
   call    write_message
(Сообщение: 
 
loadp_msg:
   .byte 13,10
   .ascii "Go to protected mode..."
   .byte 0
 )
Пока еще у нас жив BIOS, запомним позицию курсора и сохраним ее в известном месте ( 0000:0x8000 ). Ядро позже заберет все данные и будет их использовать для вывода на экран победного сообщения. 
 
save_cursor:
   mov     ah,#0x03     ; читаем текущую позицию курсора
   xor     bh,bh
   int     0x10
   seg     cs
   mov     [0x8000],dx  ;сохраняем в специальном тайнике
Теперь внимание, запрещаем прерывания (нечего отвлекаться во время такой работы) и загружаем таблицу дескрипторов 
 
   cli
   lgdt    GDT_DESCRIPTOR    ; загружаем описатель таблицы 
                               дескрипторов.
У нас таблица дескрипторов состоит из трех описателей: Нулевой (всегда должен присутствовать), сегмента кода и сегмента данных 
 
.align  4
.word   0
GDT_DESCRIPTOR: .word   3 * 8 - 1             ; размер таблицы 
                                                дескрипторов
                .long   0x600 + GDT           ; местоположение 
                                                таблицы дескрипторов
.align  2
GDT:
                .long   0, 0                  ;   Номер  0: пустой
                                                  дескриптор
                .word   0xFFFF, 0             ;   Номер  8: 
                                                  дескриптор кода
                .byte   0, CODE_ARB, 0xC0, 0
                .word   0xFFFF, 0             ;   Номер 0x10: 
                                                  дескриптор данных
                .byte   0, DATA_ARB, 0xCF, 0
Переход в защищенный режим может происходить минимум двумя способами, но обе ОС , выбранные нами для примера (Linux и Thix) используют для совместимости с 286 процессором команду lmsw. Мы будем действовать тем же способом 
 
  mov     ax, #1
  lmsw    ax          ; прощай реальный режим. Мы теперь 
                        находимся в защищенном режиме.
  jmpi    0x1000, 8   ; Затяжной прыжок на 32-разрядное ядро.
Вот и вся работа загрузочного сектора - немало, но и немного. Теперь мы попрощаемся с ним и направимся к ядру. 
 
В конце ассемблерного файла полезно добавить следующую инструкцию. 
 
.org 511
end_boot:       .byte   0
В результате скомпилированный код будет занимать ровно 512 байт, что очень удобно для подготовки образа загрузочного диска. 
 
3. Первые вздохи ядра (head.S)
 
 
 
Ядро к сожалению опять начнется с ассемблерного кода. Но теперь его будет совсем немного. 
 
Мы собственно зададим правильные значения сегментов для данных (ES, DS, FS, GS). Записав туда значение соответствующего дескриптора данных. 
 
  cld
  cli
  movl $(__KERNEL_DS),%eax
  movl %ax,%ds
  movl %ax,%es
  movl %ax,%fs
  movl %ax,%gs
Проверим, нормально ли включилась адресная линия A20 простым тестом записи. Обнулим для чистоты эксперимента регистр флагов. 
 
     xorl %eax,%eax
1:   incl %eax
     movl %eax,0x000000
     cmpl %eax,0x100000
     je 1b
     pushl $0
     popfl
Вызовем долгожданную функцию, уже написанную на С. 
 
   call SYMBOL_NAME(start_my_kernel)
И больше нам тут делать нечего. 
 
inf:    jmp     inf
4. Поговорим на языке высокого уровня (start.c)
 
 
 
Вот теперь мы вернулись к тому с чего начинали рассказ. Почти вернулись, потому что printf() теперь надо делать вручную. поскольку готовых прерываний уже нет, то будем использовать прямую запись в видеопамять. Для любопытных - почти весь код этой части , с незначительными изменениями, повзаимствован из части ядра Linux, осуществляющей распаковку (/arch/i386/boot/compressed/*). Для сборки вам потребуется дополнительно определить такие макросы как inb(), outb(), inb_p(), outb_p(). Готовые определения проще всего одолжить из любой версии Linux. 
 
Теперь, дабы не путаться со встроенными в glibc функциями, отменим их определение 
 
#undef memcpy
Зададим несколько своих 
 
static void puts(const char *);
static char *vidmem = (char *)0xb8000; /*адрес видеопамати*/
static int vidport;                    /*видеопорт*/
static int lines, cols;                /*количество линий и строк на экран*/
static int curr_x,curr_y;              /*текущее положение курсора */
И начнем, наконец, писать код на языке высокого уровня... правда с небольшими ассемблерными вставками. 
 
/*функция перевода курсора в положение (x,y). Работа ведется через ввод/вывод в видеопорт*/ 
 
void gotoxy(int x, int y)
{
int pos;
  pos = (x + cols * y) * 2;
  outb_p(14, vidport);
  outb_p(0xff & (pos >> 9), vidport+1);
  outb_p(15, vidport);
  outb_p(0xff & (pos >> 1), vidport+1);
}
/*функция прокручивания экрана. Работает, используя прямую запись в видеопамять*/ 
 
static void scroll()
{
   int i;
   memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
   for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
           vidmem[i] = ' ';
}
/*функция вывода строки на экран*/ 
 
static void puts(const char *s)
{
  int x,y;
  char c;
  x = curr_x;
  y = curr_y;
  while ( ( c = *s++ ) != '\0' ) {
   if ( c == '\n' ) {
     x = 0;
     if ( ++y >= lines ) {
             scroll();
             y--;
     }
   } else {
     vidmem [ ( x + cols * y ) * 2 ] = c;
     if ( ++x >= cols ) {
          x = 0;
          if ( ++y >= lines ) {
            scroll();
                  y--;
          }
     }
 }
  }
  gotoxy(x,y);
}
/*функция копирования из одной области памяти в другую. Заместитель стандартной функции glibc */ 
 
void* memcpy(void* __dest, __const void* __src,
                            unsigned int __n)
{
        int i;
        char *d = (char *)__dest, *s = (char *)__src;
        for (i=0;i<__n;i++) d[i] = s[i];
}
/*функция издающая долгий и протяжных звук. Использует только ввод/вывод в порты поэтому очень полезна для отладки*/ 
 
make_sound()
{
__asm__("
   movb    $0xB6, %al\n\t
   outb    %al, $0x43\n\t
   movb    $0x0D, %al\n\t
   outb    %al, $0x42\n\t
   movb    $0x11, %al\n\t
   outb     %al, $0x42\n\t
   inb     $0x61, %al\n\t
   orb     $3, %al\n\t
   outb    %al, $0x61\n\t
");
}
/*А вот и основная функция*/
int start_my_kernel()
{
/*задаются основные параметры */
   vidmem = (char *) 0xb8000;
   vidport = 0x3d4;
   lines = 25;
   cols = 80;
/*считывается предусмотрительно сохраненные координаты курсора*/
   curr_x=*(unsigned char *)(0x8000);
   curr_y=*(unsigned char *)(0x8001);
/*выводится строка*/
   puts("done\n");
/*уходим в бесконечный цикл*/
   while(1);
}
Вот и вывели мы этот "Hello World" на экран. Сколько проделано работы, а на экране только две строчки 
 
Booting data ...done
Go to proteсted mode ...done
Немного, но и немало. Закричала новая операционная система. Мир с радостью воспринял ее. Кто знает, может быть это новый Linux ... 
 
5. Подготовка загрузочного образа (floppy.img)
 
 
 
Итак, подготовим загрузочный образ нашей системки. 
 
Для начала соберем загрузочный сектор. 
 
as86 -0 -a -o boot.o boot.S
ld86 -0 -s -o boot.img boot.o
Обрежем 32 битный заголовок и получим таким образом чистый двоичный код. 
 
dd if=boot.img of=boot.bin bs=32 skip=1
Соберем ядро 
 
gcc -traditional -c head.S -o head.o
gcc -O2 -DSTDC_HEADERS -c start.c
При компоновке НЕ ЗАБУДБЬТЕ параметр "-T" он указывает относительно которого смещения вести расчеты, в нашем случае поскольку ядро грузится по адресy 0x1000, то и смещение соотетствующее 
 
ld -m elf_i386 -Ttext 0x1000  -e startup_32 head.o start.o -o head.img
Очистим зерна от плевел, то есть чистый двоичный код от всеческих служебных заголовков и комментариев 
 
objcopy -O binary -R .note -R .comment -S head.img head.bin
И соединяем воедино загрузочный сектор и ядро 
 
cat boot.bin head.bin >floppy.img
Образ готов. Записываем на дискетку (заготовьте несколько для экспериментов, я прикончил три штуки) перезагружаем компьютер и наслаждаемся. 
 
cat floppy.img >/dev/fd0
6. Е-мое, что ж я сделал (...)
 
 
 
Здорово, правда? Приятно почувствовать себя будущим Торвальдсом или кем-то еще. Красная линия намечена, можно смело идти вперед, дописывать и переписывать систему. Описанная процедура пока что едина для множества операционных систем, будь то UNIX или Windows. Что напишете Вы? ... не знает не кто. Ведь это будет Ваша система.
3
 Аватар для 0xAX
2451 / 362 / 9
Регистрация: 27.06.2009
Сообщений: 880
19.01.2010, 08:50
Цитата Сообщение от zago-vlad Посмотреть сообщение
Я очень хочу создать ОС. Большую часть работы я уже сделал, но мне надо сделать загрузчик.
Мдаа, большую чать ОС мы сделали а банальнейшую часть загрузчик помогите мне это сделать.
интересно.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
19.01.2010, 10:14
Почитай в этой теме
https://www.cyberforum.ru/asse... 84066.html
0
19.01.2010, 10:16

Не по теме:

Это читал:

Цитата Сообщение от taras atavin Посмотреть сообщение
Где ты откопал такой чайник, что ему ось нужна?
? В той самой теме.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2010, 10:16
Помогаю со студенческими работами здесь

Не могу создать загрузчик для FAT32
Создаю загрузочный файл для FAT32. Пишу org 7C00h, для того, чтобы запускалось именно по этому смещению. Линковщик TLINK ругается Invalid...

Как создать установщик для своей программы
Создал несколько программ и хотел бы похвастаться своими так скажем &quot;достижениями&quot; в области vb со своим преподавателем. Программы...

Как создать установщик для своей программы
ребят, задался вопросом создания установщика программ самый наипростейший способ как я понимаю, банальное копированием файлов ...

Создать API доступ для своей программы
Добрый день! Подскажите, что нужно делать, чтобы предоставить разработчикам сторонней программы доступ по API к моей программе? Для...

Как создать header file для своей dll?
При помощи dll wizard создал библиотеку. А как создать к ней заголовочный файл?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru